News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

mciSendCommandA error

Started by Magnum, November 29, 2011, 12:16:27 AM

Previous topic - Next topic

Magnum

This fails at line containing call    mciSendCommandA

It's too bad that Windows can't support embedding mp3 files like they do for wav files.
The coding would be simpler and smaller.  :P
Have a great day,
                         Andy

Magnum

I added mciGetErrorString to narrow down the problem and got

"Cannot determine device type from the given filename extension."

A search for that said some MCI entensions may be missing.
I added mp3 but no change.


.386                   
.Model Flat ,StdCall   
option casemap:none     

include \Masm32\include\windows.inc
include \Masm32\include\kernel32.inc
include \Masm32\include\user32.inc
include \Masm32\include\winmm.inc
includelib \Masm32\lib\kernel32.lib
includelib \Masm32\lib\user32.lib
includelib \Masm32\lib\winmm.lib

GetModuleHandleA        PROTO :DWORD

FindResourceA           PROTO :DWORD,:DWORD,:DWORD
SizeofResource          PROTO :DWORD,:DWORD
LoadResource            PROTO :DWORD,:DWORD
LockResource            PROTO :DWORD
CreateFileA             PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD
WriteFile               PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD
CloseHandle             PROTO :DWORD

mciSendCommandA         PROTO :DWORD,:DWORD,:DWORD,:DWORD

MessageBoxA             PROTO :DWORD,:DWORD,:DWORD,:DWORD
ExitProcess             PROTO :DWORD

.Data

SoundName               db "TDSound",0                  ;sound name in resource
MB1Titel                db "Program Error",0            ;message box name
MB1Text                 db "Bad work ...",0             ;message box text
MB2Titel                db "Play_Mp3",0           ;message box name
MB2Text                 db "Playing an Mp3.",0  ;message box text
FileName                db "c:\masm32\source\temp.mp3",0                 ;temporary filename
Box                     db " ",0
Oops                    db 100 Dup(?), 0

.data?

hInstance               dd ?
handleResource          dd ?
sizeResource            dd ?
pointerResource         dd ?

handleFile              dd ?
returnFile              dd ?

; - MCI_OPEN_PARMS Structure ( API=mciSendCommand ) -
open_dwCallback         dd ?
open_wDeviceID          dd ?
open_lpstrDeviceType    dd ?
open_lpstrElementName   dd ?
open_lpstrAlias         dd ?

; - MCI_GENERIC_PARMS Structure ( API=mciSendCommand ) -
generic_dwCallback      dd ?

; - MCI_PLAY_PARMS Structure ( API=mciSendCommand ) -
play_dwCallback         dd ?
play_dwFrom             dd ?
play_dwTo               dd ?

.Code

Main:

;==============================================================================
; Always get your program ID first (API=GetModuleHandleA)
;------------------------------------------------------------------------------
push    0h                              ;lpModuleHandle, 0=get program handle
call    GetModuleHandleA                ;- API Function -
mov     hInstance,eax                   ;return value in eax=handle of program

;==============================================================================
; API "FindResource" determines the location of a resource with the specified
; type and name in the specified module
;------------------------------------------------------------------------------
push    10                          ;lpType,address of resource type, RT_RCDATA
push    OFFSET SoundName            ;lpName, address of resource name
push    hInstance                   ;hModule, resource-module handle
call    FindResourceA               ;- API Function -
cmp     eax,0h                      ;
je      ErrorPrg                    ;
mov     handleResource,eax          ;
;------------------------------------------------------------------------------
; API "SizeofResource" returns the size, in bytes, of the specified resource.
;------------------------------------------------------------------------------
push    handleResource              ;hrsrc, resource handle
push    hInstance                   ;hModule, resource-module handle
call    SizeofResource              ;- API Function -
cmp     eax,0h                      ;
je      ErrorPrg                    ;
mov     sizeResource,eax            ;
;------------------------------------------------------------------------------
; API "LoadResource" loads the specified resource into global memory.
;------------------------------------------------------------------------------
push    handleResource              ;hResInfo, resource handle
push    hInstance                   ;hModule, resource-module handle
call    LoadResource                ;- API Function -
cmp     eax,0h                      ;
je      ErrorPrg                    ;
;------------------------------------------------------------------------------
; API "LockResource" locks the specified resource in memory.
;------------------------------------------------------------------------------
push    eax                         ;hResData, handle to resource to lock
call    LockResource                ;- API Function -
cmp     eax,0h                      ;
je      ErrorPrg                    ;
mov     pointerResource,eax         ;pointer to the first byte of the resource

;==============================================================================
; API "CreateFileA" creates or opens a file, returns a handle to access object.
;------------------------------------------------------------------------------
push    0h                          ;hTemplateFile,
push    80h                         ;dwFlagsAndAttributes, 80h=normal
push    2h                          ;dwCreationDistribution, CREATE_ALWAYS
push    0h                          ;lpSecurityAttributes,
push    0h                          ;dwShareMode,
push    40000000h                   ;dwDesiredAccess,GENERIC_WRITE
push    OFFSET FileName             ;lpFileName,pointer to filename
call    CreateFileA                 ;- API Function -
cmp     eax,-1                      ;error ? INVALID_HANDLE_VALUE = -1
je      ErrorPrg                    ;
mov     handleFile,eax              ;store handle in variable
;------------------------------------------------------------------------------
; API "WriteFile" writes data to a file
;------------------------------------------------------------------------------
; It writes the temp file O.K.

push    0h                          ;lpOverlapped, structure overlapped I/O
push    OFFSET returnFile           ;lpNumberOfBytesWritten,
push    sizeResource                ;nNumberOfBytesToWrite, bytes to write
push    pointerResource             ;lpBuffer, address data write to file
push    handleFile                  ;hFile, handle of file to write to
call    WriteFile                   ;- API Function -
cmp     eax,0h                      ;check for error
je      ErrorPrg                    ;
;------------------------------------------------------------------------------
; API "CloseHandle" closes an open object handle.
;------------------------------------------------------------------------------
push    handleFile                  ;hObject, handle of object to close 
call    CloseHandle                 ;- API Function -
cmp     eax,0h                      ;check for error
je      ErrorPrg                    ;
;int 3
;==============================================================================
; API "mciSendCommandA" here opens the device
;------------------------------------------------------------------------------
mov     open_lpstrDeviceType,0h                 ;fill MCI_OPEN_PARMS structure
mov     open_lpstrElementName,OFFSET FileName   ;
push    OFFSET open_dwCallback                  ;dwParam, MCI_OPEN_PARMS struc.
push    0200h                                   ;fdwCommand,
                                               ;MCI_OPEN_ELEMENT   = 0200h
                                               ;MCI_OPEN_SHAREABLE = 0100h
push    0803h                                   ;uMsg, command msg. , MCI_OPEN
push    0h                                      ;IDDevice, here not used
call    mciSendCommandA                         ;- API Function -
cmp     eax,0h                                  ; EAX = 119h
Invoke mciGetErrorString, Eax, Addr szFehler, 128
Invoke MessageBox, 0, Addr Oops, Addr Box, MB_OK Or MB_ICONERROR
;
; Getting this message, "Cannot determine device type from the given filename extension."
;
;int 3
jne     ErrorPrg                                ;
;int 3
;------------------------------------------------------------------------------
; API "mciSendCommandA", MCI_PLAY command begins transmitting output data.
;------------------------------------------------------------------------------
push    OFFSET play_dwCallback                  ;dwParam, MCI_PLAY_PARMS struc.
push    0h                                      ;fdwCommand, MCI_FROM
push    0806h                                   ;uMsg, command msg. , MCI_PLAY
push    open_wDeviceID                          ;IDDevice, given from MCI_OPEN
call    mciSendCommandA                         ;- API Function -
cmp     eax,0h                                  ;
jne     ErrorPrg                                ;
;------------------------------------------------------------------------------
; API "MessageBoxA" creates a message box.
;------------------------------------------------------------------------------
push    0h                              ;uType, style, 0=MB_OK Button
push    OFFSET MB2Titel                 ;lpCaption,pointer to title text
push    OFFSET MB2Text                  ;lpText,pointer to text message box
push    0h                              ;handle of owner window 0=no owner
call    MessageBoxA                     ;- API Function
;------------------------------------------------------------------------------
; API "mciSendCommandA" here closes the device
;------------------------------------------------------------------------------
push    OFFSET generic_dwCallback   ;dwParam, address MCI_GENERIC_PARMS struc.
push    0h                          ;fdwCommand,
push    804h                        ;uMsg, command message, MCI_CLOSE
push    open_wDeviceID              ;IDDevice,
call    mciSendCommandA             ;- API Function -
cmp     eax,0h                      ;
jne     ErrorPrg                    ;

ExitPrg:

push    hInstance                       ;push our programm handle to exit
invoke DeleteFile,offset FileName
call    ExitProcess                     ;- API Function -

ErrorPrg:

push    0h                              ;uType, style, 0=MB_OK Button
push    OFFSET MB1Titel                 ;lpCaption,pointer to title text
push    OFFSET MB1Text                  ;lpText,pointer to text message box
push    0h                              ;handle of owner window 0=no owner
call    MessageBoxA                     ;- API Function -
jmp     ExitPrg

end Main                             
Have a great day,
                         Andy

dedndave

see if this helps, Andy

scroll down to post #6
http://cboard.cprogramming.com/windows-programming/17760-how-do-i-play-mp3.html

i was playing with this stuff a while back - trying to play in-memory MIDI files
i didn't have time to mess with it, but i think it can work - you just have to do some reading on the commands
i'd be interested to know what you do to get it going

baltoro

MAGNUM,
If I were writing this kind of application, I would want to verify the Device Capabilities, once I had the correct ID to the MCI device. This is a standard approach.
capability command.
I remember doing this kind of thing with a MIDI program I wrote over a year ago. The way the Windows operating system lists the audio-capable devices available on your machine is not at all intuitive.
Working with MCI Devices
Typically, you only have one audio device on your computer, but, the capabilities vary, and Windows categorizes the sound card based on what the Audio Driver reports when it is initialized. And, usually there are several audio drivers.
I would try the open command with a WAVE format file (I think they all play wave files). and then check the capabilities once you get the Device ID.
But, it's weird,...the MP3 is one of the most common audio file formats,...I suppose for some unknown reason, the file extension is not recognized.
Baltoro

Magnum

Thanks baltoro.

I am reading up on it now.

Andy
Have a great day,
                         Andy

dedndave

QuoteHowever, if you call mciSendCommand with the MCI_ALL_DEVICE_ID device type - it will play.

i thought that was the tip   :P

Magnum

invoke mciGetDeviceID,MCI_ALL_DEVICE_ID

I used this, but don't know where the device identifier is at.

I just love the SDK's cryptic explanation,

"Returns the device identifier assigned to the device when it was opened if successful."

Dave,

In the previous code, push    open_wDeviceID is the same as MCI_ALL_DEVICE_ID.

What frustrating is that I thought this code once worked.
Have a great day,
                         Andy

dedndave

there must be something amiss with the "create file from resource" code, Andy
i was able to get a sound by playing the MP3 file directly
i replaced the message box with a Sleep   :P

        .XCREF
        .NOLIST
        INCLUDE    \masm32\include\masm32rt.inc
        INCLUDE    \masm32\include\winmm.inc
        INCLUDELIB \masm32\lib\winmm.lib
        .LIST

;#############################################################################################################

        .DATA

FileName db 'phone-disconnect-1.mp3',0

;*************************************************************************************************************

        .DATA?

; - MCI_OPEN_PARMS Structure ( API=mciSendCommand ) -
open_dwCallback         dd ?
open_wDeviceID          dd ?
open_lpstrDeviceType    dd ?
open_lpstrElementName   dd ?
open_lpstrAlias         dd ?

; - MCI_GENERIC_PARMS Structure ( API=mciSendCommand ) -
generic_dwCallback      dd ?

; - MCI_PLAY_PARMS Structure ( API=mciSendCommand ) -
play_dwCallback         dd ?
play_dwFrom             dd ?
play_dwTo               dd ?

;#############################################################################################################

        .CODE

_main   PROC

mov     open_lpstrDeviceType,0h                 ;fill MCI_OPEN_PARMS structure
mov     open_lpstrElementName,OFFSET FileName   ;
push    OFFSET open_dwCallback                  ;dwParam, MCI_OPEN_PARMS struc.
push    0200h                                   ;fdwCommand,
                                               ;MCI_OPEN_ELEMENT   = 0200h
                                               ;MCI_OPEN_SHAREABLE = 0100h
push    0803h                                   ;uMsg, command msg. , MCI_OPEN
push    0h                                      ;IDDevice, here not used
call    mciSendCommand                          ;- API Function -


push    OFFSET play_dwCallback                  ;dwParam, MCI_PLAY_PARMS struc.
push    0h                                      ;fdwCommand, MCI_FROM
push    0806h                                   ;uMsg, command msg. , MCI_PLAY
push    open_wDeviceID                          ;IDDevice, given from MCI_OPEN
call    mciSendCommand                          ;- API Function -

        INVOKE  Sleep,4000

push    OFFSET generic_dwCallback   ;dwParam, address MCI_GENERIC_PARMS struc.
push    0h                          ;fdwCommand,
push    804h                        ;uMsg, command message, MCI_CLOSE
push    open_wDeviceID              ;IDDevice,
call    mciSendCommand              ;- API Function -

        INVOKE  ExitProcess,0

_main   ENDP

;#############################################################################################################

        END     _main


the program could use a little cleanup
those structures are probably defined in windows.inc

dedndave

by the way - you may want to open the sound mixer and make sure no devices are turned all the way down or muted
double-click the volume control

because - your code works, here - once i turned up the knobs   :lol

Magnum

I think my computer has a zombie in it.

You code ran O.K. but didn't play it.

In debug, it said Error_Mod_Not_Found.

My code makes the temp mp3 file O.K. and it is playable.

I even tried restoring an old image of my hard drive.

I will just embed a wave file, even if its 10 times the size of a mp3.  :U
Have a great day,
                         Andy

dedndave

it is the "Wave" device volume
do you have that device on your sound mixer ?

if not, check the Hardware Device Manager

dedndave

http://www.soundjay.com/phone-sounds-1.html

if we look around, i am sure we can find a smaller file   :P

Magnum

After upgrading Media Player 10.0 to 11.0, the problem went away.

Have a great day,
                         Andy