void AudioBuffer::convert_rate(AudioBuffer &_dest, unsigned _frames_count, SRC_STATE *_SRC) { AudioSpec destspec{AUDIO_FORMAT_F32, m_spec.channels, _dest.rate()}; if(m_spec.format != AUDIO_FORMAT_F32 || _dest.spec() != destspec) { throw std::logic_error("unsupported format"); } _frames_count = std::min(frames(),_frames_count); double rate_ratio = double(destspec.rate)/double(m_spec.rate); unsigned out_frames = unsigned(ceil(double(_frames_count) * rate_ratio)); if(out_frames==0) { return; } unsigned destpos = _dest.samples(); unsigned destframes = _dest.frames(); _dest.resize_frames(_dest.frames()+out_frames); #if HAVE_LIBSAMPLERATE SRC_DATA srcdata; srcdata.data_in = &at<float>(0); srcdata.data_out = &_dest.at<float>(destpos); srcdata.input_frames = _frames_count; srcdata.output_frames = out_frames; srcdata.src_ratio = rate_ratio; int srcresult; if(_SRC != nullptr) { srcdata.end_of_input = 0; srcresult = src_process(_SRC, &srcdata); } else { srcdata.end_of_input = 1; srcresult = src_simple(&srcdata, SRC_SINC_BEST_QUALITY, destspec.channels) ; } if(srcresult != 0) { throw std::runtime_error(std::string("error resampling: ") + src_strerror(srcresult)); } assert(srcdata.output_frames_gen>=0 && srcdata.output_frames_gen<=out_frames); if(srcdata.output_frames_gen != out_frames) { _dest.resize_frames(destframes + srcdata.output_frames_gen); } PDEBUGF(LOG_V2, LOG_MIXER, "convert rate: f-in: %d, f-out: %d, gen: %d\n", _frames_count, out_frames, srcdata.output_frames_gen); #else for(unsigned i=destpos; i<_dest.samples(); ++i) { _dest.operator[]<float>(i) = 0.f; } #endif }
void AudioBuffer::convert_channels(const AudioBuffer &_source, AudioBuffer &_dest, unsigned _frames_count) { unsigned d = _dest.samples(); _dest.resize_frames(_dest.frames()+_frames_count); if(_source.channels()==1 && _dest.channels()==2) { //from mono to stereo for(unsigned i=0; i<_frames_count; ++i) { T ch1 = _source.at<T>(i); _dest.operator[]<T>(d+i*2) = ch1; _dest.operator[]<T>(d+i*2+1) = ch1; } } else if(_source.channels()==2 && _dest.channels()==1) { //from stereo to mono for(unsigned i=0; i<_frames_count; ++i) { double ch1 = double(_source.at<T>(i*2)); double ch2 = double(_source.at<T>(i*2+1)); _dest.operator[]<T>(d+i) = T((ch1 + ch2) / 2.0); } } }