diff --git a/player/AudioSRC.cpp b/player/AudioSRC.cpp index 2e616612..e39f9396 100644 --- a/player/AudioSRC.cpp +++ b/player/AudioSRC.cpp @@ -51,29 +51,37 @@ int AudioSRC::getPCMData(char *buf, int size) { return _delegate->getPCMData(buf, size); } - if ((int)(size / _audio_cvt.len_ratio) != _origin_size) { - _origin_size = size / _audio_cvt.len_ratio; - _origin_buf.reset(new char[(std::max)(_origin_size, size)], [](char *ptr) { - delete[] ptr; - }); - InfoL << "origin pcm buffer size is:" << _origin_size << ", target pcm buffer size is:" << size; + //对应的未转换前pcm的长度 + auto original_size = (int) (size / _audio_cvt.len_ratio); + if (original_size % 4 != 0) { + //必须为4byte的整数(双通道16bit一个采样就4个字节) + original_size = 4 * (original_size / 4) + 4; } - auto origin_size = _delegate->getPCMData(_origin_buf.get(), _origin_size); + //需要准备这么长的buf用于重采样 + if ((int) (original_size * _audio_cvt.len_mult) != _buf_size) { + _buf_size = original_size * _audio_cvt.len_mult; + _buf.reset(new char[_buf_size], [](char *ptr) { + delete[] ptr; + }); + InfoL << "origin pcm buffer size is:" << original_size << ", target pcm buffer size is:" << size; + } + + auto origin_size = _delegate->getPCMData(_buf.get(), original_size ); if (!origin_size) { //获取数据失败 TraceL << "get empty pcm data"; return 0; } - _audio_cvt.buf = (Uint8 *) _origin_buf.get(); + _audio_cvt.buf = (Uint8 *) _buf.get(); _audio_cvt.len = origin_size; if (0 != SDL_ConvertAudio(&_audio_cvt)) { WarnL << "SDL_ConvertAudio failed!"; _audio_cvt.len_cvt = 0; } if (_audio_cvt.len_cvt) { - _target_buf.append(_origin_buf.get(), _audio_cvt.len_cvt); + _target_buf.append(_buf.get(), _audio_cvt.len_cvt); } if (_target_buf.size() < size) { return 0; diff --git a/player/AudioSRC.h b/player/AudioSRC.h index f5d6cdb8..7c954799 100644 --- a/player/AudioSRC.h +++ b/player/AudioSRC.h @@ -55,8 +55,8 @@ public: private: bool _enabled = true; - int _origin_size = 0; - std::shared_ptr _origin_buf; + int _buf_size = 0; + std::shared_ptr _buf; AudioSRCDelegate *_delegate = nullptr; BufferLikeString _target_buf; SDL_AudioCVT _audio_cvt;