vector<float> loadDistortion(string& filename) {
	auto doublesBuffer = loadDoubles(filename);
	vector<float> floatBuffer(doublesBuffer.size());
	for(int i=0; i<doublesBuffer.size(); i++) {
		floatBuffer[i] = (float) doublesBuffer[i];
	}
	return floatBuffer;
}
Beispiel #2
0
/**
 * 指定したバイト数だけpcmデータを読み込みます。
 * エラーが発生するか、終端に達するまでsizeで指定したバイト数だけ読み込めます。
 */
bool PitchShiftWaveReader::read(void *dst, std::size_t size, std::size_t *actualSize)
{
	if(!isOpen()){
		return false;
	}
	
	if(size == 0){
		if(actualSize){
			*actualSize = 0;
		}
		return true;
	}

	// 出力に必要な入力サンプル数を求める。
	const std::size_t reqOutSamples = size / format_.blockAlign; //floor
	const WaveSize reqSrcSamples0 = resampler_ ? resampler_->calcRequiredInputSize(reqOutSamples) : reqOutSamples;
	if(reqSrcSamples0 > std::numeric_limits<std::size_t>::max() / format_.blockAlign){
		return false;
	}
	const std::size_t reqSrcSamples = static_cast<std::size_t>(reqSrcSamples0);
	const std::size_t reqSrcBytes = reqSrcSamples * format_.blockAlign;

	// read source bytes.
	std::size_t actualSizeSrc = 0;
	HeapArray<uint8_t> byteBuffer(reqSrcBytes);
	if(!source_->read(byteBuffer.get(), reqSrcBytes, &actualSizeSrc)){
		return false;
	}

	// pitch shift.
	const std::size_t actualSrcSamples = actualSizeSrc / format_.blockAlign; //floor

	if(shiftRatio_ != 1.0f){
		HeapArray<float> floatBuffer(actualSrcSamples);
		for(unsigned int ch = 0; ch < format_.channels; ++ch){
			demultiplex(floatBuffer.get(), byteBuffer.get(), ch, actualSrcSamples, format_.blockAlign, format_.bytesPerSample);

			shifters_[ch]->smbPitchShift(
				shiftRatio_,
				actualSrcSamples,
				fftOverlapFactor_,
				static_cast<float>(format_.samplesPerSec),
				floatBuffer.get(),
				floatBuffer.get());

			multiplex(byteBuffer.get(), floatBuffer.get(), ch, actualSrcSamples, format_.blockAlign, format_.bytesPerSample);
		}
	}

	// resample.
	if(resampler_){
		assert(actualSrcSamples == reqSrcSamples);
		std::size_t actualOutSamples = reqOutSamples;
		if(actualSrcSamples != reqSrcSamples){
			const std::size_t maxOutSamples = static_cast<std::size_t>(std::min(resampler_->calcMaxOutputSize(actualSrcSamples), static_cast<WaveSize>(reqOutSamples)));
			if(actualOutSamples > maxOutSamples){
				actualOutSamples = maxOutSamples;
			}
		}

		switch(format_.blockAlign){
		case 1:
			resampler_->resample(
				reinterpret_cast<uint8_t *>(dst),
				reinterpret_cast<uint8_t *>(dst) + actualOutSamples,
				byteBuffer.get(),
				byteBuffer.get() + actualSrcSamples);
			break;
		case 2:
			resampler_->resample(
				reinterpret_cast<uint16_t *>(dst),
				reinterpret_cast<uint16_t *>(dst) + actualOutSamples,
				reinterpret_cast<const uint16_t *>(byteBuffer.get()),
				reinterpret_cast<const uint16_t *>(byteBuffer.get()) + actualSrcSamples);
			break;
		case 4:
			resampler_->resample(
				reinterpret_cast<uint32_t *>(dst),
				reinterpret_cast<uint32_t *>(dst) + actualOutSamples,
				reinterpret_cast<const uint32_t *>(byteBuffer.get()),
				reinterpret_cast<const uint32_t *>(byteBuffer.get()) + actualSrcSamples);
			break;
		}
		if(actualSize){
			*actualSize = actualOutSamples * format_.blockAlign;
		}
		outputPos_ += actualOutSamples;
	}
	else{
		std::memcpy(dst, byteBuffer.get(), actualSrcSamples * format_.blockAlign);
		if(actualSize){
			*actualSize = actualSrcSamples * format_.blockAlign;
		}
		outputPos_ += actualSrcSamples;
	}

	return true;
}