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; }