void AudioBuffer::convert(const AudioSpec &_new_spec) { if(_new_spec == m_spec) { return; } AudioSpec new_spec = _new_spec; AudioBuffer dest[2]; unsigned bufidx = 0; AudioBuffer *source = this; if(source->rate() != new_spec.rate) { #if HAVE_LIBSAMPLERATE if(source->format() != AUDIO_FORMAT_F32) { dest[1].set_spec({AUDIO_FORMAT_F32, source->channels(), source->rate()}); source->convert_format(dest[1], source->frames()); source = &dest[1]; } dest[0].set_spec({source->format(), source->channels(), new_spec.rate}); source->convert_rate(dest[0], source->frames(), nullptr); source = &dest[0]; bufidx = 1; #else new_spec.rate = source->rate(); #endif } if(source->channels() != new_spec.channels) { dest[bufidx].set_spec({source->format(),new_spec.channels,source->rate()}); source->convert_channels(dest[bufidx], source->frames()); source = &dest[bufidx]; bufidx = (bufidx + 1) % 2; } if(source->format() != new_spec.format) { dest[bufidx].set_spec({new_spec.format,source->channels(),source->rate()}); source->convert_format(dest[bufidx], source->frames()); source = &dest[bufidx]; } if(new_spec != m_spec) { m_data = source->m_data; m_spec = new_spec; } }
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 }