2011-11-16 6 views
10

Desarrollando una aplicación de iOS que utiliza CoreAudio framework, estoy lidiando con el comportamiento sin sentido de la RHO en el registro SDL. reproduciendo audio. SDL reproduce audio en bucle, y la única manera de activar la reproducción es llamar al SDL_PauseAudio(0), y la única forma de detenerlo (sin otros efectos secundarios, de los que no hablaré aquí) es llamar al SDL_PauseAudio(1). Por lo que sé.SDL: cómo detener el audio - no reanudar, ¿qué SDL_PauseAudio (1) realmente hace?

¿Cuál es el problema para mí en SDL aquí? Simplemente: la próxima llamada al SDL_PauseAudio(1) en realidad REANUDA la reproducción, haciendo que el marco juegue un poco lío * antes de solicitar nuevo datos de sonido *. Esto se debe a la forma en que SDL_CoreAudio.c implementa el ciclo de reproducción.

Esto significa, que SDL no implementa PARADA, implementa simplemente una pausa/reanudar e incorrectamente maneja el procesamiento de audio. Significa, que si reproduce sampleA, y desea reproducir sampleB más tarde, también escuchará fragmentos de sampleA mientras espera oír la reproducción de sampleB.

Si estoy equivocado, por favor corríjanme.

Si no, aquí está mi diff, que también implementé STOP: tan pronto como termine de reproducir sampleA, llamo al SDL_PauseAudio(2) para que el loop de reproducción se cierre y la próxima llamada a SDL_PauseAudio (0) lo inicie de nuevo, esta vez jugando no mess de sampleA, pero reproduciendo correctamente solo datos de 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; 
    } 

estoy avergonzado de que he editado código SDL, pero no tengo ninguna conexión con autores y no he encontrado ninguna ayuda en todo. Bueno, es extraño para mí, que nadie parece necesitar un comportamiento STOP en SDL.

Respuesta

0

Una forma de solucionar su problema es, por ejemplo, administrar mejor su dispositivo de audio con SDL. Aquí es lo que sugieren:

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); 
} 

Esto funciona para mí, la devolución de llamada no se llama después de stopAudio() y no hay basura se envía al altavoz tampoco.

Cuestiones relacionadas