[C++] Directsound buffer

Pagina: 1
Acties:
  • 122 views sinds 30-01-2008
  • Reageer

  • Nikel
  • Registratie: Juli 2000
  • Niet online
Omdat ik wil dat er tijdens het afspelen van mijn geluid geen ander geluid doorheen kan worden afgespeeld en omdat ik zoveel mogelijk controle wil hebben wil ik een primary directsound buffer gebruiken. Nu heb ik een probleem met IDirectSoundBuffer8::SetFormat. Eeen stukje uit msdn:
code:
1
2
3
The SetFormat method sets the format of the primary buffer. Whenever this application has the input focus, DirectSound will set the primary buffer to the specified format.

Since primary sound buffers do not support the IDirectSoundBuffer8 interface, this method must be called on IDirectSoundBuffer.

van: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dx8_c/directx_cpp/htm/_dx_idirectsoundbuffer8_setformat_dxaudio.asp

Nu mijn code:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
ZeroMemory(&waveFormat, sizeof(waveFormat));

    waveFormat.wFormatTag = WAVE_FORMAT_PCM;
    waveFormat.nChannels = (WORD)numchannels;
    waveFormat.nSamplesPerSec = (DWORD)samplerate;
    waveFormat.nAvgBytesPerSec = (DWORD)(samplerate * bitspersamp * numchannels / 8);
    waveFormat.nBlockAlign = (WORD)(bitspersamp * numchannels / 8);
    waveFormat.wBitsPerSample = (WORD)bitspersamp;
    
    ZeroMemory(&priBufSet, sizeof(priBufSet));

    priBufSet.dwSize = sizeof(DSBUFFERDESC);
    priBufSet.dwFlags = DSBCAPS_GLOBALFOCUS;
    priBufSet.dwBufferBytes = 26460;
    priBufSet.lpwfxFormat = &waveFormat;

    HRESULT temp2;
    HRESULT temp;

    if (DirectSoundCreate(NULL, &soundcard, NULL) == DS_OK) //create direct sound object
    {
      //ok, DirectSound Object created, let's take control now...
      if (soundcard->SetCooperativeLevel(out.hMainWindow, DSSCL_WRITEPRIMARY) == DS_OK)
      {
            
            if (soundcard->CreateSoundBuffer(&priBufSet, &priBuf, NULL) != DS_OK)
            {
                MessageBox(out.hMainWindow, "createsoundbuffer mislukt!", "mooizo!", MB_OK);
                return -1;
            }
            
            priBuf->Stop();


            temp = priBuf->SetFormat(&waveFormat);
            if (temp == DSERR_INVALIDCALL)
            {
                MessageBox(out.hMainWindow, "Set primary buffer format didn't Work1!", "BAD!!", MB_OK);
                return -1;
            }

Ik krijg dus de onderste messagebox te zien. Wat ik niet helemaal snap is de zin "Since primary sound buffers do not support the IDirectSoundBuffer8 interface, this method must be called on IDirectSoundBuffer." uit msdn. Wat bedoelen ze hier precies mee, en wat moet ik ermee? Het enige verschil is dat er geen 8 achter staat. Maar je gebruikt toch sowieso alle namen zonder die 8 erbij? Kan iemand die uitleggen, en natuurlijk ook kijken wat er nu precies fout is in mijn code.

Verwijderd

8 bits

Verwijderd

Op zondag 26 mei 2002 12:57 schreef robh het volgende:
8 bits
Praat geen onzin. die 8 slaat op het versie nummer van de interface IDirectSoundBuffer8 zal wat meer functies supporten dan de orignele IDirectSoundBuffer.

  • Nikel
  • Registratie: Juli 2000
  • Niet online
Maar je gebruikt toch zelf alleen maar als LPDIRECTSOUNDBUFFER, zoals in mijn declaraties:
code:
1
2
LPDIRECTSOUND soundcard = NULL;
LPDIRECTSOUNDBUFFER priBuf = NULL;

Hoe zou je dan kunnen kiezen tussen de versie met en zonder 8?

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03-09 13:30

.oisyn

Moderator Devschuur®

Demotivational Speaker

probeer eens:
code:
1
IDirectSoundBuffer8::SetFormat (...)

(volgens mij is die 8 die ze weggelaten hebben in de msdn gewoon een schrijffout, er is namelijk helemaal geen IDirectSoundBuffer) .edit: zie onder :)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Verwijderd

Op zondag 26 mei 2002 15:33 schreef .oisyn het volgende:
(volgens mij is die 8 die ze weggelaten hebben in de msdn gewoon een schrijffout, er is namelijk helemaal geen IDirectSoundBuffer)
Tuurlijk wel, alleen niet superduidelijk gedocumenteerd :Y)
For the primary buffer, you must use the IDirectSoundBuffer interface. IDirectSoundBuffer8 is not available. IDirectSoundBuffer is not documented separately. For documentation, see the corresponding IDirectSoundBuffer8 methods.

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03-09 13:30

.oisyn

Moderator Devschuur®

Demotivational Speaker

oh IDirectSoundBuffer is gewoon de oude versie :)
The IDirectSoundBuffer8 interface is used to manage sound buffers.

The IDirectSoundBuffer8 interface supersedes IDirectSoundBuffer and adds new methods.

To obtain the interface, use the IDirectSound8::CreateSoundBuffer method to retrieve IDirectSoundBuffer, and then pass IID_IDirectSoundBuffer8 to IDirectSoundBuffer::QueryInterface.

For the primary buffer, you must use the IDirectSoundBuffer interface. IDirectSoundBuffer8 is not available. IDirectSoundBuffer is not documented separately. For documentation, see the corresponding IDirectSoundBuffer8 methods.

Not all methods of IDirectSoundBuffer are valid for primary buffers. For example, SetCurrentPosition will fail. See the reference topics for individual methods.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Nikel
  • Registratie: Juli 2000
  • Niet online
To obtain the interface, use the IDirectSound8::CreateSoundBuffer method to retrieve IDirectSoundBuffer, and then pass IID_IDirectSoundBuffer8 to IDirectSoundBuffer::QueryInterface.



Hoe doe ik dat? Wat is IID_IDirectSoundBuffer, en waar haal ik hem vandaan?

Verwijderd

Op zondag 26 mei 2002 16:46 schreef Nikel het volgende:
Hoe doe ik dat? Wat is IID_IDirectSoundBuffer, en waar haal ik hem vandaan?
Das de guid van de IDirectSoundBuffer en 't ding zal ongetwijfeld in je directX headerfiles zitten.

  • Nikel
  • Registratie: Juli 2000
  • Niet online
In dsound.h staat ergens:

DEFINE_GUID(IID_IDirectSoundBuffer, 0x279AFA85, 0x4981, 0x11CE, 0xA5, 0x21, 0x00, 0x20, 0xAF, 0x0B, 0xE5, 0x60);

Maar bij builden krijg ik de volgende error:

out_filter.obj : error LNK2001: unresolved external symbol _IID_IDirectSoundBuffer


Hoe ik denk dat het moet (maar wat vast niet goed is):
code:
1
2
3
4
LPVOID interf;
            priBuf->QueryInterface(&IID_IDirectSoundBuffer, &interf);
            
            interf->SetFormat(&waveFormat);

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 21:50
Op zondag 26 mei 2002 16:54 schreef Nikel het volgende:
code:
1
priBuf->QueryInterface(&IID_IDirectSoundBuffer, &interf);
Ik ben er vrij zeker van dat die eerste ampersand weg moet. Hoe het verder moet weet ik niet.

Is dit niet in de SDK tutorials te vinden, of als voorbeeld bij QueryInterface?

  • Nikel
  • Registratie: Juli 2000
  • Niet online
Op zondag 26 mei 2002 17:31 schreef Soultaker het volgende:

[..]

Ik ben er vrij zeker van dat die eerste ampersand weg moet. Hoe het verder moet weet ik niet.

Is dit niet in de SDK tutorials te vinden, of als voorbeeld bij QueryInterface?
Zonder die eerste ampersand krijg ik juist een error dat dat symbool niet bestaat oid. Voor mijn gevoel hoort het er ook niet, dus zal ik idd wel iets anders fout doen.

Het is trouwens niet terug te vinden in de tutorials. QueryInterface vind ik al helemaal summier gedocumenteerd, maar misschien zoek ik op de verkeerde plaats.

Verwijderd

Op zondag 26 mei 2002 17:34 schreef Nikel het volgende:
Het is trouwens niet terug te vinden in de tutorials. QueryInterface vind ik al helemaal summier gedocumenteerd, maar misschien zoek ik op de verkeerde plaats.
Er is ook niet zo heel veel boeiends aan QueryInterface, je request een interface aan 'n object en dan krijg je of je interface terug als ie 'm support of 'n error als ie 'm niet support..

die link error krijg je denk ik omdat je dsound.lib niet mee linkt?

  • Nikel
  • Registratie: Juli 2000
  • Niet online
dsound.lib link ik natuurlijk wel mee, anders zou er wel heel wat meer fout gaan.

Verwijderd

Op zondag 26 mei 2002 18:23 schreef Nikel het volgende:
dsound.lib link ik natuurlijk wel mee, anders zou er wel heel wat meer fout gaan.
heb je dxguid.lib al geprobeerd?

  • Nikel
  • Registratie: Juli 2000
  • Niet online
Nee, die nog niet, ga ik nu proberen.

  • Nikel
  • Registratie: Juli 2000
  • Niet online
Dat lost dat probleem op.
code:
1
2
3
4
5
6
LPVOID interf;
            
            priBuf->QueryInterface(IID_IDirectSoundBuffer, &interf);


            interf->SetFormat(&waveFormat);

Die onderste regel is niet juist, E:\Data\Out-filter\out_filter.cpp(155) : error C2227: left of '->SetFormat' must point to class/struct/union


Hoe moet het dan wel?

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03-09 13:30

.oisyn

Moderator Devschuur®

Demotivational Speaker

maak van die interf eens een IDirectSoundBuffer8 * ipv een void * :)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Verwijderd

Die onderste regel is niet juist, E:\Data\Out-filter\out_filter.cpp(155) : error C2227: left of '->SetFormat' must point to class/struct/union


Hoe moet het dan wel?
interf moet geen LPVOID zijn, maar een LPDIRECTSOUNDBUFFER. Het wordt dan iets van :
code:
1
2
3
4
LPDIRECTSOUNDBUFFER interf = NULL;
priBuf->QueryInterface(IID_IDirectSoundBuffer, (VOID**)&interf);

interf->SetFormat(&waveFormat);

geen idee of het zo zal werken, maar dat mag jij zelf ff testen ( ik heb hier jouw code niet, vandaar).

Eigenlijk gaat het erom dat je niet kan verwachten dat de compiler van een LPVOID een class kan maken, er moet het eea gecast worden.

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03-09 13:30

.oisyn

Moderator Devschuur®

Demotivational Speaker

overigens hoef je die hele QueryInterface niet aan te roepen. Die heb je pas nodig als je van een IDirectSoundBuffer een IDirectSoundBuffer8 wilt maken

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Nikel
  • Registratie: Juli 2000
  • Niet online
Neen, ik krijg nu weer dat setformat een DSERR_INVALIDCALL teruggeeft.

  • Nikel
  • Registratie: Juli 2000
  • Niet online
Nu snap ik er niets meer van. Die setformat mag je toch alleen uitvoeren op de interface zelf?

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03-09 13:30

.oisyn

Moderator Devschuur®

Demotivational Speaker

misschien kijken we in de verkeerde hoek...
wat zijn de waarden voor numchannels, samplerate en bitspersamp? (hoewel je dan een BADFORMAT error hoort te krijgen)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Nikel
  • Registratie: Juli 2000
  • Niet online
Die waarden rollen zo uit winamp, en in een andere winamp plugin waar ik de source van heb gaat het net zo. Maar sowieso, als die waarden fout staan moet er bij het creeren vand e buffer een fout optreden en dat gebeurt dus niet.

Verwijderd

tja, nu ik je code wat beter bekijk, denk ik dat je te moeilijk bezig bent. Kun je het gebruik van DirectSoundBuffer8 niet gewoon vermijden ( en dus ook QueryInterface)?

  • Nikel
  • Registratie: Juli 2000
  • Niet online
Ik wil in ieder geval een primaire buffer gebruiken. Ik zou niet weten hoe ik dat anders moet doen

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03-09 13:30

.oisyn

Moderator Devschuur®

Demotivational Speaker

maar waarom wil je per se een primary buffer creeeren? gewoon secondary buffers werken ook prima (plus windows kan de geluiden van andere applicaties dan gewoon erdoorheen mixen)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Nikel
  • Registratie: Juli 2000
  • Niet online
Op zondag 26 mei 2002 21:48 schreef .oisyn het volgende:
maar waarom wil je per se een primary buffer creeeren? gewoon secondary buffers werken ook prima (plus windows kan de geluiden van andere applicaties dan gewoon erdoorheen mixen)
Ik wil dus niet dat windows er geluiden doorheen gaat mengen.

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03-09 13:30

.oisyn

Moderator Devschuur®

Demotivational Speaker

dan zet je een EXCLUSIVE priority :)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Verwijderd

ik zie in je stukje code het volgende:
code:
1
priBufSet.dwFlags = DSBCAPS_GLOBALFOCUS;

probeer eens :
code:
1
priBufSet.dwFlags = DSBCAPS_PRIMARYBUFFER;

maar er moet denk ik nog meer gebeuren, dus dit zal het probleem nog niet oplossen.

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03-09 13:30

.oisyn

Moderator Devschuur®

Demotivational Speaker

heh idd, dat was me nog niet eens opgevallen.

je kunt die flags trouwens natuurlijk ook or'en met DSBCAPS_GLOBALFOCUS

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Nikel
  • Registratie: Juli 2000
  • Niet online
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
int open(int samplerate, int numchannels, int bitspersamp, int bufferlenms, int prebufferms)
{
    w_offset = writtentime = 0;
    numchan = numchannels;
    srate = samplerate;
    bps = bitspersamp;
    
    WAVEFORMATEX waveFormat;
    DSBUFFERDESC priBufSet;
    
    
    ZeroMemory(&waveFormat, sizeof(waveFormat));

    waveFormat.wFormatTag = WAVE_FORMAT_PCM;
    waveFormat.nChannels = (WORD)numchannels;
    waveFormat.nSamplesPerSec = (DWORD)samplerate;
    waveFormat.nAvgBytesPerSec = (DWORD)(samplerate * bitspersamp * numchannels / 8);
    waveFormat.nBlockAlign = (WORD)(bitspersamp * numchannels / 8);
    waveFormat.wBitsPerSample = (WORD)bitspersamp;
    
    ZeroMemory(&priBufSet, sizeof(priBufSet));

    priBufSet.dwSize = sizeof(DSBUFFERDESC);
    priBufSet.dwFlags = DSBCAPS_PRIMARYBUFFER;
    priBufSet.dwBufferBytes = 0;
    priBufSet.lpwfxFormat = NULL;

    
    HRESULT temp2;
    HRESULT temp;



    if (DirectSoundCreate(NULL, &soundcard, NULL) == DS_OK) //create direct sound object
    {
      //ok, DirectSound Object created, let's take control now...
      if (soundcard->SetCooperativeLevel(out.hMainWindow, DSSCL_WRITEPRIMARY) == DS_OK)
      {
            
            if (soundcard->CreateSoundBuffer(&priBufSet, &priBuf, NULL) == DSERR_INVALIDPARAM)
            {
                MessageBox(out.hMainWindow, "createsoundbuffer mislukt!", "mooizo!", MB_OK);
                return -1;
            }

Die onderste messagebox krijg ik nu weer te zien. Dus er is iets mis met de parameters die ik naar createsoundbuffer stuur, dat zal dus zijn dat er iets mis is met priBufSet, maar volgens mij doe ik het nu netjes volgens de manual.

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03-09 13:30

.oisyn

Moderator Devschuur®

Demotivational Speaker

je hebt priBufSet.dwBufferBytes op 0 gezet

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Nikel
  • Registratie: Juli 2000
  • Niet online
Klopt dat moet ook volgens de manual. Zal het even opzoeken.

dwBufferBytes

Size of the new buffer, in bytes. This value must be zero when creating a buffer with the DSBCAPS_PRIMARYBUFFER flag. For secondary buffers, the minimum and maximum sizes allowed are specified by DSBSIZE_MIN and DSBSIZE_MAX, defined in Dsound.h.

Verwijderd

weet je ook of je hardware het scrijven naar de primary buffer ondersteund? Ik heb in mijn Visual Studio documentatie een artikel genaamd 'Writing to the Primary Buffer' gevonden. Mocht je het niet kennen, dan zou je het kunnen lezen -> http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dx8_c/hh/dx8_c/audio_advanced_7lin.asp
(daar hebben ze het weer over IDirectSound8 ed., maar mischien dat je die 8 ook daar kunt weghalen )
Pagina: 1