Toon posts:

[C++/audio] waveOutUnprepareHeader problemen

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

Verwijderd

Topicstarter
Ik heb een programma dat over twee streams mono ADPCM data ontvangt, die mengt tot een stereo ADPCM signaal, en die via waveOut afspeelt (zodat de twee mono streams over twee afzonderlijke luidsprekers te horen zijn). Het werkt, en da's mooi. Maar wat niet zo mooi is, is dat hij zichzelf af en toe ophangt.

Ik ben er al achter dat het in de callback zit: die doet een call naar waveOutUnprepareHeader (helemaal volgens het boekje), maar waveOutUnprepareHeader komt vervolgens niet meer terug. Het lullige is dat hij vast zit in een windows dll (NTDLL om precies te zijn), dus ik kan niet zien wat er mis gaat. De call stack is als volgt:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
NTDLL! 7c90eb94()
NTDLL! 7c90104b()
WINMM! 76b45831()
VoiceMixer::dataDone(wavehdr_tag * 0x00a5f4d0) line 1382 + 19 bytes
VoicePlayer::dataDone(wavehdr_tag * 0x00a5f4d0, unsigned int 0x00000000) line 409
VoiceMixer::waveCallBack(HWAVEOUT__ * 0x0015efc8, unsigned int 0x000003bd, unsigned long 0x00000000, unsigned long 0x00a5f4d0, unsigned long 0x00000000) line 1441
WINMM! 76b454f3()
MSACM32! 72d114e4()
WINMM! 76b454f3()
WDMAUD! 72d21da2()
WDMAUD! 72d2230c()
WDMAUD! 72d24617()
KERNEL32! 7c80b50b()


De wave header (op adres 0x00a5f4d0) die ik wil unpreparen is correct, dus daar ligt het niet aan. Ik heb geen idee wat er mis is, misschien heeft iemand een hint?

Vervolgens: ik heb het ook geprobeerd door waveOutUnprepareHeader gewoon over te slaan, en meteen een "delete[]" te doen op het audio data block en een "delete" op de wave header. Dat lijkt geen problemen op te leveren (misschien op de lange duur?) vandaar mijn vraag: wat doet waveOutUnprepareHeader nou precies? Verder dan "de rommel opruimen" kom ik niet met de informatie die ik op het web vind. Kan iemand dit nader preciseren?

P.S. Oeps, ik zie dat de titel van dit topic nog niet volledig is. Geen idee hoe ik dat alsnog kan aanpassen. Misscien dat een mod er nog iets van kan maken? ("waveOutUnprepareHeader problemen" of zo iets...).

[ Voor 5% gewijzigd door Verwijderd op 05-09-2006 10:08 . Reden: onvolledige titel ]


  • RobLemmens
  • Registratie: Juni 2003
  • Laatst online: 10-02 16:09
Op de vraag wat waveOutUnprepareHeader doet kan ik je wel antwoord geven:

Onder windows XP helemaal niets.
Onder win 3.1 (volgens mij ook win9x) doet waveOutPrepareHeader een globallock plaatsen op het geheugen en met de unprepare haal je hem weer eraf.

Toch moet je hem gebruiken op de juiste plaatsen want het kan zijn dat ie ooit nog iets gaat doen.


edit: Je mag trouwens nooit in een callback wavexxx functies aanroepen -> dan blijft het zaakje inderdaad hangen.

[ Voor 14% gewijzigd door RobLemmens op 05-09-2006 11:05 ]


Verwijderd

Topicstarter
RobLemmens schreef op dinsdag 05 september 2006 @ 11:03:
Op de vraag wat waveOutUnprepareHeader doet kan ik je wel antwoord geven:

Onder windows XP helemaal niets.
Dat lijkt me stug. Waarom gaat hij dan drie levels diep Windows in (zie de call stack in mijn eerste posting)? Dan zou hij toch net zo goed rechtstreeks een "return" kunnen doen? En waarom hangt hij dan als hij niets doet? Want het is echt waveOutUnprepareHeader (of nog iets daaronder) die hangt....

  • RobLemmens
  • Registratie: Juni 2003
  • Laatst online: 10-02 16:09
Verwijderd schreef op dinsdag 05 september 2006 @ 11:07:
[...]


Dat lijkt me stug. Waarom gaat hij dan drie levels diep Windows in (zie de call stack in mijn eerste posting)? Dan zou hij toch net zo goed rechtstreeks een "return" kunnen doen? En waarom hangt hij dan als hij niets doet? Want het is echt waveOutUnprepareHeader (of nog iets daaronder) die hangt....
Hij hangt omdat je een wavexxx functie aanroept vanuit een callback die uit de wavexxx zone komt.

En waveoutunprepare doet echt niets onder xp, zie msdn blog in het commentaar van larry.

Verwijderd

Topicstarter
RobLemmens schreef op dinsdag 05 september 2006 @ 11:13:
Hij hangt omdat je een wavexxx functie aanroept vanuit een callback die uit de wavexxx zone komt.

En waveoutunprepare doet echt niets onder xp, zie msdn blog in het commentaar van larry.
Okay, ik zie dat Larry dat zegt, maar dat verklaart nog steeds niet waarom die call drie levels diep Windows in duikt.

En dan je andere punt: als ik geen wavexxx functies mag aanroepen in mijn callback, hoe kan ik dan de gealloceerde buffers weer vrijgeven? Het enige wat me zo te binnen wil schieten is de adressen in een queue plaatsen en die queue periodiek doorlopen. Maar dat lijkt me een gruwelijk lelijke oplossing. Waarvoor is die callback uberhaupt als je hem niet kunt gebruiken om de gealloceerde buffers vrij te geven? Daar is het WOM_DONE event toch juist voor bedoeld?

Edit: zie ook hier: http://www.pocketpcdn.com/articles/pocketpcaudio.html (gaat weliswaaar over PocketPC, maar toch...) Daar staat letterlijk: "Handle the clean-up at the point where you receive the WOM_DONE heads up." En je krijgt WOM_DONE in de callback, dus volgens dat artikel is dat ook de plaats waar je het kunt (of moet) afhandelen. Overigens had ik de implementatie al gemaakt voordat ik dat artikel had gelezen, op basis van andere informatie, en die zei ook dat je WOM_DONE moet gebruiken als seintje om de cleanup actie uit te voeren.

[ Voor 22% gewijzigd door Verwijderd op 05-09-2006 11:25 . Reden: aanvulling ]


  • RobLemmens
  • Registratie: Juni 2003
  • Laatst online: 10-02 16:09
Ik heb hier in het verleden veel mee gewerkt en ik deed op wom_done een event triggeren om zo later de juiste code aan te roepen.

Uit msdn:

Remarks
Applications should not call any system-defined functions from inside a callback function, except for EnterCriticalSection, LeaveCriticalSection, OutputDebugString, PostMessage, PostThreadMessage, and SetEvent. Calling other wave functions will cause deadlock.

edit:

De schrijver van dat artikel gaat hier mooi langs door in zen voorbeeld code (playwave.cpp) de flags te pollen op de waveheader voor WOM_DONE en door te wachten op het stop event, hij gebruikt het callback mechanisme niet eens maar het event based model.

[ Voor 80% gewijzigd door RobLemmens op 05-09-2006 11:49 ]


Verwijderd

Topicstarter
Ik was inmiddels ook zover dat ik een callback event had geimplementeerd i.p.v. een callback functie, en nu hangt hij zichzelf niet meer op...

Rob, bedankt!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 13-02 18:54

.oisyn

Moderator Devschuur®

Demotivational Speaker

misschien ten overvloede, maar:
Verwijderd schreef op dinsdag 05 september 2006 @ 10:05:
Ik ben er al achter dat het in de callback zit: die doet een call naar waveOutUnprepareHeader (helemaal volgens het boekje), maar waveOutUnprepareHeader komt vervolgens niet meer terug. Het lullige is dat hij vast zit in een windows dll (NTDLL om precies te zijn), dus ik kan niet zien wat er mis gaat.
NT Symbol server instellen. Ga naar de properties van je solution, dan Debug Symbols, en voeg dan deze string toe aan de te zoeken symbol paths:
code:
1
srv*c:\cache*http://msdl.microsoft.com/download/symbols

Dan heb je iig al een duidelijkere callstack en kun je wellicht beter zien wat er precies mis gaat (waarschijnlijk zie je een WaitForSingleObjectEx oid in de callstack, wat duidt op een deadlock).

[ Voor 10% gewijzigd door .oisyn op 05-09-2006 17:22 ]

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.

Pagina: 1