diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/soundplayer.cc | 123 | ||||
| -rw-r--r-- | src/soundplayer.h | 15 | 
2 files changed, 87 insertions, 51 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); diff --git a/src/soundplayer.h b/src/soundplayer.h index 8502e6e..d8ba929 100644 --- a/src/soundplayer.h +++ b/src/soundplayer.h @@ -31,13 +31,16 @@  #include <QString>  #include <QList>  #include <QMutex> +#include <QMap> + +#include <cstdlib>  class QueueItem  {  public:  	float *samples; -	size_t pos; -	size_t size; +	std::size_t pos; +	std::size_t size;  };  class SoundPlayer @@ -57,4 +60,12 @@ private:  	QList<QueueItem> queue;  	QList<QueueItem> active; + +	struct Samples +	{ +		float *data; +		std::size_t size; +	}; +	Samples getSampleData(QString file); +	QMap<QString, Samples> cache;  }; | 
