2011-11-16 7 views
10

Sviluppando un'applicazione iOS che utilizza il framework CoreAudio, mi sto occupando del comportamento assurdo IMHO del registro SDL. riproduzione audio. SDL riproduce l'audio in loop e l'unico modo per attivare la riproduzione è chiamare lo SDL_PauseAudio(0) e l'unico modo per fermarlo (senza altri effetti collaterali, di cui non parlerò qui) è chiamare lo SDL_PauseAudio(1). Per quanto ne so.SDL: come interrompere l'audio - non riprendere, quale SDL_PauseAudio (1) ha effettivamente?

Qual è il problema per me in SDL qui? Semplicemente - la prossima chiamata allo SDL_PauseAudio(1) in realtà RIPRENDE la riproduzione, facendo sì che il framework suoni qualche mess * prima di richiedere nuovi dati audio *. Questo è dovuto al modo in cui SDL_CoreAudio.c implementa il ciclo di riproduzione.

Significa che SDL non implementa STOP, implementa solo PAUSA/RIPRENDI e gestisce erroneamente l'elaborazione audio. Significa che, se suoni sampleA e vuoi suonare sampleB in seguito, sentirai anche frammenti di sampleA mentre ti aspetti di sentire solo la riproduzione di sampleB.

Se ho torto, per favore correggimi.

Se no, ecco il mio diff, che ho usato per implementare anche ARRESTO comportamento: non appena ho finito di giocare sampleA, che io chiamo SDL_PauseAudio(2) così quel ciclo di riproduzione si chiude e successiva chiamata a SDL_PauseAudio (0) inizia di nuovo, questa volta giocando senza problemi da sampleA, ma riproducendo correttamente solo i dati da smapleB.

Index: src/audio/coreaudio/SDL_coreaudio.c 
=================================================================== 
--- src/audio/coreaudio/SDL_coreaudio.c 
+++ src/audio/coreaudio/SDL_coreaudio.c 
@@ -250,6 +250,12 @@ 
      abuf = &ioData->mBuffers[i]; 
      SDL_memset(abuf->mData, this->spec.silence, abuf->mDataByteSize); 
     } 
+  if (2 == this->paused) 
+  { 
+   // this changes 'pause' behavior to 'stop' behavior - next 
+   // plyaing starts from beginning, i.e. it won't resume 
+   this->hidden->bufferOffset = this->hidden->bufferSize; 
+  } 
     return 0; 
    } 

mi vergogno che ho modificato il codice SDL, ma non ho alcun collegamento con gli autori e non hanno trovato alcun aiuto in giro. Beh, è ​​strano per me che nessuno sembra aver bisogno del comportamento STOP in SDL?

risposta

0

Un modo per aggirare il problema è, ad esempio, una migliore gestione del dispositivo audio con SDL. Ecco cosa suggerisco:

void myAudioCallback(void *userdata, Uint8 *stream, int len) { ... } 
SDL_AudioDeviceID audioDevice; 

void startAudio() 
{ 
    // prepare the device 
    static SDL_AudioSpec audioSpec; 
    SDL_zero(audioSpec); 
    audioSpec.channels = 2; 
    audioSpec.freq  = 44100; 
    audioSpec.format = AUDIO_S16SYS; 
    audioSpec.userdata = (void*)myDataLocation; 
    audioSpec.callback = myAudioCallback; 
    audioDevice = SDL_OpenAudioDevice(NULL, 0, &audioSpec, &audioSpec, 0); 
    // actually start playback 
    SDL_PauseAudioDevice(audioDevice, 0); 
} 

void stopAudio() 
{ 
    SDL_CloseAudioDevice(audioDevice); 
} 

Questo funziona per me, la richiamata non è chiamato dopo stopAudio() e senza spazzatura viene inviato al diffusore sia.