samplebrain/samplebrain/src/renderer.cpp

117 lines
3.3 KiB
C++
Raw Normal View History

2015-07-09 17:50:03 -03:00
#include "renderer.h"
#include <iostream>
using namespace spiralcore;
using namespace std;
2015-07-11 08:29:51 -03:00
void renderer::init(brain &source, brain &target) {
2015-07-11 15:03:05 -03:00
m_volume=1;
2015-07-12 20:26:30 -03:00
m_playing=false;
2015-07-09 17:50:03 -03:00
m_source=source;
m_target=target;
m_render_time=0;
m_render_blocks.clear();
}
2015-07-09 19:54:05 -03:00
static int ratio_time = 0;
2015-07-09 17:50:03 -03:00
void renderer::process(u32 nframes, float *buf) {
2015-07-11 08:29:51 -03:00
if (!m_playing) return;
2015-07-09 17:50:03 -03:00
// get blocks from source for the current buffer
u32 tgt_shift = m_target.get_block_size()-m_target.get_overlap();
u32 tgt_start = m_render_time/(float)tgt_shift;
u32 tgt_end = (m_render_time+nframes)/(float)tgt_shift;
2015-07-09 18:59:44 -03:00
2015-07-12 20:26:30 -03:00
if (tgt_end>=m_target.get_num_blocks() || m_source.get_num_blocks()==0) {
2015-07-09 18:59:44 -03:00
m_render_time=0;
m_render_blocks.clear();
// next time...
return;
}
// cerr<<"-----------------"<<endl;
// cerr<<"tgt start:"<<tgt_start<<endl;
// cerr<<"tgt end:"<<tgt_end<<endl;
2015-07-09 17:50:03 -03:00
// get indices for current buffer
2015-07-09 18:59:44 -03:00
for (u32 tgt_index = tgt_start; tgt_index<=tgt_end; tgt_index++) {
2015-07-09 17:50:03 -03:00
u32 time=tgt_index*tgt_shift;
2015-07-11 08:29:51 -03:00
u32 src_index = m_source.search(m_target.get_block(tgt_index), m_search_params);
2015-07-09 17:50:03 -03:00
// put them in the index list
m_render_blocks.push_back(render_block(src_index,time));
}
// render all blocks in list
for (std::list<render_block>::iterator i=m_render_blocks.begin(); i!=m_render_blocks.end(); ++i) {
const sample &pcm=m_source.get_block_pcm(i->m_index);
// get the sample offset into the buffer
s32 offset = i->m_time-m_render_time;
// assume midway through block
2015-07-09 18:59:44 -03:00
u32 block_start = offset;
2015-07-09 17:50:03 -03:00
u32 buffer_start = 0;
2015-07-09 18:59:44 -03:00
if (offset<0) {
block_start=-offset;
2015-07-09 17:50:03 -03:00
if (block_start>=pcm.get_length()) i->m_finished=true;
} else { // block is midway through buffer
block_start=0;
buffer_start=offset;
}
2015-07-09 18:59:44 -03:00
// cerr<<"-----------------"<<endl;
// cerr<<"block start:"<<block_start<<endl;
// cerr<<"buffer start:"<<buffer_start<<endl;
2015-07-09 17:50:03 -03:00
if (!i->m_finished) {
// mix in
u32 buffer_pos = buffer_start;
u32 block_pos = block_start;
2015-07-09 18:59:44 -03:00
u32 block_end = pcm.get_length();
2015-07-09 17:50:03 -03:00
while (block_pos<block_end && buffer_pos<nframes) {
2015-07-11 08:29:51 -03:00
buf[buffer_pos]+=pcm[block_pos]*0.2*m_volume;
2015-07-09 17:50:03 -03:00
++buffer_pos;
++block_pos;
}
}
}
// delete old ones
std::list<render_block>::iterator i=m_render_blocks.begin();
std::list<render_block>::iterator ni=m_render_blocks.begin();
while(i!=m_render_blocks.end()) {
ni++;
if (i->m_finished) m_render_blocks.erase(i);
i=ni;
}
m_render_time+=nframes;
}
bool renderer::unit_test() {
brain source;
source.load_sound("test_data/up.wav");
2015-07-09 18:59:44 -03:00
source.init(10,0,0);
2015-07-09 17:50:03 -03:00
brain target;
target.load_sound("test_data/up.wav");
2015-07-09 18:59:44 -03:00
target.init(10,0,0);
2015-07-09 17:50:03 -03:00
2015-07-11 08:29:51 -03:00
renderer rr(source,target);
2015-07-09 17:50:03 -03:00
float *buf=new float[10];
rr.process(10,buf);
assert(rr.m_render_blocks.size()==2);
2015-07-09 18:59:44 -03:00
rr.process(10,buf);
assert(rr.m_render_blocks.size()==3);
rr.process(20,buf);
assert(rr.m_render_blocks.size()==4);
2015-07-09 17:50:03 -03:00
rr.process(5,buf);
2015-07-09 18:59:44 -03:00
assert(rr.m_render_blocks.size()==2);
2015-07-09 17:50:03 -03:00
2015-07-09 18:59:44 -03:00
target.init(10,5,0);
2015-07-09 17:50:03 -03:00
rr.process(10,buf);
2015-07-09 18:59:44 -03:00
assert(rr.m_render_blocks.size()==5);
2015-07-09 17:50:03 -03:00
}