无论我使用什么音频文件,它总是会切断大约四分之一。我有一种感觉,因为我正在将解码后的音频转换为Uint8*
,但如果我不这样做,音频播放速度非常快,而且它仍然只播放大约一半的文件。此外,使用SDL_MixAudio
代替SDL_memcpy
会导致声音的一堆副本因某种原因相互影响。
Uint8* audio_pos;
Uint32 audio_len;
void audioCallback(void* userdata, Uint8* stream, int len) {
if (audio_len == 0) return;
len = (len > audio_len ? audio_len : len);
SDL_memcpy(stream, audio_pos, len);
audio_pos += len;
audio_len -= len;
}
int main(int argc, char *argv[]) {
...
short* decoded;
int channels, rate, len;
len = stb_vorbis_decode_filename(RealPath("music.ogg").c_str(), &channels, &rate, &decoded);
SDL_AudioSpec spec;
spec.freq = rate;
spec.format = AUDIO_S16;
spec.channels = channels;
spec.samples = 2048;
spec.callback = audioCallback;
spec.userdata = NULL;
audio_pos = (Uint8*)decoded;
audio_len = len;
if (SDL_OpenAudio(&spec, NULL) < 0) {
std::cout << "failed to open audio device: " << SDL_GetError() << '\n';
SDL_GL_DeleteContext(context);
SDL_Quit();
return -1;
}
SDL_PauseAudio(0);
SDL_Event windowEvt;
while (true) {
if (audio_len == 0) break;
if (SDL_PollEvent(&windowEvt)) {
if (windowEvt.type == SDL_QUIT) break;
if (windowEvt.type == SDL_KEYUP && windowEvt.key.keysym.sym == SDLK_ESCAPE) break;
}
SDL_GL_SwapWindow(window);
}
...
}
答案 0 :(得分:0)
stb_vorbis_decode_filename
返回&#34;已解码的样本数,&#34;这与int16
有关,并不包括渠道因素。
您正在寻找:
int32 length = stb_vorbis_decode_filename("thing.ogg", &channels, &rate, &decoded);
int32 audio_length = length * channels * (sizeof(int16) / sizeof(uint8));
对于声音重叠的SDL_MixAudio
vs SDL_memcpy
,您需要使用静音值明确清除流。例如,当您输入SDL音频回调时SDL_memset
。
void audioCallback(void* userdata, Uint8* stream, int len)
{
SDL_memset(stream, 0, len);// silence the stream
if (audio_len == 0) return;
len = (len > audio_len ? audio_len : len);
SDL_MixAudio(stream, audio_pos, len, SDL_MIX_MAXVOLUME);// this takes a volume argument
audio_pos += len;
audio_len -= len;
}
传递给SDL_memset
的零应与您在调用SDL_AudioSpec
时在SDL_OpenAudioDevice
中创建的静音值相同。