Exemple #1
0
bool OggStream::read(clunk::Buffer &data, unsigned hint) {
	if (hint == 0) 
		hint = 44100;
	
	data.set_size(hint);

	int section = 0;
	int r = ov_read(&_ogg_stream, (char *)data.get_ptr(), hint, 0, 2, 1, & section);
	//LOG_DEBUG(("ov_read(%d) = %d (section: %d)", hint, r, section));
	
	if(r >= 0) {
		data.set_size(r);
		
		return r != 0;
	}

	return false; //:(
}
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;
}