flat assembler
Message board for the users of flat assembler.

Index > Windows > DirectSound problem

Author
Thread Post new topic Reply to topic
ManOfSteel



Joined: 02 Feb 2005
Posts: 1154
ManOfSteel 06 May 2007, 10:01
Hello,

After reading Farrier's DirectSound recording utility, I tried to make a program that will play a small wave file.

Code:
ds                DirectSound
dsb              DirectSoundBuffer
dsbd               DSBUFFERDESC
WaveFormatEx    WAVEFORMATEX

...

         invoke  DirectSoundCreate,\
                        0,\
                        ds,\
                       0

               cominvk ds,\
                       SetCooperativeLevel,\
                      [hwnd],\
                   DSSCL_NORMAL

            mov     [WaveFormatEx.wFormatTag],WAVE_FORMAT_PCM
           mov     [WaveFormatEx.nChannels],2
          mov     [WaveFormatEx.nSamplesPerSec],44100
         mov     [WaveFormatEx.nAvgBytesPerSec],176400
               mov     [WaveFormatEx.nBlockAlign],4
                mov     [WaveFormatEx.wBitsPerSample],16
            mov     [WaveFormatEx.cbSize],0

         mov     [dsbd.dwSize],sizeof.DSBUFFERDESC
           mov     [dsbd.dwFlags],DSBCAPS_GLOBALFOCUS or DSBCAPS_CTRLPOSITIONNOTIFY
            mov     [dsbd.dwBufferBytes],176400
         mov     [dsbd.lpwfxFormat],WaveFormatEx
             cominvk ds,\
                       CreateSoundBuffer,\
                        dsbd,\
                     dsb,\
                      0
           cmp     eax,DS_OK
           jne     Error
    


CreateSoundBuffer doesn't seem to be working: the code jumps to "Error" right after the call.

What am I doing wrong?

Thanks in advance.
Post 06 May 2007, 10:01
View user's profile Send private message Reply with quote
farrier



Joined: 26 Aug 2004
Posts: 274
Location: North Central Mississippi
farrier 06 May 2007, 15:29
ManOfSteel,

As vid would say: "Always check the return value of any Windows function"!

What were the return values for the DirectSoundCreate and SetCooperativeLevel calls? That may give you your answer.

Also, what is the return value from the CreateSoundBuffer call?

hth,

farrier

_________________
Some Assembly Required
It's a good day to code!
U.S.Constitution; Bill of Rights; Amendment 1:
... the right of the people peaceably to assemble, ...
The code is dark, and full of errors!
Post 06 May 2007, 15:29
View user's profile Send private message Reply with quote
madmatt



Joined: 07 Oct 2003
Posts: 1045
Location: Michigan, USA
madmatt 07 May 2007, 09:58
Everything looks good, except for:
1. should zero out 'dsbd' and 'WaveFormatEx' structures before using.
2. I use these flags for the buffer desc: DSBCAPS_STATIC or DSBCAPS_LOCSOFTWARE or DSBCAPS_CTRLFREQUENCY or DSBCAPS_CTRLPAN or DSBCAPS_CTRLVOLUME.
3. And as farrier quoted, Check ALL return values for errors. This helps in debugging also.
Post 07 May 2007, 09:58
View user's profile Send private message Reply with quote
ManOfSteel



Joined: 02 Feb 2005
Posts: 1154
ManOfSteel 07 May 2007, 11:52
Hello Farrier,
Quote:
As vid would say: "Always check the return value of any Windows function"!

Actually, that's what I'm doing. I only removed the checks because those two functions are working fine. I always compare the returning eax with 0 (which is DS_OK) after each API.

Quote:
What were the return values for the DirectSoundCreate and SetCooperativeLevel calls? That may give you your answer.

I'm getting 0 on both of them, so I guess CreateSoundBuffer must be the faulty one.

Quote:
Also, what is the return value from the CreateSoundBuffer call?

2147942487 in decimal, which is ... DSERR_INVALIDPARAM.
Is it necessary to do a QueryInterface before CreateSoundBuffer? Could it be that?

By the way, I read somewhere DirectSound can't play other than 22KHZ, 8-Bit, Mono at the NORMAL priority (SetCooperativeLevel,[hwnd],DSSCL_NORMAL). Is it true?
I changed the code to:
Code:
mov [WaveFormatEx.nChannels],1            ;mono
mov [WaveFormatEx.nSamplesPerSec],22050   ;22050 sample/s
mov [WaveFormatEx.nAvgBytesPerSec],44100  ;nSamplesPerSec * nBlockAlign
mov [WaveFormatEx.nBlockAlign],2          ;(nChannels * wBitsPerSample) / 8
mov [WaveFormatEx.wBitsPerSample],8       ;8 bits/sample
    

Are these values above (1 for mono, etc) correct?
Anyway, the result is still the same.


madmatt,
Thanks, I'll check all this later. I must go now. I'll be back soon.
Post 07 May 2007, 11:52
View user's profile Send private message Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid 07 May 2007, 12:02
ManOfSteel wrote:

Quote:
As vid would say: "Always check the return value of any Windows function"!

Actually, that's what I'm doing. I only removed the checks because those two functions are working fine. I always compare the returning eax with 0 (which is DS_OK) after each API.
If function worked fine one time on your computer, it doesn't mean they always will in future and on everyone's machine.

You really should leave those checks there.
Post 07 May 2007, 12:02
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
ManOfSteel



Joined: 02 Feb 2005
Posts: 1154
ManOfSteel 07 May 2007, 13:55
madmatt,
I clean both structures with RtlZeroMemory and I also tried the flags you told me about, but it's still the same.

vid,
Quote:

If function worked fine one time on your computer, it doesn't mean they always will in future and on everyone's machine.
You really should leave those checks there.

Ok, I will.
Post 07 May 2007, 13:55
View user's profile Send private message Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid 07 May 2007, 14:32
ManOfSteel:
look at MSDN reference of IDirectSound8::CreateSoundBuffer, and check description of "ppDSBuffer", there is the bug.

I'll leave rest on you Wink
Post 07 May 2007, 14:32
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
farrier



Joined: 26 Aug 2004
Posts: 274
Location: North Central Mississippi
farrier 07 May 2007, 14:37
ManOfSteel,

You can use GetCaps to find out exactly what your sound card is capable of. This will make sure you can use the parameters you have coded.

hth,

farrier

_________________
Some Assembly Required
It's a good day to code!
U.S.Constitution; Bill of Rights; Amendment 1:
... the right of the people peaceably to assemble, ...
The code is dark, and full of errors!
Post 07 May 2007, 14:37
View user's profile Send private message Reply with quote
ManOfSteel



Joined: 02 Feb 2005
Posts: 1154
ManOfSteel 08 May 2007, 05:54
vid,
I already read the MSDN. Are you suggesting that I write ppDSBuffer as a dword value in the .data section? Like that:
Code:
ppDSBuff dd ?
...
cominvk ds,CreateSoundBuffer,dsbd,ppDSBuff,0
    


Well, I've seen some code doing that and I already thought about it, but it doesn't work any better. It still gives me the same invalid parameter error.

In the DirectSound recording utility I talked about earlier, Farrier did it like me (dsb DirectSoundBuffer) and it worked fine. I'm really confused.


farrier,
Quote:
You can use GetCaps to find out exactly what your sound card is capable of. This will make sure you can use the parameters you have coded.

I'm using the same flags and settings as you did in your recording/playback utility (from the 'com_invoke' macro thread) and this utility is working fine.
Post 08 May 2007, 05:54
View user's profile Send private message Reply with quote
farrier



Joined: 26 Aug 2004
Posts: 274
Location: North Central Mississippi
farrier 08 May 2007, 06:46
ManOfSteel,

Just a wild guess:

Try removing the flags: DSBCAPS_GLOBALFOCUS or DSBCAPS_CTRLPOSITIONNOTIFY and try again.

The only other difference I can see is that I have been using the '8' functions, only because they are the ones recommended in the latest SDK. I use DirectSoundCreate8, you use DirectSoundCreate. Other than that, I can't see why yours is not working.

hth,

farrier

_________________
Some Assembly Required
It's a good day to code!
U.S.Constitution; Bill of Rights; Amendment 1:
... the right of the people peaceably to assemble, ...
The code is dark, and full of errors!
Post 08 May 2007, 06:46
View user's profile Send private message Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid 08 May 2007, 09:27
Quote:
I already read the MSDN. Are you suggesting that I write ppDSBuffer as a dword value in the .data section? Like that:

Yes, that's how the function must be called.

You don't pass pointer to structure (LPDIRECTSOUNDBUFFER = DIRECTSOUNDBUFFER *, LP = long pointer). You pass pointer to pointer to structure (LPDIRECTSOUNDBUFFER* = DIRECTSOUNDBUFFER**). In assembly terms, where every pointer is dword, you pass address of dword, which will on return hold address of filled structure.

But naybe you also have some other errors there.
Post 08 May 2007, 09:27
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
ManOfSteel



Joined: 02 Feb 2005
Posts: 1154
ManOfSteel 09 May 2007, 20:41
If what you say is correct, then I should do the same with DirectSoundCreate. Its second parameter is the "address of a variable to receive an IDirectSound8 interface pointer".

So when I call IDirectSound::SetCooperativeLevel, I will use the pointer that I just got from the first function.

For that I can't use cominvk anymore. I will have to use comcall, right?
Code:
ds       DirectSound
dsbd     DSBUFFERDESC

ppDS     dd ?
ppDSBuff dd ?

invoke   DirectSoundCreate,0,ppDS,0
comcall  [ppDS],ds,SetCooperativeLevel,[hwnd],DSSCL_NORMAL
...
comcall         [ppDS],ds,CreateSoundBuffer,dsbd,ppDSBuff,0
    


The problem is still there: the first two functions still work well, while CreateSoundBuffer doesn't.

Anyway, the output of both codes is quite the same: the disassembly is almost identical. I think there's an explanation about the dword pointer in the manual:
Quote:

You can also use the name of COM interface in the same way as the name of data structure, to define the variable that will hold the handle to object of given type:
ShellTaskBar ITaskBarList
The above line defines the double word variable, in which the handle to COM object can be stored. After storing there the handle to an object, its methods can be called with the cominvk.
Post 09 May 2007, 20:41
View user's profile Send private message Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid 09 May 2007, 21:42
sorry, you was right. I forgot that FASM's "DSBUFFERDESC" is C's "LPDSBUFFERDESC" etc...
Embarassed
Post 09 May 2007, 21:42
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.