News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

Bundle and Play XM File As Resource

Started by DavidB, November 21, 2017, 05:06:26 PM

Previous topic - Next topic

aw27

@DavidB

Here is a VS Project that plays the XM file from Siekmanski.
The XM is added directly as a RCDATA resource into VS.
You need to add these libs and ignore all the others
msvcrt.lib
ufmod.lib
Winmm.lib


.model FLAT, STDCALL

include ufmod.inc

ElteesSong     equ 101

.data
hinst dd 0

.code
main proc
invoke  uFMOD_PlaySong, ElteesSong, hinst, XM_RESOURCE
    ret
main endp

end


Have fun with the music and the Irvine book.

Siekmanski

Here are 2 to minimal examples of the uFMOD XMplayer

The XMplayer loads a XM file from disk and plays it.
The XMplayerMemory plays a XM hex-dump file from memory. ( XM file included in the executable )
Use the SaveBin2Hex.exe to convert the XM file to a hex-dump include file.
Creative coders use backward thinking techniques as a strategy.

aw27

Someone may consider as well to port the ufmod to 64-bit, it looks uncomplicated but I will not volunteer this time.
The site is here https://sourceforge.net/projects/ufmod/

DavidB

Quote from: Siekmanski on November 22, 2017, 06:25:00 PM
Good idea.  :t

Click on the "MASM32 Downloads" link in the top right of this page and download the MASM SDK.
It has all you need to get started programming with MASM.
Wow. I am so lost. :( I have not even bothered with trying to understand how to use uFMOD yet because I cannot figure out how to convert my XM to a data dump that I could then use in my .data section, nor can I figure out how to include the libraries in my Visual Studio project. I wish I didn't have to use Visual Studio for this.  :(

Quote from: jj2007 on November 22, 2017, 07:02:15 PM
Quote from: DavidB on November 22, 2017, 06:13:58 PMMy program is a small console application, so I'm probably going to opt for the data dump method and load it from data memory

Console programs can also have resource sections, no problem.

Quote...a program that uses Irvine. As for the "Intel ABI compliant" part is concerned, what does that mean? Why would it cause problems?

It would not necessarily cause problems, but you would need to know exactly what you do. And in any case, Masm32 is a much more mature and powerful package. Kip's stuff is really just meant for students who need a certificate and then quickly forget what assembly is good for.
Okay, that's good to know. The only thing I want to do that cannot be done with Irvine for this project is play the XM file. Other than that, everything else can be achieved using Irvine. As I mentioned earlier, my Assembly class is the reason I was introduced to Irvine, but it seems that if I actually want to learn Assembly for real, I need to ditch him. Quite a shame.

jj2007

Quote from: DavidB on November 23, 2017, 05:47:45 PMI cannot figure out how to convert my XM to a data dump that I could then use in my .data section

That is the easy part, use the attached tool: Just drag the xm file over the exe (works with any type of file, but there may be size limits, see SetClip$).

Once it's on the clipboard, use the data as follows:include \masm32\include\masm32rt.inc
.code
start:
  mov ebx, offset dend
  mov edi, offset dstart
  sub ebx, edi
  ... your code here ...
  print str$(edi), " is the start of the buffer", 13, 10
  inkey str$(ebx), " bytes are available", 13, 10
  exit
dstart:
db  045h, 078h, 074h, 065h, 06Eh, 064h, 065h, 064h, 020h, 04Dh, 06Fh, 064h, 075h, 06Ch, 065h, 03Ah
db  020h, 048h, 061h, 070h, 070h, 079h, 020h, 048h, 02Eh, 020h, 043h, 068h, 072h, 069h, 073h, 074h
...
db  021h, 000h, 000h, 000h, 020h, 020h, 020h, 020h, 020h, 020h, 020h, 073h, 069h, 067h, 06Eh, 065h
db  064h, 02Ch, 020h, 044h, 052h, 041h, 058h, 000h, 000h, 000h, 080h, 000h, 000h, 028h, 000h, 000h
db  000h
dend:
end start

avcaballero

Hello, this is my contribution, though not in masm, but in PellesC, playing a xm tune from the resource. Full src ready to compile.

Siekmanski

Creative coders use backward thinking techniques as a strategy.

DavidB

#22
Quote from: jj2007 on November 23, 2017, 06:47:23 PM
Quote from: DavidB on November 23, 2017, 05:47:45 PMI cannot figure out how to convert my XM to a data dump that I could then use in my .data section

That is the easy part, use the attached tool: Just drag the xm file over the exe (works with any type of file, but there may be size limits, see SetClip$).

Once it's on the clipboard, use the data as follows:include \masm32\include\masm32rt.inc
.code
start:
  mov ebx, offset dend
  mov edi, offset dstart
  sub ebx, edi
  ... your code here ...
  print str$(edi), " is the start of the buffer", 13, 10
  inkey str$(ebx), " bytes are available", 13, 10
  exit
dstart:
db  045h, 078h, 074h, 065h, 06Eh, 064h, 065h, 064h, 020h, 04Dh, 06Fh, 064h, 075h, 06Ch, 065h, 03Ah
db  020h, 048h, 061h, 070h, 070h, 079h, 020h, 048h, 02Eh, 020h, 043h, 068h, 072h, 069h, 073h, 074h
...
db  021h, 000h, 000h, 000h, 020h, 020h, 020h, 020h, 020h, 020h, 020h, 073h, 069h, 067h, 06Eh, 065h
db  064h, 02Ch, 020h, 044h, 052h, 041h, 058h, 000h, 000h, 000h, 080h, 000h, 000h, 028h, 000h, 000h
db  000h
dend:
end start

Well that method was way too messy, so what I've done instead is added an obj file that was created from the XM file to the linker. I tried adding the inc file created from the XM to the linker instead, but Visual Studio complained that it was invalid.

The inc file has this in it:

; -----------------------------------------------------
; Include the contents of this file in your source file
; to access the data as an OFFSET and use the equate as
; the byte count for the file data in the object module
; -----------------------------------------------------
EXTERNDEF MyXMFile:DWORD
ln_MyXMFile equ <26087>


I've placed this code in the .data segment. I acquired a copy of the ufmod.inc and ufmod.lib and added them to my project like so:

include ufmod.inc
includelib ufmod.lib


After that, I tried loading the offset for my XM file in eax like this:

lea eax, MyXMFile

I followed this line up with:

invoke uFMOD_PlaySong, eax, 0, 0

Moving the offset of MyXMFile to eax seems to have worked, but when I try to do the "PlaySong" part, I get an entire collection of "unresolved external symbol" errors. Here is the section of Visual Studio's output pertaining to this issue.

1>ufmod.lib(ufmod.obj) : error LNK2001: unresolved external symbol __imp__waveOutClose@4
1>ufmod.lib(ufmod.obj) : error LNK2001: unresolved external symbol __imp__waveOutGetPosition@12
1>ufmod.lib(ufmod.obj) : error LNK2001: unresolved external symbol __imp__waveOutOpen@24
1>ufmod.lib(ufmod.obj) : error LNK2001: unresolved external symbol __imp__waveOutPrepareHeader@12
1>ufmod.lib(ufmod.obj) : error LNK2001: unresolved external symbol __imp__waveOutReset@4
1>ufmod.lib(ufmod.obj) : error LNK2001: unresolved external symbol __imp__waveOutUnprepareHeader@12
1>ufmod.lib(ufmod.obj) : error LNK2001: unresolved external symbol __imp__waveOutWrite@12


Where do I go from here? I am fairly certain that I am close, but I am still not quite there.

dedndave

what i find interesting here is the "sound from memory" ability
i have been looking for a good way to do this, primarily for ham radio stuff

if i wasn't so lazy, i could pour through all the ufmod library code and figure out how it works
(that would probably include learning all about the XM file format)

instead, i wanted a quick list of the functions called to make it happen
so, i did a disassembly on one of Marinus' programs and dumped this  :biggrin:

   Import Module 002: winmm.dll

Addr:00003210 hint(00B5) Name: waveOutGetPosition
Addr:00003226 hint(00B8) Name: waveOutOpen
Addr:00003234 hint(00BA) Name: waveOutPrepareHeader
Addr:0000324C hint(00BB) Name: waveOutReset
Addr:0000325C hint(00C0) Name: waveOutUnprepareHeader
Addr:00003276 hint(00C1) Name: waveOutWrite
Addr:00003200 hint(00AC) Name: waveOutClose


.... wow, Jochen is catching me up - lol - 7666 posts  :shock:
although, he's got a way to go if we count the old forum numbers

dedndave

David...

what those tell you is that you want to use the winmm inc and lib from the masm32 package
        INCLUDE    \Masm32\Include\Masm32rt.inc
        INCLUDE    \Masm32\Include\WinMm.inc
        INCLUDELIB \Masm32\Lib\WinMm.lib


now you know which functions to learn about
you can read up on them on the msdn site  :t

aw27

I posted a complete VS project, David completely ignored it and keeps bumping his head against the walls trying to make his VS project work. These newbies are really funny.  :badgrin:

DavidB

Quote from: dedndave on November 24, 2017, 01:06:24 PM
David...

what those tell you is that you want to use the winmm inc and lib from the masm32 package
        INCLUDE    \Masm32\Include\Masm32rt.inc
        INCLUDE    \Masm32\Include\WinMm.inc
        INCLUDELIB \Masm32\Lib\WinMm.lib


now you know which functions to learn about
you can read up on them on the msdn site  :t
Awesome! Thanks!

Quote from: aw27 on November 24, 2017, 02:33:24 PM
I posted a complete VS project, David completely ignored it and keeps bumping his head against the walls trying to make his VS project work. These newbies are really funny.  :badgrin:
I would love to see you floundering about clueless about something some day. Unfortunately, it probably won't happen. This forum has a wide variety of people. Some are very helpful and understanding, some are helpful, yet rude about it. And some are both rude and useless. At least you're the second, and for that I am thankful, but nonetheless, there's no reason to be rude about it.

That said, thanks for posting the VS project. I honestly did not see it. I wish I had noticed it earlier.

Update: Although I am sure the code in your project will be helpful after I review it a little more, the project itself does not open properly Visual Studio.

aw27

Quote
the project itself does not open properly Visual Studio.

Honestly, you don't appear to have life for IT, but you are really good at judging people.

DavidB

Quote from: aw27 on November 24, 2017, 04:00:05 PMHonestly, you don't appear to have life for IT,
Well I am sorry you think that.

Quote from: aw27 on November 24, 2017, 04:00:05 PMbut you are really good at judging people.
You're one to talk.

Siekmanski

Quote from: dedndave on November 24, 2017, 12:54:11 PM
what i find interesting here is the "sound from memory" ability
i have been looking for a good way to do this, primarily for ham radio stuff

if i wasn't so lazy, i could pour through all the ufmod library code and figure out how it works
(that would probably include learning all about the XM file format)

instead, i wanted a quick list of the functions called to make it happen
so, i did a disassembly on one of Marinus' programs and dumped this  :biggrin:

   Import Module 002: winmm.dll

Addr:00003210 hint(00B5) Name: waveOutGetPosition
Addr:00003226 hint(00B8) Name: waveOutOpen
Addr:00003234 hint(00BA) Name: waveOutPrepareHeader
Addr:0000324C hint(00BB) Name: waveOutReset
Addr:0000325C hint(00C0) Name: waveOutUnprepareHeader
Addr:00003276 hint(00C1) Name: waveOutWrite
Addr:00003200 hint(00AC) Name: waveOutClose


.... wow, Jochen is catching me up - lol - 7666 posts  :shock:
although, he's got a way to go if we count the old forum numbers

Hi Dave,

The XM file format is probably not what you want for ham radio stuff.
It's a format with song data, audio effect routines and separate sound samples mixed to create an audio song.

For ham radio stuff, the simplest way is to set up the sound card as a ring-buffer and feed it with audio portions from your ham data stream directly from memory.

With DirectSound ( and some tricks ) you can get a reliable latency of close to 10 milliseconds.
With DirectSound you don't have exclusive ownership of the sound card.

Low latency audio is often a big deal in radio land, and therefore the "pro's" use ASIO capable sound cards to get 2 milliseconds latency. ( you can record from your microphone and transmit it without hearing a delay )
With ASIO you have exclusive ownership of the sound card.

Do you have an ASIO sound card?
Creative coders use backward thinking techniques as a strategy.