diff options
| author | Bent Bisballe Nyeng <deva@aasimon.org> | 2018-12-27 13:57:43 +0100 | 
|---|---|---|
| committer | Bent Bisballe Nyeng <deva@aasimon.org> | 2018-12-27 13:57:43 +0100 | 
| commit | 5864285c0b987f97b632d1acfcc7cc49439e985d (patch) | |
| tree | 98b0647f856131b1889aeed86bd7c421fd1a21a9 /src/soundplayer.cc | |
| parent | 55e4e6a951ca2b5bb23cdc600c6661e76c70a50a (diff) | |
Add audio cache for the resampled/channel expanded sounds.
Diffstat (limited to 'src/soundplayer.cc')
| -rw-r--r-- | src/soundplayer.cc | 123 | 
1 files changed, 74 insertions, 49 deletions
| diff --git a/src/soundplayer.cc b/src/soundplayer.cc index 2570f31..c170ff2 100644 --- a/src/soundplayer.cc +++ b/src/soundplayer.cc @@ -104,72 +104,97 @@ void SoundPlayer::run()  	ao_shutdown();  } -void SoundPlayer::playFile(QString file) +SoundPlayer::Samples SoundPlayer::getSampleData(QString file)  { -	printf(" - playFile(%s)\n", file.toStdString().c_str()); - -	SNDFILE *fh; -	SF_INFO sf_info; - -	fh = sf_open(file.toStdString().c_str(), SFM_READ, &sf_info); -	if(!fh) +	// Not yet in cache. Read it from file +	if(!cache.contains(file))  	{ -		printf("Load error '%s'\n", file.toStdString().c_str()); -		return; -	} +		printf("Insert '%s' into cache\n", file.toStdString().data()); +		SNDFILE *fh; +		SF_INFO sf_info; -	size_t size = sf_info.frames * sf_info.channels; -	float *data = new float[size]; -	sf_read_float(fh, data, size); -	sf_close(fh); +		fh = sf_open(file.toStdString().c_str(), SFM_READ, &sf_info); +		if(!fh) +		{ +			printf("Load error '%s'\n", file.toStdString().c_str()); +			return {}; +		} -	if(sf_info.channels != 2) -	{ -		float* stereo_data = new float[sf_info.frames * 2]; -		for(int i = 0; i < sf_info.frames; ++i) +		size_t size = sf_info.frames * sf_info.channels; +		float *data = new float[size]; +		sf_read_float(fh, data, size); +		sf_close(fh); + +		if(sf_info.channels != 2)  		{ -			int c = 0; -			for(;c < sf_info.channels && c < 2; ++c) -			{ -				stereo_data[i * 2 + c] = data[i * sf_info.channels + c]; -			} -			int last = c - 1; -			for(;c < 2; ++c) +			printf("channel convert %d => 2\n", (int)sf_info.channels); +			float* stereo_data = new float[sf_info.frames * 2]; +			for(int i = 0; i < sf_info.frames; ++i)  			{ -				stereo_data[i * 2 + c] = data[i * sf_info.channels + last]; +				int c = 0; +				for(;c < sf_info.channels && c < 2; ++c) +				{ +					stereo_data[i * 2 + c] = data[i * sf_info.channels + c]; +				} +				int last = c - 1; +				for(;c < 2; ++c) +				{ +					stereo_data[i * 2 + c] = data[i * sf_info.channels + last]; +				}  			} +			delete[] data; +			data = stereo_data; +			size = sf_info.frames * 2;  		} -		delete[] data; -		data = stereo_data; -		size = sf_info.frames * 2; -	} -	if(sf_info.samplerate != 48000) -	{ -		double ratio = 48000.0 / sf_info.samplerate; -		std::size_t resampled_size = sf_info.frames * 2 * ratio; -		float *resampled_data = new float[resampled_size + 1]; +		if(sf_info.samplerate != 48000) +		{ +			printf("resample %d => 48000\n", (int)sf_info.samplerate); +			double ratio = 48000.0 / sf_info.samplerate; +			std::size_t resampled_frames = sf_info.frames * ratio; +			float *resampled_data = new float[resampled_frames * 2]; + +			SRC_DATA s{}; +			s.data_in = data; +			s.input_frames = sf_info.frames; -		SRC_DATA s{}; -		s.data_in = data; -		s.input_frames = sf_info.frames; +			s.data_out = resampled_data; +			s.output_frames = resampled_frames; -		s.data_out = resampled_data; -		s.output_frames = resampled_size + 1; +			s.src_ratio = ratio; -		s.src_ratio = ratio; +			int err = src_simple(&s, SRC_SINC_BEST_QUALITY, 2); +			if(err) +			{ +				printf("SRC error: %s\n", src_strerror(err)); +			} +			delete[] data; +			data = resampled_data; +			size = s.output_frames_gen * 2; +			printf("size: %d\n", (int)size); +		} -		src_simple(&s, SRC_SINC_BEST_QUALITY, 2); -		delete[] data; -		data = resampled_data; -		size = s.output_frames_gen * 2; -		printf("size: %d\n", (int)size); +		Samples s; +		s.data = data; +		s.size = size; +		printf(" - %p %d\n", (void*)s.data, (int)s.size); +		cache.insert(file, s);  	} +	return cache[file]; +} + +void SoundPlayer::playFile(QString file) +{ +	auto samples = getSampleData(file); + +	printf(" - playFile(%s) [%p %d]\n", file.toStdString().c_str(), +	       (void*)samples.data, (int)samples.size); +  	QueueItem qi; -	qi.samples = data; +	qi.samples = samples.data;  	qi.pos = 0; -	qi.size = size; +	qi.size = samples.size;  	{  		QMutexLocker lock(&mutex); | 
