The MASM Forum Archive 2004 to 2012

General Forums => The Campus => Topic started by: NoCforMe on January 09, 2012, 12:45:57 AM

Title: Making a simple WAV player
Post by: NoCforMe on January 09, 2012, 12:45:57 AM
I'd like a reallllly simple WAV player. Just something I can fire up, select the file to play and have it play in the background while I do other stuff.

I tried PlaySound():


INVOKE PlaySoundA, ADDR SoundFilename, NULL, SND_FILENAME ;OR SND_ASYNC


It works--it plays the sound--but it has problems, and I don't think it's the right thing to use here.

No problem for short sound files, but when I tried to play a song of a few minutes length (~23 MB), it played to a certain point, then stopped. Plus I couldn't get the "async" flag to work (no sound at all if I use this flag). The one page I found in MSDN (http://msdn.microsoft.com/en-us/library/aa909766.aspx) about this function says:

QuoteThe sound specified by pszSound must fit into available physical memory and be playable by an installed waveform-audio device driver.

So it apparently does little or no buffering of the WAV data. (I used PlaySoundA() because this was all I could find in the MASM32 include and lib files; no PlaySound().)

The documentation on MSDN is very confusing. All the descriptions I found seem to apply to weird things like Windows CE and Windows Mobile, or else they give C++ or C# examples that need a certain SDK or language-specific features. (Then there's the whole "core audio" API, which requires Vista or later.)

I think I want to use some of the wavexxxx() functions instead. All I want is a really simple player; all it needs is to be able to select a WAV file, and maybe a "stop" button to kill it. Don't really even need positioning controls, pause, etc., though these would probably be easy enough to add.

Can someone point me to a simple tutorial on this, or maybe a working example somewhere, that shows how to use these functions?
Title: Re: Making a simple WAV player
Post by: dedndave on January 09, 2012, 01:32:48 AM
http://msdn.microsoft.com/en-us/library/windows/desktop/dd757160%28v=vs.85%29.aspx

that is just one of the functions
look to the left-hand side for others
there is a bit of reading to do   :P

http://msdn.microsoft.com/en-us/library/windows/desktop/dd757151%28v=VS.85%29.aspx
Title: Re: Making a simple WAV player
Post by: Bill Cravener on January 09, 2012, 11:14:27 AM
Dave has you on the correct path and with my simple mp3 player example you should have no trouble making your own wave file player. Simply change the DlgDirList functions lpPathSpec in my example to "*.wav" and it will play wave files.

http://www.quickersoft.com/examples/PlayMp3.zip
Title: Re: Making a simple WAV player
Post by: jj2007 on January 09, 2012, 01:19:53 PM
Try if it stops early with your 23 MB file.
include \masm32\include\masm32rt.inc
include \masm32\include\winmm.inc
includelib \masm32\lib\winmm.lib

.data
playthis db "play "
buffer db 128 dup(?)

.code
start:
mov esi, offset buffer
; drag a valid wav file over the executable,
; e.g. C:\WINDOWS\Media\Windows XP Startup.wav
invoke GetCL, 1, esi
.if rv(GetShortPathName, esi, esi, 127)
sub esi, 5
invoke mciSendString, esi, 0, 0, 0
.endif
inkey "bye"
exit
end start
Title: Re: Making a simple WAV player
Post by: NoCforMe on January 10, 2012, 06:13:36 AM
Hmm; I tried that, jj, but it doesn't work at all. Here's the bulk of my program:


.data

SoundCommand DB "play \SAVE\Sounds\Music\Balkan-E. European\Bulgarian\Gumzoviana.wav", 0
ErrorMsgBuffer DB 200 DUP (?)


;============================================
; CODE LIVES HERE
;============================================
.code


start: INVOKE mciSendString, OFFSET SoundCommand, NULL, 0, 0
OR EAX, EAX
JZ @F
INVOKE mciGetErrorString, EAX, OFFSET ErrorMsgBuffer, SIZEOF ErrorMsgBuffer
INVOKE MessageBox, 0, OFFSET ErrorMsgBuffer, NULL, MB_OK

@@: INVOKE ExitProcess, EAX


All I get is an error message that says "The specified device is not open or is not recognized by MCI".

Bill, I'm going to look at your example next.
Title: Re: Making a simple WAV player
Post by: NoCforMe on January 10, 2012, 06:32:44 AM
Bill, I just edited and built your little app. It works, but I've got some questions.

I just changed ".mp3" to ".wav" as you suggested, and it does play WAV files (all the way through, too). But even though I can select and play MP3 files as well, they don't play ... correctly. Sound all chopped up.

I notice some minor buffering glitches too, which must be due to the way the file is being handled by the mcixxx() functions.

I notice you open a device called "MPEGVideo"; shouldn't this be changed if I want to play WAVs? or not? (seems to work OK).

By the way, I hate your user interface (and I mean this in the nicest possible way). Very hard to drill back up through a disk directory structure.

Thanks for the app, and thanks in advance for any further answers.

Update: Just remade the app changing the ".wav" back to ".mp3". Did you know it makes no difference? You can play WAV or MP3 files in either case.

I tried playing some MP3s. The files I have don't play well at all (all chopped up, as noted above), but your sample MP3 plays just fine. For some reason it doesn't seem to like my MP3s. (Mine were made with a Sound Forge plug-in and play on every other player I've used.) No big deal, just thought you'd like to know.
Title: Re: Making a simple WAV player
Post by: jj2007 on January 10, 2012, 06:37:34 AM
Quote from: NoCforMe on January 10, 2012, 06:13:36 AM
Hmm; I tried that, jj, but it doesn't work at all.

Your filename has spaces. Won't work with spaces.
Title: Re: Making a simple WAV player
Post by: donkey on January 10, 2012, 06:41:16 AM
Hi NoCforMe,

Many MP3 files are VBR encoded, these wll have problems with mciXXX functions as far as I remember (its been quite a while since I've used them). You can check for a XING signature in the MP3 file to see if it is VBR, I posted a program (http://www.masm32.com/board/index.php?topic=10610.0) to extract the information from MP3 files that demonstrates how to do this. It will also allow you to display other information about the MP3 at the same time.

Edgar
Title: Re: Making a simple WAV player
Post by: NoCforMe on January 10, 2012, 06:47:26 AM
Quote from: jj2007 on January 10, 2012, 06:37:34 AM
Quote from: NoCforMe on January 10, 2012, 06:13:36 AM
Hmm; I tried that, jj, but it doesn't work at all.

Your filename has spaces. Won't work with spaces.

And yet PlaySound() can play that same file, coded the same way.

I thought the problem might be that you never opened the sound device, like Bill does in his little app (using mciSendCommand(MCI_OPEN) ).
Title: Re: Making a simple WAV player
Post by: jj2007 on January 10, 2012, 07:43:14 AM
NoC,

There could be a problem with your audio setup or Windows version. I forgot that my example should work with spaces, too, since it uses GetShortPathName. On my puter, WinXP SP2, it works just fine, you can drag *.wav or *.mp3 over the exe and it starts playing until you hit the key.

See also Edgar's comment concerning mp3 files (but your problem is wav...).
Title: Re: Making a simple WAV player
Post by: donkey on January 10, 2012, 09:19:44 AM
You know if you're going to be serious about playing MP3's the mci is very limited. You should think about DirectShow. Unfortunately (for some) it is only available as a COM interface but it is extremely easy to use. I have cut the appropriate parts out of a project I was working on (but have shelved indefinitely) and pasted them here. It is in GoAsm syntax and requires my headers but I am sure someone here can translate them for you. It plays MP3s very well and if you want to get deeper you can control pretty much everything about your player.

Note that this should play WAVs as well but I have never tried it.

Sorry about the length of this code, I didn't want to build a project.

STRINGS UNICODE
#DEFINE UNICODE

#define WIN32_LEAN_AND_MEAN 

#DEFINE WINVER NTDDI_WINXP
#DEFINE FILTERAPI

#DEFINE LINKFILES
#DEFINE LINKVCRT

#DEFINE CCUSEORDINALS

#include "WINDOWS.H"
#include "macros.h"
#include "mmsystem.h"
#include "strmif.h"
#include "control.h"
#include "uuids.h"

#IF X64
S=8
#ELSE
S=4
#ENDIF

DATA SECTION
pigb PTR NULL
pimc PTR NULL
pimex PTR NULL
piba PTR NULL
pims PTR NULL
ready BOOL FALSE
duration LONGLONG 0

IID_IGraphBuilder GUID GUID_IID_IGraphBuilder
IID_IMediaControl GUID GUID_IID_IMediaControl
IID_IMediaEventEx GUID GUID_IID_IMediaEventEx
IID_IBasicAudio GUID GUID_IID_IBasicAudio
IID_IMediaSeeking GUID GUID_IID_IMediaSeeking
CLSID_FilterGraph GUID GUID_CLSID_FilterGraph
TIME_FORMAT_MEDIA_TIME GUID GUID_TIME_FORMAT_MEDIA_TIME

MP3File DUS "Some.mp3",0

evcode DD 0

CODE SECTION
// Be sure to initialize COM
invoke CoInitialize,NULL

// To play a file just do this
invoke Load,offset MP3File
// Volume is 0 (full) to -10000 (mute)
invoke SetVolume,0
invoke Play
// Wait for it to complete
invoke WaitForCompletion,10000000,offset evcode
// Cleanup the interfaces
call Cleanup

// When your program is done shut down COM
invoke CoUninitialize

// The functions (I have a few more but they require a lot of setup code)

Cleanup:
cmp S[pimc],0
je >
CoInvoke(pimc,IMediaControl.Stop)
:
cmp S[pigb],0
je >
CoInvoke(pigb,IGraphBuilder.Release)
mov S[pigb],NULL
:
cmp S[pimc],0
je >
CoInvoke(pimc,IMediaControl.Release)
mov S[pimc],NULL
:
cmp S[pimex],0
je >
CoInvoke(pimex,IMediaEventEx.Release)
mov S[pimex],NULL
:
cmp S[piba],0
je >
CoInvoke(piba,IBasicAudio.Release)
mov S[piba],NULL
:
cmp S[pims],0
je >
CoInvoke(pims,IMediaSeeking.Release)
mov S[pims],NULL
:
mov D[ready],FALSE
RET


Load FRAME szFile
LOCAL LocResult:D

call Cleanup

mov D[ready],FALSE
invoke CoCreateInstance,offset CLSID_FilterGraph,NULL,CLSCTX_INPROC_SERVER,offset IID_IGraphBuilder,offset pigb
test eax,eax

jnz >>.EXIT
xor eax,eax
mov [LocResult],eax
CoInvoke(pigb,IGraphBuilder.IUnknown.QueryInterface,offset IID_IMediaControl,offset pimc)
or [LocResult],eax
CoInvoke(pigb,IGraphBuilder.IUnknown.QueryInterface,offset IID_IMediaEventEx,offset pimex)
or [LocResult],eax
CoInvoke(pigb,IGraphBuilder.IUnknown.QueryInterface,offset IID_IBasicAudio,offset piba)
or [LocResult],eax
CoInvoke(pigb,IGraphBuilder.IUnknown.QueryInterface,offset IID_IMediaSeeking,offset pims)
or [LocResult],eax
cmp D[LocResult],0
jne >.EXIT

CoInvoke(pigb,IGraphBuilder.RenderFile,[szFile],NULL)
test eax,eax
jnz >.EXIT
mov D[ready],TRUE
cmp S[pims],0
je >>.EXIT
CoInvoke(pims,IMediaSeeking.SetTimeFormat,offset TIME_FORMAT_MEDIA_TIME)
CoInvoke(pims,IMediaSeeking.GetDuration,offset duration)


    .EXIT
    mov eax,[ready]
    ret
ENDF

Play:
cmp D[ready],FALSE
je >>.EXIT
cmp S[pimc],0
je >>.EXIT
CoInvoke(pimc,IMediaControl.Run)
ret
.EXIT
mov eax,-1
ret

Pause:
cmp D[ready],FALSE
je >>.EXIT
cmp S[pimc],0
je >>.EXIT
CoInvoke(pimc,IMediaControl.Pause)
ret
.EXIT
mov eax,-1
ret

Stop:
cmp D[ready],FALSE
je >>.EXIT
cmp S[pimc],0
je >>.EXIT
CoInvoke(pimc,IMediaControl.Stop)
ret
    .EXIT
mov eax,-1
ret

WaitForCompletion FRAME msTimeout, pEvCode
cmp D[ready],FALSE
je >>.EXIT
cmp S[pimex],0
je >>.EXIT
CoInvoke(pimex,IMediaEventEx.WaitForCompletion,[msTimeout],[pEvCode])
cmp eax,0
jne >.EXIT
mov eax,1
ret
.EXIT
mov eax,0
ret
ENDF

SetVolume FRAME vol
cmp D[ready],FALSE
je >>.EXIT
cmp S[piba],0
je >>.EXIT
CoInvoke(piba,IBasicAudio.put_Volume,[vol])
ret
    .EXIT
mov eax,-1
ret
ENDF

GetVolume FRAME pvol
cmp D[ready],FALSE
je >>.EXIT
cmp S[piba],0
je >>.EXIT
CoInvoke(piba,IBasicAudio.get_Volume,[pvol])
ret
    .EXIT
mov eax,-1
ret
ENDF

GetCurrentPosition FRAME pInt64curpos
cmp D[ready],FALSE
je >>.EXIT
cmp S[pims],0
je >>.EXIT
mov eax,[pInt64curpos]
mov D[eax],-1
mov D[eax+4],-1
CoInvoke(pims,IMediaSeeking.GetCurrentPosition,[pInt64curpos])
ret
    .EXIT
mov eax,-1
ret
ENDF

SetPositions FRAME pINT64Current, pINT64Stop, bAbsolutePositioning
LOCAL Posflags:D

mov D[Posflags],0
cmp D[ready],FALSE
je >>.EXIT
cmp S[pims],0
je >>.EXIT
cmp D[bAbsolutePositioning],0
je >
mov D[Posflags], AM_SEEKING_AbsolutePositioning | AM_SEEKING_SeekToKeyFrame
jmp >>.SETPOS
        :
mov D[Posflags], AM_SEEKING_RelativePositioning | AM_SEEKING_SeekToKeyFrame
.SETPOS
CoInvoke(pims,IMediaSeeking.SetPositions,[pINT64Current], [Posflags], [pINT64Stop], [Posflags])
ret
.EXIT
mov eax,-1
ret
ENDF
Title: Re: Making a simple WAV player
Post by: Bill Cravener on January 10, 2012, 10:44:04 AM
Quote from: NoCforMe on January 10, 2012, 06:32:44 AM
I notice you open a device called "MPEGVideo"; shouldn't this be changed if I want to play WAVs? or not? (seems to work OK).

Using the MPEGVideo type you can play almost all of the newest media files such as divx, xvid, mp3, avi, wav, mpeg, mpg, wma and wmv. If I recall correctly earlier versions of Windows win.ini file had a list of supported media file types that the MPEGVideo type supported. The MPEGVideo type refers to Windows system default media driver which as we know can play most anything including MP3 using I think DirectShow which is the technology that replaced MCI some 10 years or more ago. If you have a third-party driver with a higher precedence that claims to support MP3 but in fact doesn't or a third-party installer that has broke MPEGVideo's registration you may get stuttering in your playback. It is not the fault of my simple media player example.

Quote from: NoCforMe on January 10, 2012, 06:32:44 AM
By the way, I hate your user interface (and I mean this in the nicest possible way). Very hard to drill back up through a disk directory structure.

Come on NoCforMe just what did you expect for free its intention is to be simple. What you do with it from there is up to you. Now if you want to open up your wallet I'll do you up something real fancy. :bg
Title: Re: Making a simple WAV player
Post by: bomz on January 10, 2012, 11:47:15 AM
QuoteBill Cravener http://www.quickersoft.com/examples/PlayMp3.zip

Now it is clear how players make (http://smiles.kolobok.us/light_skin/tender.gif)
Title: Re: Making a simple WAV player
Post by: Bill Cravener on January 10, 2012, 12:31:42 PM
Thank you bomz!  :bg
Title: Re: Making a simple WAV player
Post by: Bill Cravener on January 10, 2012, 01:25:49 PM
First time I've ever tested my simple media player example on a full length mp3 and it appears to work perfectly. :bg

Crank it up!! HillbillyHerald.mp3 (http://www.quickersoft.com/examples/HillbillyHerald.mp3)
Title: Re: Making a simple WAV player
Post by: bomz on January 14, 2012, 03:40:04 AM
Bill Cravener
Quote.386

.model flat, stdcall
option casemap :none

        include \masm32\include\windows.inc
        include \masm32\include\user32.inc
        include \masm32\include\kernel32.inc
        includelib \masm32\lib\user32.lib
        includelib \masm32\lib\kernel32.lib

.data
   FileName   db "Sample.avi",0
   szMCIdll        db "msvfw32.dll", 0
   szMCIWndCreate  db "MCIWndCreate", 0

.code
start:
                invoke LoadLibrary, addr szMCIdll
                push eax
                invoke GetProcAddress, eax, addr szMCIWndCreate
                push offset FileName
                push 0
                push 0
                push 0
                call eax
                call FreeLibrary
      invoke MessageBox,0,0,0,0
      invoke ExitProcess,0
end start

(http://s47.radikal.ru/i115/0810/9a/919ffed6ae3a.gif)
Title: Re: Making a simple WAV player
Post by: donkey on January 14, 2012, 08:37:14 AM
 :wink clearer in GoAsm

#DEFINE WINVER NTDDI_WINXP // Target system is XP
#DEFINE FILTERAPI // Generate errors for unavailable/deprecated API
#define LINKFILES // Link the DLL libraries
#INCLUDE Windows.h // Core headers

DATA SECTION
FileName   db "Sample.avi",0

CODE SECTION

Start:
invoke MCIWndCreate,0,0,0,offset FileName
invoke MessageBox,0,0,0,0
invoke ExitProcess,0
Title: Re: Making a simple WAV player
Post by: dedndave on January 14, 2012, 10:59:09 AM
yah - we need to create a vfw32.inc and vfw32.lib that get functions from avicap32.dll, avifil32.dll, and msvfw32.dll
not from vfw32.dll, which does not exist
vfw32 is, however, the correct name for the include and import library
at least, that is how MS C handles it
i suppose we could put the functions in 3 seperate INC/LIB pairs

vfw32.inc/lib in masm32 version 10 do not have the MCIWndCreate(A/W) functions
vfw32.inc/lib in masm32 version 11 do have the MCIWndCreate(A/W) functions, but try to import from the nonexistant DLL
i suppose this should be a bug report in the MASM32 project subforum   :P
Title: Re: Making a simple WAV player
Post by: MichaelW on January 14, 2012, 01:57:23 PM
I'm sure I posted an import library and an incomplete include file (for everything but the procedure prototypes, which are in separate include file that AFAIK is complete) somewhere here, but I can't seem to find it now, so here they are again.
Title: Re: Making a simple WAV player
Post by: bomz on January 14, 2012, 03:00:20 PM
How make player? I try hook mciSendCommand
Title: Re: Making a simple WAV player
Post by: dedndave on January 14, 2012, 04:51:21 PM
ok - my next question is...
how do we emulate all these macros ?   :P

http://msdn.microsoft.com/en-us/library/windows/desktop/dd743598%28v=VS.85%29.aspx

i guess someone with a C compiler can do it 
Title: Re: Making a simple WAV player
Post by: dedndave on January 14, 2012, 04:56:10 PM
maybe this guy has already done so
it looks like many of the macros are covered in ASM source...

http://4coder.org/assembler-source-code/73/

you can download the entire package, or modify the URL as follows for an example...

http://4coder.org/assembler-source-code/73/libmci/MCIWndCanConfig.asm.html

ok - well, it's not perfect
that particular function is supposed to be a macro, not a proc
but, the code is there to figure out how to write the macro
Title: Re: Making a simple WAV player
Post by: Bill Cravener on January 14, 2012, 06:28:31 PM
When I change my simple multimedia example so that it can list all file types it plays anything I throw at it. The example link below includes the player and a small AVI, WMV, WAV, MP3 and MPG-1 sample media file. At least on my Windows 7 64 bit machine and my old XP Home Edition SP3 machine it plays them all perfectly. Using my example my Win 7 machine will also play MPG-2's but my XP machine will not.

http://www.quickersoft.com/examples/Multimedia.zip
Title: Re: Making a simple WAV player
Post by: dedndave on January 14, 2012, 06:33:47 PM
i am running XP MCE2005 SP3
it plays the movie clip fine, Bill   :U
all you need is an MPEG-2 codec

here is one i know works...
http://www.free-codecs.com/download/stinky_mpeg_2_codec.htm

i use the k-lite mega codec package, which has all kinds of stuff   :P
Title: Re: Making a simple WAV player
Post by: Bill Cravener on January 14, 2012, 06:39:13 PM
Hi Dave, yes I figured that was the case. I need to spend some time on my XP box and get everything up to date. It really gets ignored now that I have this new Win 7 box. :bg
Title: Re: Making a simple WAV player
Post by: dedndave on January 14, 2012, 06:43:12 PM
well - MCE won't work without an MPEG-2 codec
oddly enough, MS does not provide one - lol
for that reason, MCE was only available in OEM machines, and had to be bundled with some kind of player that provided one
this Sony machine came with WinDVD, which includes the codec
the MPEG-2 codec is also required to play DVD's
Title: Re: Making a simple WAV player
Post by: bomz on January 14, 2012, 07:39:47 PM
Bill Cravener
Install K-Lite Codec Pack and you Simple MP3 Player may show all video files

http://www.erightsoft.com/SUPER.html - Starnge When I install this converter all video files may show too, including MKV conteiners
Title: Re: Making a simple WAV player
Post by: jj2007 on January 15, 2012, 12:57:27 AM
Here is one that takes a file from the commandline and plays it immediately.

I had lots of trouble playing avi files (decompressor not available) until I found a site that said "rename them to mpg", and wow, it worked :dazzled:
Title: Re: Making a simple WAV player
Post by: dedndave on January 15, 2012, 01:29:59 AM
little secret - that also works for VOB files   :P
although - i didn't have any luck with that player - lol
Title: Re: Making a simple WAV player
Post by: bomz on January 15, 2012, 02:09:54 AM
It 's depend from codecs which install and registering in system

http://www.codecguide.com/download_k-lite_codec_pack_full.htm
Title: Re: Making a simple WAV player
Post by: jj2007 on January 15, 2012, 06:42:36 AM
Quote from: dedndave on January 15, 2012, 01:29:59 AM
little secret - that also works for VOB files   :P
although - i didn't have any luck with that player - lol

You mean the one I posted? I just tried my luck with Hutch's suggestion (http://www.masm32.com/board/index.php?topic=18169.0) but no luck - even renaming to *.mpg just gave a message "damaged file". It opens fine in other players, though, meaning the codecs are there but mci is not able to find them.
For my own private *.avi files instead, renaming to *.mpg helps. If I use them as *.avi, there is a message "video not available", sound works (!), and the mouse is almost blocked.
The whole video business is very, very messy on Windows. I remember that frequently Windows doesn't know about its own formats. Greetings to Redmond :wink
Title: Re: Making a simple WAV player
Post by: dedndave on January 15, 2012, 01:13:49 PM
i tried a variety of file types - mp4, m4v, flv, and so on - all of which i have codecs for
many of them would not play with your player
by renaming them to mpg, they did play
it did not work for vob's - although, i have had success with that when i did not have a full set of codecs
Title: Re: Making a simple WAV player
Post by: Bill Cravener on January 15, 2012, 02:33:42 PM
Dave I have a copy of Richard Hammond's BBC documentry of Evil Knievel in VOB format (last he ever gave) its an hour long and it plays perfectly on my Win 7 machine from that simple media player example of mine. I'm quite certain using the MPEGVideo type you can play most any media file if the correct codec is installed on a machine even VOB's. 
Title: Re: Making a simple WAV player
Post by: dedndave on January 15, 2012, 02:58:41 PM
yah - VOB files are containers for MPEG video information   :P
Title: Re: Making a simple WAV player
Post by: Bill Cravener on January 15, 2012, 06:42:56 PM
Dave,

Well to be honest about it I'm not all that savvy about all that media shit, I get an idea for an example I want to create and I start digging into Microsoft's SDK. That's how I derive every example I've created over all these years and at the same time having one hell of a lot of fun doing so. :bg
Title: Re: Making a simple WAV player
Post by: dedndave on January 15, 2012, 07:01:01 PM
i hear ya, Bill
i am a novice, too - lol
i do have some interest - i'd like to learn more about it
for now, i am just trying to learn my way around the API   :P
Title: Re: Making a simple WAV player
Post by: bomz on January 19, 2012, 11:23:46 AM
(http://smiles.kolobok.us/light_skin/vava.gif)
Quote.386

.model flat, stdcall
option casemap :none

        include \masm32\include\windows.inc
        include \masm32\include\user32.inc
        include \masm32\include\kernel32.inc
        include \masm32\include\comctl32.inc
        include \masm32\include\winmm.inc

        includelib \masm32\lib\user32.lib
        includelib \masm32\lib\kernel32.lib
        includelib \masm32\lib\comctl32.lib
        includelib \masm32\lib\winmm.lib

HookProc   PROTO :DWORD, :DWORD, :DWORD
HookWndProc   PROTO :DWORD, :DWORD, :DWORD, :DWORD

.data
mestitle   db "Bomz",0
Mp3Device   db "MPEGVideo",0
FileName   db "Seven.Years.in.Tibet.1997.BDRip.720p.mkv",0

.data?
mciOpenParms   MCI_OPEN_PARMS <>
mciPlayParms   MCI_PLAY_PARMS <>
Mp3DeviceID   dd ?
hHook      dd ?
ThreadId   dd ?

.code
start:

   invoke GetCurrentThreadId
   mov ThreadId, eax
   invoke SetWindowsHookEx,WH_CALLWNDPROC,addr HookProc,NULL,ThreadId
   mov hHook, eax

      mov eax,0
      mov mciPlayParms.dwCallback,eax   ; функция которой послать сообщение MM_MCINOTIFY об окончании воспроизведения
      lea eax, Mp3Device
      mov mciOpenParms.lpstrDeviceType,eax
      lea eax,FileName
      mov mciOpenParms.lpstrElementName,eax
      invoke mciSendCommand,0,MCI_OPEN,MCI_OPEN_TYPE or MCI_OPEN_ELEMENT,ADDR mciOpenParms
      ;invoke MessageBox,0,0,ADDR mestitle,MB_ICONASTERISK
      mov eax,mciOpenParms.wDeviceID
      mov Mp3DeviceID,eax
      invoke mciSendCommand,Mp3DeviceID,MCI_PLAY,MCI_NOTIFY,ADDR mciPlayParms
      invoke MessageBox,0,0,ADDR mestitle,0;MB_ICONASTERISK
      invoke mciSendCommand,Mp3DeviceID,MCI_CLOSE,0,0
      invoke ExitProcess,0


HookProc PROC nCode:DWORD,wParam:DWORD,lParam:DWORD

   .if nCode==HC_ACTION
   mov edx, lParam
   assume edx:PTR CWPSTRUCT
      .if [edx].message == WM_INITDIALOG
      invoke SetWindowText, [edx].hwnd, addr Mp3Device
      ;invoke MessageBeep, MB_ICONASTERISK
      invoke UnhookWindowsHookEx,hHook
      .endif
   assume edx:nothing
   .endif

   invoke CallNextHookEx,hHook,nCode,wParam,lParam
   xor eax,eax
   ret

HookProc endp

end start