Пример #1
0
void AudioBuffer::convert_channels(AudioBuffer &_dest, unsigned _frames_count)
{
	AudioSpec destspec{m_spec.format, _dest.channels(), m_spec.rate};
	if(_dest.spec() != destspec) {
		throw std::logic_error("unsupported format");
	}

	_frames_count = std::min(frames(),_frames_count);
	if(m_spec.channels == destspec.channels) {
		_dest.add_frames(*this,_frames_count);
		return;
	}

	switch(m_spec.format) {
		case AUDIO_FORMAT_U8:
			convert_channels<uint8_t>(*this,_dest,_frames_count);
			break;
		case AUDIO_FORMAT_S16:
			convert_channels<int16_t>(*this,_dest,_frames_count);
			break;
		case AUDIO_FORMAT_F32:
			convert_channels<float>(*this,_dest,_frames_count);
			break;
		default:
			throw std::logic_error("unsupported format");
	}
}
Пример #2
0
void SoundFX::load_audio_file(const char *_filename, AudioBuffer &_sample, const AudioSpec &_spec)
{
	try {
		std::string path = g_program.config().get_file_path(_filename, FILE_TYPE_ASSET);
		WAVFile wav;
		wav.open_read(path.c_str());
		_sample.load(wav);
		if(_spec != _sample.spec()) {
			PDEBUGF(LOG_V1, LOG_AUDIO, "converting from %s to %s\n",
					_sample.spec().to_string().c_str(),
					_spec.to_string().c_str());
			_sample.convert(_spec);
		}
	} catch(std::exception &e) {
		PERRF(LOG_AUDIO, "SoundFX: %s: %s\n", _filename, e.what());
	}
}
Пример #3
0
void AudioBuffer::add_frames(const AudioBuffer &_source, unsigned _frames_count)
{
	if(_source.spec() != m_spec) {
		throw std::logic_error("sound buffers must have the same spec");
	}
	_frames_count = std::min(_frames_count, _source.frames());
	if(_frames_count == 0) {
		return;
	}
	unsigned datalen = _frames_count * frame_size();
	auto srcstart = _source.m_data.begin();
	m_data.insert(m_data.end(), srcstart, srcstart+datalen);
}
Пример #4
0
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
}
Пример #5
0
void AudioBuffer::convert_format(AudioBuffer &_dest, unsigned _frames_count)
{
	AudioSpec destspec{_dest.format(), m_spec.channels, m_spec.rate};

	if(_dest.spec() != destspec) {
		throw std::logic_error("destination must have same channels and rate");
	}

	_frames_count = std::min(frames(),_frames_count);

	if(m_spec.format == destspec.format) {
		_dest.add_frames(*this,_frames_count);
		return;
	}

	const unsigned samples_count = m_spec.frames_to_samples(_frames_count);
	std::vector<uint8_t> buffer, *data=&buffer;
	switch(m_spec.format) {
		case AUDIO_FORMAT_U8:
			u8_to_f32(m_data, buffer, samples_count);
			break;
		case AUDIO_FORMAT_S16:
			s16_to_f32(m_data, buffer, samples_count);
			break;
		case AUDIO_FORMAT_F32:
			data = &m_data;
			break;
		default:
			throw std::logic_error("unsupported source format");
	}
	switch(destspec.format) {
		case AUDIO_FORMAT_S16:
			f32_to_s16(*data, _dest.m_data, samples_count);
			break;
		case AUDIO_FORMAT_F32:
			_dest.m_data.swap(buffer);
			break;
		default:
			throw std::logic_error("unsupported destination format");
	}
}