Exemplo n.º 1
0
void Hrtf::get_kemar_data(kemar_ptr & kemar_data, int & elev_n, const v3f &pos) {
	
	kemar_data = 0;
	elev_n = 0;
	if (pos.is0())
		return;

#ifdef _WINDOWS
       float len = (float)_hypot(pos.x, pos.y);
#else
       float len = (float)hypot(pos.x, pos.y);
#endif

	int elev_gr = (int)(180 * atan2f(pos.z, len) / (float)M_PI);
	//LOG_DEBUG(("elev = %d (%g %g %g)", elev_gr, pos.x, pos.y, pos.z));

	for(size_t i = 0; i < KemarElevationCount; ++i)
	{
		const kemar_elevation_data &elev = ::kemar_data[i];
		if (elev_gr < elev.elevation + KemarElevationStep / 2)
		{
			//LOG_DEBUG(("used elevation %d", elev.elevation)); 
			kemar_data = elev.data;
			elev_n = elev.samples;
			break;
		}
	}
}
Exemplo n.º 2
0
unsigned Hrtf::process(
	unsigned sample_rate, clunk::Buffer &dst_buf, unsigned dst_ch,
	const clunk::Buffer &src_buf, unsigned src_ch,
	const v3f &delta_position, float fx_volume)
{
	s16 * const dst = static_cast<s16*>(dst_buf.get_ptr());
	const unsigned dst_n = (unsigned)dst_buf.get_size() / dst_ch / 2;

	const s16 * const src = static_cast<const s16 *>(src_buf.get_ptr());
	const unsigned src_n = (unsigned)src_buf.get_size() / src_ch / 2;
	assert(dst_n <= src_n);

	kemar_ptr kemar_data;
	int angles;
	get_kemar_data(kemar_data, angles, delta_position);

	if (delta_position.is0() || kemar_data == NULL) {
		//2d stereo sound!
		if (src_ch == dst_ch) {
			memcpy(dst_buf.get_ptr(), src_buf.get_ptr(), dst_buf.get_size());
			return dst_n;
		}
		else
			throw_ex(("unsupported sample conversion"));
	}
	assert(dst_ch == 2);
	
	//LOG_DEBUG(("data: %p, angles: %d", (void *) kemar_data, angles));

	float t_idt, angle_gr, left_to_right_amp;
	idt_iit(delta_position, t_idt, angle_gr, left_to_right_amp);

	const int kemar_sector_size = 360 / angles;
	const int kemar_idx[2] = {
		((360 - (int)angle_gr + kemar_sector_size / 2) / kemar_sector_size) % angles,
		((int)angle_gr + kemar_sector_size / 2) / kemar_sector_size
	};

	float amp[2] = {
		left_to_right_amp > 1? 1: 1 / left_to_right_amp,
		left_to_right_amp > 1? left_to_right_amp: 1
	};
	//LOG_DEBUG(("%g (of %d)-> left: %d, right: %d", angle_gr, angles, kemar_idx_left, kemar_idx_right));
	
	int idt_offset = (int)(t_idt * sample_rate);

	int window = 0;
	while(sample3d[0].get_size() < dst_n * 2 || sample3d[1].get_size() < dst_n * 2) {
		size_t offset = window * WINDOW_SIZE / 2;
		assert(offset + WINDOW_SIZE / 2 <= src_n);
		for(unsigned c = 0; c < dst_ch; ++c) {
			sample3d[c].reserve(WINDOW_SIZE);
			s16 *dst = static_cast<s16 *>(static_cast<void *>((static_cast<u8 *>(sample3d[c].get_ptr()) + sample3d[c].get_size() - WINDOW_SIZE)));
			hrtf(c, dst, src + offset * src_ch, src_ch, src_n - offset, idt_offset, kemar_data, kemar_idx[c], amp[c]);
		}
		++window;
	}
	assert(sample3d[0].get_size() >= dst_n * 2 && sample3d[1].get_size() >= dst_n * 2);
	
	//LOG_DEBUG(("angle: %g", angle_gr));
	//LOG_DEBUG(("idt offset %d samples", idt_offset));
	s16 * src_3d[2] = { static_cast<s16 *>(sample3d[0].get_ptr()), static_cast<s16 *>(sample3d[1].get_ptr()) };
	
	//LOG_DEBUG(("size1: %u, %u, needed: %u\n%s", (unsigned)sample3d[0].get_size(), (unsigned)sample3d[1].get_size(), dst_n, sample3d[0].dump().c_str()));
	
	for(unsigned i = 0; i < dst_n; ++i) {
		for(unsigned c = 0; c < dst_ch; ++c) {
			dst[i * dst_ch + c] = src_3d[c][i];
		}
	}
	skip(dst_n);
	return window * WINDOW_SIZE / 2;
}