예제 #1
0
void HrtfPanner::pan(float* input, float *left_output, float *right_output) {
	//Do we need to crossfade? We do if we've moved more than the threshold and crossfading is being allowed.
	bool needsCrossfade = should_crossfade && fabs(azimuth-prev_azimuth)+fabs(elevation-prev_elevation) >= crossfade_threshold;
	if(azimuth != prev_azimuth || elevation != prev_elevation) {
		if(needsCrossfade) {
			std::swap(left_convolver, prev_left_convolver);
			std::swap(right_convolver, prev_right_convolver);
			left_convolver->reset();
			right_convolver->reset();
		}
		float* left_response_ptr = left_response_workspace.get(response_length);
		float* right_response_ptr = right_response_workspace.get(response_length);
		float leftDelay, rightDelay;
		std::tie(leftDelay, rightDelay) = hrtf->computeCoefficientsStereo(elevation, azimuth, left_response_ptr, right_response_ptr);
		left_convolver->setResponse(response_length, left_response_ptr);
		right_convolver->setResponse(response_length, right_response_ptr);
		left_delay->setDelay(leftDelay, needsCrossfade);
		right_delay->setDelay(rightDelay, needsCrossfade);
	}
	//These two convolutions always happen.
	left_convolver->convolve(input, left_output);
	right_convolver->convolve(input, right_output);
	if(needsCrossfade) {
		double delta = 1.0/block_size;
		float* crossfade_ptr = crossfade_workspace.get(block_size);
		prev_left_convolver->convolve(input, crossfade_ptr);
		for(int i = 0; i < block_size; i++) left_output[i] = (block_size-i)*delta*crossfade_ptr[i]+i*delta*left_output[i];
		prev_right_convolver->convolve(input, crossfade_ptr);
		for(int i = 0; i < block_size; i++) right_output[i] = (block_size-i)*delta*crossfade_ptr[i]+i*delta*right_output[i];
	}
	prev_azimuth = azimuth;
	prev_elevation = elevation;
	left_delay->process(block_size, left_output, left_output);
	right_delay->process(block_size, right_output, right_output);
}	
예제 #2
0
HrtfPanner::HrtfPanner(int _block_size, float _sr, std::shared_ptr<HrtfData> _hrtf): block_size(_block_size), sr(_sr), hrtf(_hrtf) {
	response_length = hrtf->getLength();
	float* left_response_ptr= left_response_workspace.get(response_length);
	float* right_response_ptr = right_response_workspace.get(response_length);
	hrtf->computeCoefficientsStereo(azimuth, elevation, left_response_ptr, right_response_ptr);
	left_convolver = new BlockConvolver(block_size);
	right_convolver = new BlockConvolver(block_size);
	prev_left_convolver = new BlockConvolver(block_size);
	prev_right_convolver = new BlockConvolver(block_size);
	left_convolver->setResponse(response_length, left_response_ptr);
	right_convolver->setResponse(response_length, right_response_ptr);
	left_delay = new DoppleringDelayLine(hrtf->getMaxDelay(), _sr);
	right_delay = new DoppleringDelayLine(hrtf->getMaxDelay(), _sr);
	// Move delay over 1 MS.
	left_delay->setInterpolationTime(0.003);
	right_delay->setInterpolationTime(0.003);
}