I searched the forum for such an example but get fragments only.
Does anyone has a functioning example in MASM of playing a .WAV file using wavXXX functions?


Posted on 2005-12-08 09:41:36 by japheth
You can use sndPlaySound to simply play a wave, or use Dsound9+ACM for full control 8) :)
Posted on 2005-12-08 10:13:07 by ti_mo_n

Cool! Thank you very much indeed!

But I still would prefer a waveXXX sample.
Posted on 2005-12-08 10:43:31 by japheth
hi japheth,

here's a little eg i wrote now, it should play raw files using wavexxx functions, i couldn't test it cos i couldn't find any software that converts wav to raw format.. sorry, lemme know if it works.. :) i hope it does... :roll:

Posted on 2005-12-08 12:22:45 by lone_samurai5

hi lone_samurai,

thx, but it doesn't work (waveOutPrepare fails), but that isn't surprising at all, since I want to play a "real" .WAV file, not just plain data, and your code does nothing to analyse the file header.

Posted on 2005-12-08 14:07:05 by japheth
Hi Japheth,

Sorry bout the prev one, here's the workin code.. :) 
Edit: plays large wav files now
Posted on 2005-12-09 02:04:22 by lone_samurai5

thanks samurai, but now it's too late, in the meantime I wrote it on my own ;-).

        .Model flat, stdcall
        option casemap:none

        include windows.inc
        include mmsystem.inc
        include macros.inc

?BLKSIZE    equ 10000h

RIFFHDR struct
chkId  dd ?
chkSiz  dd ?
format  dd ?

subchkId    dd ?
subchkSiz  dd ?

WAVEFMT struct
wFormatTag      dw ?
nChannels      dw ?
nSamplesPerSec  dd ?
nAvgBytesPerSec dd ?
nBlockAlign    dw ?
wBitsPerSample  dw ?


WavHdr1    WAVEHDR <>
WavHdr2    WAVEHDR <>
pWaveHdr    dd 0
pWavBuff    DD 0
pWavBuffEnd DD 0
dwBuffSize  dd 0
g_hConOut  dd 0
g_bDone    db 0
szFileName  DB ".\S_16_44.wav",0


;--- printf emulation

printf  proc c pszText:dword, parms:VARARG

local  dwWritten:dword
local  szText[128]:byte

        invoke wvsprintf, addr szText, pszText, addr parms
        lea ecx, dwWritten
        invoke WriteConsole, g_hConOut, addr szText, eax, ecx, 0
printf  endp

GetDataChunk proc
        mov eax, pWavBuffEnd
        sub eax, pWavBuff
        .if (eax > ?BLKSIZE)
            mov eax, ?BLKSIZE
        add pWavBuff, eax
GetDataChunk endp

WavProc Proc uses ebx hWaveOut:HANDLE, uMsg:UINT, UserData:Dword, Param1:Dword, Param2:Dword

  .If uMsg==WOM_DONE
        invoke printf, CStr(<"WavProc, pBuffer=%X, pBufferEnd=%X",10>), pWavBuff, pWavBuffEnd
        mov ebx, pWaveHdr
        Invoke waveOutUnprepareHeader, hWaveOut, ebx, sizeof WAVEHDR
        mov eax, pWavBuff
        mov .WAVEHDR.lpData, eax
        invoke GetDataChunk
        .if (!eax)
            inc g_bDone
            jmp @exit
        mov .WAVEHDR.dwBufferLength, eax
        mov .WAVEHDR.dwLoops, 1
        Invoke waveOutPrepareHeader, hWaveOut, ebx, sizeof WAVEHDR
        Invoke waveOutWrite, hWaveOut, ebx, sizeof WAVEHDR
        .if (ebx == offset WavHdr1)
            mov pWaveHdr, offset WavHdr2
            mov pWaveHdr, offset WavHdr1

WavProc EndP

main    proc c

local  hFile:DWORD
local  dwRead:DWORD
local  riffhdr:RIFFHDR
local  wavefmt:WAVEFMT
local  hWaveOut:HANDLE
local  datahdr:RIFFCHKHDR

        invoke GetStdHandle, STD_OUTPUT_HANDLE
        mov g_hConOut, eax
        invoke waveOutGetNumDevs
        .if (!eax)
            invoke printf, CStr(<"waveOutGetNumDevs() returned 0",10>)
            jmp @exit
        mov hFile,eax
        .if (hFile == -1)
            invoke printf, CStr(<"file %s not found",10>), addr szFileName
            jmp @exit
        Invoke ReadFile, hFile, addr riffhdr, sizeof RIFFHDR, addr dwRead, NULL
        .if (dwRead != sizeof RIFFHDR)
            invoke printf, CStr(<"unknown file format",10>)
            jmp @exit
        .if (riffhdr.chkId != "FFIR")
            invoke printf, CStr(<"no RIFF header found",10>)
            jmp @exit
        .if (riffhdr.format != "EVAW")
            invoke printf, CStr(<"not a WAVE format",10>)
            jmp @exit
        Invoke ReadFile, hFile, addr wavefmt, sizeof WAVEFMT, addr dwRead, NULL
        .if (dwRead != sizeof WAVEFMT)
            invoke printf, CStr(<"unknown file format",10>)
            jmp @exit
        .if (wavefmt.subchkId != " tmf")
            invoke printf, CStr(<"no fmt chunk found",10>)
            jmp @exit

        Invoke ReadFile, hFile, addr datahdr, sizeof RIFFCHKHDR, addr dwRead, NULL
        .if (dwRead != sizeof RIFFCHKHDR)
            invoke printf, CStr(<"unknown file format",10>)
            jmp @exit
        .if (datahdr.subchkId != "atad")
            invoke printf, CStr(<"no data chunk found",10>)
            jmp @exit
        mov eax, datahdr.subchkSiz
        mov dwBuffSize, eax
        Invoke LocalAlloc, LMEM_FIXED or LMEM_ZEROINIT, dwBuffSize
        mov pWavBuff, eax
        .if (!eax)
            invoke printf, CStr(<"out of memory",10>)
            jmp @exit
        Invoke ReadFile, hFile, pWavBuff, dwBuffSize, addr dwRead, NULL
        mov eax, dwBuffSize
        .if (eax != dwRead)
            invoke printf, CStr(<"unexpected end of file",10>)
            jmp @exit

        mov eax, pWavBuff       
        add eax, dwBuffSize
        mov pWavBuffEnd, eax
        mov ebx, offset WavFormat
        mov .WAVEFORMATEX.cbSize,sizeof WAVEFORMATEX 
        mov ax, wavefmt.wFormatTag
        mov .WAVEFORMATEX.wFormatTag, ax
        mov ax, wavefmt.nChannels
        mov .WAVEFORMATEX.nChannels,ax
        mov eax, wavefmt.nSamplesPerSec
        mov .WAVEFORMATEX.nSamplesPerSec, eax
        mov eax, wavefmt.nAvgBytesPerSec
        mov .WAVEFORMATEX.nAvgBytesPerSec, eax
        mov ax, wavefmt.nBlockAlign
        mov .WAVEFORMATEX.nBlockAlign, ax
        mov ax, wavefmt.wBitsPerSample
        mov .WAVEFORMATEX.wBitsPerSample, ax
        Invoke waveOutOpen, addr hWaveOut, WAVE_MAPPER, ebx,\
                offset WavProc, NULL, CALLBACK_FUNCTION
        .if (eax != MMSYSERR_NOERROR)
            invoke printf, CStr(<"waveOutOpen failed",10>)
            jmp @exit

        mov pWaveHdr, offset WavHdr1

        mov WavHdr1.dwFlags, 0
        mov WavHdr1.dwLoops, 1
        mov eax, pWavBuff
        mov WavHdr1.lpData, eax
        invoke GetDataChunk
        .if (eax)
            mov WavHdr1.dwBufferLength, eax
            invoke waveOutPrepareHeader, hWaveOut, addr WavHdr1, sizeof WAVEHDR
            inc g_bDone

        mov WavHdr2.dwFlags, 0
        mov WavHdr2.dwLoops, 1
        mov eax, pWavBuff
        mov WavHdr2.lpData, eax
        invoke GetDataChunk
        .if (eax)
            mov WavHdr2.dwBufferLength, eax
            invoke waveOutPrepareHeader, hWaveOut, addr WavHdr2, sizeof WAVEHDR
            inc g_bDone

        .if (WavHdr1.dwBufferLength)
            Invoke waveOutWrite, hWaveOut, addr WavHdr1, sizeof WAVEHDR
        .if (WavHdr2.dwBufferLength)
            Invoke waveOutWrite, hWaveOut, addr WavHdr2, sizeof WAVEHDR

        .while (g_bDone != 2)
            invoke Sleep,0
        invoke waveOutClose, hWaveOut
        .if (hFile != -1)           
            Invoke CloseHandle, hFile

main    endp

        invoke main
        invoke ExitProcess, 0

        end start

Posted on 2005-12-09 04:40:43 by japheth
Dats gr8  :P btw was wondering, does anyone know how to write a visualization, i mean like the bars that are displayed in winamp.. See attached pic..
Posted on 2005-12-09 05:25:32 by lone_samurai5
In Bassmod 1.8 there is a folder with c-examples. There you can check the spectrum.c.
It's not entirely what you want but you can use the very idea implemented.
Posted on 2005-12-12 09:15:07 by k3Eahn
If I am not mistaken - Those visualization bars are in some way connected to the FFT algorithm.
NaN once wrote an assembly proc on FFT available here in the forums.

Hope this helps.
Posted on 2005-12-12 12:13:00 by JimmyClif
Thanx K3Eahn, just what i was lookin for.. btw Jimmy, do u have it? can u upload it here..
Posted on 2005-12-12 13:06:24 by lone_samurai5
Posted on 2005-12-12 13:09:24 by JimmyClif
Here are the 2 missing files from the thread.

Posted on 2005-12-12 18:19:12 by roticv