|
(A5) random crash on al_detach_voice() |
thebignic
Member #14,419
July 2012
|
Using Allegro 5.0.5 running on Win XP, Directx9.0c I'm encountering an intermittent lockup when cleaning up audio. Under Win7, I haven't encountered the bug at all. If I destroy the mixer before destroying my voice, sometimes the program will lock at al_destroy_mixer. If I destroy the voice first, it will hang on al_detach_voice(voice). Once in a while it will get passed al_destroy_voice, al_destroy_mixer() and then hang on al_uninstall_audio(). This may be a huge assumption, but will al_destroy_mixer detach any attached voices before it is cleaned up? Will al_uninstall_audio() also attempt to do the same thing? WHAT IS THE PROPER ORDER? When I say intermittent, I mean sometimes it will run/exit fine 20 times in a row (just loading main screen, exiting) and then randomly crash. Only thing I can do to reproduce it is to keep running/exiting until it happens. Code:blocks debugger doesnt appear to even catch that the app is hung up? 1
2 audio cleanup routine
3 ...
4
5
6
7 al_stop_samples();
8
9
10 if (stream) {
11 std::cout << "destroying stream...\n";
12
13 al_set_audio_stream_playing(stream, false);
14 al_unregister_event_source(event_queue, al_get_audio_stream_event_source(stream));
15
16
17 al_detach_audio_stream(stream);
18 al_destroy_audio_stream(stream);
19 }
20 if (menuStream) {
21 std::cout << "destroying menuStream...\n";
22
23 al_set_audio_stream_playing(menuStream, false);
24 al_unregister_event_source(event_queue, al_get_audio_stream_event_source(menuStream));
25
26 al_detach_audio_stream(menuStream);
27 al_destroy_audio_stream(menuStream);
28 }
29
30 if (mixer) {
31 std::cout << "al_destroy_mixer...\n";
32 al_destroy_mixer(mixer);
33 }
34
35 if (voice) {
36 std::cout << "al_set_voice_playing(voice, false)...\n";
37 al_set_voice_playing(voice, false);
38 std::cout << "al_detach_voice(voice);...\n";
39 al_detach_voice(voice);
40 std::cout << "al_destroy_voice(voice);...\n";
41 al_destroy_voice(voice);
42 }
43
44
45
46 if (al_is_audio_installed) {
47 std::cout << "al_uninstall_audio...\n";
48 al_uninstall_audio();
49 }
I can't really post complete code due to the size of the project and the resources involved. Just wanted to know if anyone else has had intermittent issues with cleaning up audio, and if so, what might I be doing wrong? In that code, I am setting the streams to stop regardless of their state since if al_get_audio_stream_playing(stream) was returning false even though the stream WAS playing. Curious... I generally don't post threads, preferring to smash my head against the wall and look at other forum posts until I've fixed the issue but I've searched high and low for similar issues and of the two threads I've seen, both seem to be unanswered. Help me Obi Wan Allegro.cc... you're my only hope! Edit: Debug did catch a crash finally... #0 00000000 0x00448574 in _dsound_stop_voice() (??:??) EDIT - Updated Code: I can't see anything in allegro.log that appears to be of relevance... 1
2 if (stream) {
3 std::cout << "destroying stream...\n";
4 al_drain_audio_stream(stream);
5 al_set_audio_stream_playing(stream, false);
6 al_unregister_event_source(event_queue, al_get_audio_stream_event_source(stream));
7
8
9 if (al_get_audio_stream_attached(stream)) { al_detach_audio_stream(stream); }
10 al_destroy_audio_stream(stream);
11 }
12
13 if (menuStream) {
14 std::cout << "destroying menuStream...\n";
15
16 al_drain_audio_stream(menuStream);
17
18 al_set_audio_stream_playing(menuStream, false);
19 al_unregister_event_source(event_queue, al_get_audio_stream_event_source(menuStream));
20
21
22 if (al_get_audio_stream_attached(menuStream)) { al_detach_audio_stream(menuStream); }
23 al_destroy_audio_stream(menuStream);
24 }
25
26 //#ifndef BYPASS_MIXER
27 if (mixer) {
28
29 if (al_get_mixer_attached(mixer)) {
30 std::cout << "al_detach_mixer...\n";
31 al_detach_mixer(mixer);
32 }
33
34 std::cout << "al_destroy_mixer...\n";
35 al_destroy_mixer(mixer);
36 }
37 //#endif
38
39 if (voice) {
40 std::cout << "al_detach_voice(voice);...\n";
41 al_detach_voice(voice);
42 std::cout << "al_destroy_voice(voice);...\n";
43 al_destroy_voice(voice);
44 }
45
46
47 if (al_is_audio_installed) {
48 std::cout << "al_uninstall_audio...\n";
49 al_uninstall_audio();
50 }
Tearing my hair out of my skull now... Why is it so random? Why do I have to run it 20-30 times before it'll happen? Then sometimes it'll happen as soon as I build and run once....
|
SiegeLord
Member #7,827
October 2006
|
Could you try running this with a) 5.0.7 and b) with debug symbols turned on (so we see the lines in the backtrace)? Anyway, the order you're doing things seems to be right, as this is the order Allegro uses for its default mixer: al_destroy_mixer(allegro_mixer); al_destroy_voice(allegro_voice);
"For in much wisdom is much grief: and he that increases knowledge increases sorrow."-Ecclesiastes 1:18 |
thebignic
Member #14,419
July 2012
|
Linking to 5.0.7 now... Same issue. #0 0045002C _dsound_stop_voice(voice=0x1b130c0) (D:\Libraries\build\allegro\src\allegro-5.0.x\allegro-5.0.x\addons\audio\dsound.cpp:460) From dsound.cpp... 437/* The stop_voice method should stop playback. For non-streaming voices, it
438 should leave the data loaded, and reset the voice position to 0. */
439static int _dsound_stop_voice(ALLEGRO_VOICE* voice)
440{
441 ALLEGRO_DS_DATA *ex_data = (ALLEGRO_DS_DATA *)voice->extra;
442
443 if (!ex_data->ds8_buffer) {
444 ALLEGRO_ERROR("Trying to stop empty voice buffer\n");
445 return 1;
446 }
447
448 /* if playing a sample */
449 if (!voice->is_streaming) {
450 ex_data->ds8_buffer->Stop();
451 return 0;
452 }
453
454 if (ex_data->stop_voice == 0) {
455 ex_data->stop_voice = 1;
456 al_join_thread(ex_data->thread, NULL);
457 al_destroy_thread(ex_data->thread);
458 }
459
460 ex_data->ds8_buffer->Release();
461 ex_data->ds8_buffer = NULL;
462
463 return 0;
464}
Also in dsound.cpp... Not sure if/when this is called (perhaps completely unrelated) Is the buffer intentionally not NULLed? Shouldnt it be? 375/* The unload_voice method unloads a sample previously loaded with load_voice.
376 This method should not be called on a streaming voice. */
377static void _dsound_unload_voice(ALLEGRO_VOICE *voice)
378{
379 ALLEGRO_DS_DATA *ex_data = (ALLEGRO_DS_DATA *)voice->extra;
380 ex_data->ds8_buffer->Release();
381}
|
SiegeLord
Member #7,827
October 2006
|
Where do you get your voice/mixer from? It's not the allegro's default voice/mixer by any chance, is it? "For in much wisdom is much grief: and he that increases knowledge increases sorrow."-Ecclesiastes 1:18 |
thebignic
Member #14,419
July 2012
|
Not sure what the "default mixer" would be? This is the initial setup 1 if(!al_install_audio()){
2 fprintf(stderr, "failed to initialize audio!\n");
3 return -1;
4 }
5
6std::cout << " initialized audio\n";
7
8 if(!al_init_acodec_addon()){
9 fprintf(stderr, "failed to initialize audio codecs!\n");
10 return -1;
11 }
12
13std::cout << " initialized al_init_acodec_addon()\n";
14
15
16 if (!al_reserve_samples(16)){
17 fprintf(stderr, "failed to reserve samples!\n");
18 return -1;
19 }
20
21 voice = al_create_voice(44100, ALLEGRO_AUDIO_DEPTH_INT16, ALLEGRO_CHANNEL_CONF_2);
22 if (!voice) {
23 fprintf(stderr, "Could not create ALLEGRO_VOICE.\n");
24 return -1;
25 }
26
27 mixer = al_create_mixer(44100, ALLEGRO_AUDIO_DEPTH_FLOAT32, ALLEGRO_CHANNEL_CONF_2);
28 if (!mixer) {
29 fprintf(stderr, "Could not create ALLEGRO_MIXER.\n");
30 return 1;
31 }
32
33 if (!al_attach_mixer_to_voice(mixer, voice)) {
34 fprintf(stderr, "al_attach_mixer_to_voice failed.\n");
35 return 1;
36 }
37
38
39 initialized=true;
|
Elias
Member #358
May 2000
|
al_reserve_samples already will create a voice and mixer for you (and attach it), so you don't need the last three calls at all. It still sounds like there is a bug in Allegro as creating a second voice is supposed to work. But a quick fix is likely to either not call al_reserve_samples (and don't use al_play_sample) or don't create a second voice. -- |
thebignic
Member #14,419
July 2012
|
Remarked out all the voice and mixer code, and attached my streams to the default mixer via al_get_default_mixer(). Seemed to work for a while (about thirty runs) but crashed again, this time on al_uninstall_audio(); Still crashed on the same line though.... #0 0044ED30 _dsound_stop_voice(voice=0x1b13868) (D:\Libraries\build\allegro\src\allegro-5.0.x\allegro-5.0.x\addons\audio\dsound.cpp:460) I have the most recent audio drivers for the chipset. Allegro.log doesn't appear to have any relevant information and I find that somewhat curious. Perhaps I should note that the crash seems to occur even if I hadn't actually played any samples or streams yet.
|
SiegeLord
Member #7,827
October 2006
|
Does this happen with the Allegro examples, like ex_audio_simple? I tried the examples on WinXP and they never crashed for me. "For in much wisdom is much grief: and he that increases knowledge increases sorrow."-Ecclesiastes 1:18 |
|