2016-06-28 8 views
0

내가 사용하는 오디오 파일이 무엇이든 관계없이 항상 약 4 분의 1이 잘립니다. 디코딩 된 오디오를 Uint8*으로 전송했기 때문에 느낌이 들지만, 그렇지 않으면 오디오가 실제로 빠르게 재생되고 파일의 절반 정도만 재생됩니다. 또한 SDL_memcpy 대신 SDL_MixAudio을 사용하면 어떤 이유로 여러 개의 소리 복사본이 서로 재생됩니다.stb_vorbis 및 SDL2로 오디오 재생이 끊어집니다.

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

stb_vorbis_decode_filename는이 int16에 대하여이고,는 채널 계수를 포함하지 않는 "샘플들의 수가 디코딩"을 반환. 당신이 찾고있는 : 사운드 중복에 대한 SDL_memcpySDL_MixAudio에 대한

int32 length = stb_vorbis_decode_filename("thing.ogg", &channels, &rate, &decoded); 
int32 audio_length = length * channels * (sizeof(int16)/sizeof(uint8)); 

, 당신은 명시 적으로 침묵 값 스트림을 취소해야합니다. 예를 들어, SDL_memset은 SDL 오디오 콜백을 입력 할 때 사용됩니다.

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_OpenAudioDevice를 호출 할 때 SDL_AudioSpec에서 만든 같은 침묵의 값이어야합니다 SDL_memset에 전달.