SDL:如何停止音频 - 不恢复,SDL_PauseAudio(1)实际上做了什么?

lef*_*lef 11 c sdl core-audio playback

开发使用CoreAudio框架的iOS应用程序,我正在处理SDL reg的IMHO废话行为.播放音频.SDL循环播放音频,只有如何触发播放的方式是调用SDL_PauseAudio(0),而如何停止它的唯一方法(没有其他副作用,这里我不会谈到)是调用SDL_PauseAudio(1).我所知道的.

SDL在这里有什么问题?简单 - 下一次调用SDL_PauseAudio(1)实际上恢复播放,导致框架在要求新的声音数据*之前播放一些混乱*.这是因为SDL_CoreAudio.c实现回放循环的方式.

这意味着,SDL不实现STOP,它只实现PAUSE/RESUME并错误地管理音频处理.这意味着,如果您播放sampleA,并希望稍后播放sampleB,您将听到sampleA的片段,同时期望只听到sampleB的播放.

如果我错了,请纠正我.

如果不是,这是我的差异,是我用来实现也将停止行为:只要我完成播放sampleA,我打电话SDL_PauseAudio(2)让循环播放退出并SDL_PauseAudio下一个电话(0)打再次启动,这一次没搞成从sampleA,但正确播放来自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;
     }
Run Code Online (Sandbox Code Playgroud)

我感到很惭愧,我编辑了SDL代码,但我与作者没有关系,也没有找到任何帮助.嗯,对我来说很奇怪,在SDL中似乎没有人需要STOP行为?

Eri*_*las 0

例如,解决您的问题的方法是使用 SDL 更好地管理您的音频设备。这是我的建议:

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);
}
Run Code Online (Sandbox Code Playgroud)

这对我有用,在 stopAudio() 之后不会调用回调,也不会向扬声器发送垃圾。