Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

14.10.2005, 23:14

soundbuffer

hallo!

ich habe mehrere soundbuffer die ich nacheinander abspielen will.

momentan hab verwende ich diese lösung:

g_pSounds[0]->Play(0, 0, 0);
g_pSounds[0]->GetStatus(&dwStatus);
while ((dwStatus & DSBSTATUS_PLAYING)) g_pSounds[0]->GetStatus(&dwStatus);

g_pSounds[1]->Play(0, 0, 0);
g_pSounds[1]->GetStatus(&dwStatus);
while ((dwStatus & DSBSTATUS_PLAYING)) g_pSounds[1]->GetStatus(&dwStatus);
....

es funktioiert zwar, ich halte es aber für wenig elegant und sogar problematisch weil das programm für die zeit die es braucht um einen buffer abzuspielen in der while schleife festhängt.

kann mir jemand eine andere lösung zeigen?

merci, dave

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

2

14.10.2005, 23:57

1. Du könntest diese Aufrufe in einen separaten Thread packen.
Siehe Platform-SDK-Dokumenation: "CreateThread"

2. Du kannst Dich von DirectSound benachrichten lassen, wenn ein Soundbuffer an einer bestimmten Stelle angelangt ist (in Deinem Fall: wenn er am Ende angelangt ist).
Siehe DirectX-SDK-Dokumentation: "Play Buffer Notification"

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

3

15.10.2005, 12:52

Die Schleife verbraucht in dieser Form 100% der CPU-Leistung. Das ist ein Nachteil. Am besten wäre es, die Event-Notification anzufordern (ein Event wird signalisiert, wenn der Soundbuffer am Ende angelangt ist). In dem Thread wartest Du dann mit WaitForSingleObject auf das Event. Solange es nicht signalisiert wird, verbraucht der Thread dann keine CPU-Leistung, da Windows ihn erst dann wieder aktiviert, wenn das Event signalisiert wurde.
Wenn man es trotzdem mit einer Schleife machen will, dann wäre es so besser:

C-/C++-Quelltext

1
2
3
4
5
6
7
g_pSounds[0]->Play(0, 0, 0);
g_pSounds[0]->GetStatus(&dwStatus);
while ((dwStatus & DSBSTATUS_PLAYING))
{
    Sleep(0);
    g_pSounds[0]->GetStatus(&dwStatus);
}


Durch das "Sleep(0)" gibt der Thread frühzeitig sein "Zeitfenster" an den nächsten Thread ab.
Beim Multi-Tasking wird ja die CPU abwechselnd den verschiedenen Prozessen/Threads zugeteilt. Die laufen also nicht wirklich gleichzeitig, sondern immer nur in kurzen Abständen stückchenweise. Wenn der Sound-Thread jetzt seine volle zugeteilte Zeit nutzen würde, nur um in einer blöden while-Schleife festzustecken, wäre das sehr schlecht für die Performance.

Anonymous

unregistriert

4

20.10.2005, 19:47

danke für die ausfühliche Hilfe.
hat noch jemand ein codestück als bsp zu Play Buffer Notification bei der hand?

5

20.10.2005, 20:17

-> siehe directsound tutorials

6

07.11.2005, 02:45

hi!

ich hab mich in der directx msdn umgeschaut und folgendes zusammengetragen:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
LPDIRECTSOUNDNOTIFY8 lpDsNotify; 
DSBPOSITIONNOTIFY PositionNotify;
HANDLE hStop[2];
DWORD tmp;

for (int idx=0;idx<2;idx++) {

  hStop[idx] = (HANDLE)CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)threadRout,(void *)this,0,&tmp);

  if (SUCCEEDED(hr = pSounds[idx]->QueryInterface(IID_IDirectSoundNotify8, (LPVOID*)&lpDsNotify))) 
  { 
     PositionNotify.dwOffset = DSBPN_OFFSETSTOP;
     PositionNotify.hEventNotify = hStop;
     hr = lpDsNotify->SetNotificationPositions(1, &PositionNotify);
     lpDsNotify->Release();
  }

}

pSounds[0]->Play(0, 0, 0);


in threadRout erfolgt dann abwechseln pSounds[idx]->Play(0, 0, 0); (idx = 0 oder 1);

die pSounds sind korrekt initaialisiert, und pSounds[0]->Play(0, 0, 0); bzw pSounds[0]->Play(0, 0, 0); liefern auch das gewünschte ergebnis.

das programm springt aber nur zu Beginn zweimal in threadRout, und nicht wie gewünscht nach ende von pSounds[0] bzw. pSounds[0].

kann mir da jemand weiterhelfen?

Nox

Supermoderator

Beiträge: 5 272

Beruf: Student

  • Private Nachricht senden

7

08.11.2005, 20:10

Du erstellst die Threads die laufen ihr Programm ab und beenden sich dann. Was willst du denn genau machen?
PRO Lernkurs "Wie benutze ich eine Doku richtig"!
CONTRA lasst mal die anderen machen!
networklibbenc - Netzwerklibs im Vergleich | syncsys - Netzwerk lib (MMO-ready) | Schleichfahrt Remake | Firegalaxy | Sammelsurium rund um FPGA&Co.

8

08.11.2005, 22:49

also eigentlich will ich zwei verschiedene soundbuffer abwechselnd abspielen. dazu hab ich ein array von sb.

eine lösung hab ich schon, ein thread der sb[playingbuffer]->getStatus macht und den nächsten abspielt wenn der eine stoppt.
funktioniert zwar, is aber nicht sehr aufregend.

deshalb will ich buffer notifikations verwenden.

in der msdn finde ich dazu leider nichts, und DSBPOSITIONNOTIFY + c++ im google bringt mich auch nicht weiter.

das ich keinen thread-handle übergeben darf hab ich mitlerweile auch schon herausgefunden. dachte zuerst die würden dann automatisch gestartet.

hilfe erbeten, dave

Nox

Supermoderator

Beiträge: 5 272

Beruf: Student

  • Private Nachricht senden

9

08.11.2005, 22:58

Aus der DX DOKU unter dem Begriff "Play Buffer Notification"

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
HRESULT SetStopNotification(HANDLE hMyEvent, 
        LPDIRECTSOUNDBUFFER8 lpDsbSecondary)
{
  LPDIRECTSOUNDNOTIFY8 lpDsNotify; 
  DSBPOSITIONNOTIFY PositionNotify;
  HRESULT hr;

  if (SUCCEEDED(
      hr = lpDsbSecondary->QueryInterface(IID_IDirectSoundNotify8,
             (LPVOID*)&lpDsNotify))) 
  { 
    PositionNotify.dwOffset = DSBPN_OFFSETSTOP;
    PositionNotify.hEventNotify = hMyEvent;
    hr = lpDsNotify->SetNotificationPositions(1, &PositionNotify);
    lpDsNotify->Release();
  }
  return hr;
}
PRO Lernkurs "Wie benutze ich eine Doku richtig"!
CONTRA lasst mal die anderen machen!
networklibbenc - Netzwerklibs im Vergleich | syncsys - Netzwerk lib (MMO-ready) | Schleichfahrt Remake | Firegalaxy | Sammelsurium rund um FPGA&Co.

Anonymous

unregistriert

10

08.11.2005, 23:10

ja, wenn du ein stückchen weiter oben schaust hab ich fast den selben code gepostet.
das ist nicht das problem. das ich in der BufferDesc dwFlags auf DSBCAPS_CTRLPOSITIONNOTIFY setzten muß hab ich inzwischen auch geschnallt.
was ich nicht hab ist der handle PositionNotify.hEventNotify = hStop;
und vor allem wie werde ich dann benachrichtigt?

Werbeanzeige