demo readish

This commit is contained in:
Dave Griffiths 2015-07-09 22:59:44 +01:00
parent cb1ca8e0e3
commit 7d7c7c82f6
8 changed files with 62 additions and 52 deletions

View File

@ -4,14 +4,12 @@ TARGET_LIB := libsamplebrain.a
SRCS := src/fft.cpp \
src/brain.cpp \
src/block.cpp \
src/libmfcc.cpp \
src/main.cpp \
src/mfcc.cpp \
src/renderer.cpp \
src/aquila/filter/MelFilterBank.cpp \
src/aquila/filter/MelFilter.cpp \
src/aquila/transform/Dct.cpp \
src/renderer.cpp
TARGET_SRCS := src/main.cpp

View File

@ -4,4 +4,4 @@ make distclean
autoheader
# build configure
autoconf configure.ac > configure
./configure CXX=g++-4.7
./configure CXX=g++-4.7 CCFLAGS=-O3

View File

@ -1,7 +1,6 @@
#include <assert.h>
#include <iostream>
#include "libmfcc.h"
#include "block.h"
using namespace spiralcore;
@ -20,7 +19,7 @@ void enveloper(sample &s, u32 start, u32 end) {
}
}
block::block(const string &filename, const sample &pcm, u32 rate, bool ditchpcm) :
block::block(const string &filename, const sample &pcm, u32 rate, u32 env, bool ditchpcm) :
m_pcm(pcm),
m_fft(pcm.get_length()),
m_mfcc(MFCC_FILTERS),
@ -32,7 +31,7 @@ block::block(const string &filename, const sample &pcm, u32 rate, bool ditchpcm)
assert(m_mfcc_proc!=NULL);
assert(m_fftw!=NULL);
enveloper(m_pcm,50,50);
enveloper(m_pcm,env,env);
m_fftw->impulse2freq(m_pcm.get_non_const_buffer());
@ -104,7 +103,7 @@ bool block::unit_test() {
data[i]=i/(float)data.get_length();
}
block bb("test",data,44100);
block bb("test",data,44100,0);
assert(bb.m_pcm.get_length()==data.get_length());
//assert(bb.m_fft.get_length()==data.get_length());
@ -113,7 +112,7 @@ bool block::unit_test() {
assert(bb.m_rate==44100);
assert(bb.m_block_size==data.get_length());
block bb2("test",data,44100);
block bb2("test",data,44100,0);
assert(bb.compare(bb2,1)==0);
assert(bb.compare(bb2,0)==0);
assert(bb.compare(bb2,0.5)==0);
@ -123,9 +122,9 @@ bool block::unit_test() {
data[i]=i%10;
}
block cpy("test",data,100);
block cpy("test",data,100,4);
{
block bb3("test",data2,44100);
block bb3("test",data2,44100,4);
assert(bb.compare(bb3,1)!=0);
assert(bb.compare(bb3,0)!=0);
assert(bb.compare(bb3,0.5)!=0);

View File

@ -12,7 +12,7 @@ namespace spiralcore {
class block {
public:
// runs analysis on pcm
block(const std::string &filename, const sample &pcm, u32 rate, bool ditchpcm=false);
block(const std::string &filename, const sample &pcm, u32 rate, u32 env, bool ditchpcm=false);
// returns distance based on ratio of fft-mfcc values
double compare(const block &other, float ratio) const;

View File

@ -38,23 +38,23 @@ void save_sample(const string &filename, const sample s) {
}
// rewrites whole brain
void brain::init(u32 block_size, u32 overlap, bool ditchpcm) {
void brain::init(u32 block_size, u32 overlap, u32 env, bool ditchpcm) {
m_blocks.clear();
m_block_size = block_size;
m_overlap = overlap;
for (vector<sample>::iterator i=m_samples.begin(); i!=m_samples.end(); ++i) {
chop_and_add(*i, block_size, overlap, ditchpcm);
chop_and_add(*i, block_size, overlap, env, ditchpcm);
}
}
void brain::chop_and_add(const sample &s, u32 block_size, u32 overlap, bool ditchpcm) {
void brain::chop_and_add(const sample &s, u32 block_size, u32 overlap, u32 env, bool ditchpcm) {
u32 pos=0;
while (pos+block_size-1<s.get_length()) {
cerr<<'\r';
cerr<<"adding: "<<pos/(float)s.get_length()*100;
sample region;
s.get_region(region,pos,pos+block_size-1);
m_blocks.push_back(block("",region,44100,ditchpcm));
m_blocks.push_back(block("",region,44100,env,ditchpcm));
pos += (block_size-overlap);
}
}
@ -123,13 +123,13 @@ bool brain::unit_test() {
assert(b.m_samples.size()==2);
assert(s.get_length()==100);
b.init(10, 0);
b.init(10, 0, 0);
assert(b.m_samples.size()==2);
assert(b.m_blocks.size()==20);
b.init(10, 5);
b.init(10, 5, 0);
assert(b.m_samples.size()==2);
assert(b.m_blocks.size()==38);
b.init(20, 5);
b.init(20, 5, 0);
assert(b.m_samples.size()==2);
assert(b.m_blocks.size()==12);
@ -139,8 +139,8 @@ bool brain::unit_test() {
brain b3;
b3.load_sound("test_data/up.wav");
b2.init(512, 0);
b3.init(512, 0);
b2.init(512, 0, 20);
b3.init(512, 0, 20);
assert(b3.search(b2.m_blocks[0],1)==0);
assert(b3.search(b2.m_blocks[9],1)==9);
assert(b3.search(b2.m_blocks[19],1)==19);

View File

@ -14,7 +14,7 @@ public:
brain();
// rewrites whole brain
void init(u32 block_size, u32 overlap, bool ditchpcm=false);
void init(u32 block_size, u32 overlap, u32 env, bool ditchpcm=false);
// load, chop up and add to brain
// todo: add tags
@ -25,6 +25,7 @@ public:
const sample &get_block_pcm(u32 index) const;
const block &get_block(u32 index) const;
const u32 get_num_blocks() const { return m_blocks.size(); }
const u32 get_block_size() const { return m_block_size; }
const u32 get_overlap() const { return m_overlap; }
@ -34,7 +35,7 @@ public:
private:
void chop_and_add(const sample &s, u32 block_size, u32 overlap, bool ditchpcm=false);
void chop_and_add(const sample &s, u32 block_size, u32 overlap, u32 env, bool ditchpcm=false);
vector<block> m_blocks;
vector<sample> m_samples;

View File

@ -53,20 +53,21 @@ void run_audio(void* c, unsigned int frames) {
int main(int argc, char *argv[])
{
// unit_test();
unit_test();
cerr<<"starting"<<endl;
brain source, target;
source.load_sound("../sound/source/shostakovich6.wav");
// source.load_sound("../sound/source/808.wav");
// source.load_sound("../sound/source/shostakovich6.wav");
source.load_sound("../sound/source/808.wav");
source.load_sound("../sound/source/full.wav");
target.load_sound("../sound/source/sb-left.wav");
// target.load_sound("../sound/source/sb-left.wav");
target.load_sound("../sound/source/apache.wav");
cerr<<"loaded sounds"<<endl;
u32 len=3000;
source.init(len,len-len);
target.init(len,len-len/2);
u32 len=1024;
source.init(len,len-len,50);
target.init(len,len-len/4,50);
cerr<<"ready..."<<endl;
a = new audio_device("samplebrain",44100,2048);

View File

@ -14,15 +14,23 @@ void renderer::init(brain &source, brain &target, float ratio) {
void renderer::process(u32 nframes, float *buf) {
// get blocks from source for the current buffer
u32 src_shift = m_source.get_block_size()-m_source.get_overlap();
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;
tgt_end++;
if (tgt_end>=m_target.get_num_blocks()) {
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;
// get indices for current buffer
for (u32 tgt_index = tgt_start; tgt_index<tgt_end; tgt_index++) {
for (u32 tgt_index = tgt_start; tgt_index<=tgt_end; tgt_index++) {
u32 time=tgt_index*tgt_shift;
u32 src_index = m_source.search(m_target.get_block(tgt_index), m_ratio);
// put them in the index list
@ -36,24 +44,27 @@ void renderer::process(u32 nframes, float *buf) {
s32 offset = i->m_time-m_render_time;
// assume midway through block
s32 block_start = offset;
u32 block_start = offset;
u32 buffer_start = 0;
if (block_start<0) {
block_start=-block_start;
if (offset<0) {
block_start=-offset;
if (block_start>=pcm.get_length()) i->m_finished=true;
} else { // block is midway through buffer
block_start=0;
buffer_start=offset;
}
// cerr<<"-----------------"<<endl;
// cerr<<"block start:"<<block_start<<endl;
// cerr<<"buffer start:"<<buffer_start<<endl;
if (!i->m_finished) {
// mix in
u32 buffer_pos = buffer_start;
u32 block_pos = block_start;
u32 block_end = block_start+pcm.get_length();
u32 block_end = pcm.get_length();
while (block_pos<block_end && buffer_pos<nframes) {
buf[buffer_pos]+=pcm[block_pos];
buf[buffer_pos]+=pcm[block_pos]*0.2;
++buffer_pos;
++block_pos;
}
@ -75,26 +86,26 @@ void renderer::process(u32 nframes, float *buf) {
bool renderer::unit_test() {
brain source;
source.load_sound("test_data/up.wav");
source.init(10,0);
source.init(10,0,0);
brain target;
target.load_sound("test_data/up.wav");
target.init(10,0);
target.init(10,0,0);
renderer rr(source,target,1);
float *buf=new float[10];
rr.process(5,buf);
assert(rr.m_render_blocks.size()==1);
rr.process(10,buf);
assert(rr.m_render_blocks.size()==1);
rr.process(20,buf);
assert(rr.m_render_blocks.size()==2);
rr.process(5,buf);
assert(rr.m_render_blocks.size()==1);
target.init(10,5);
rr.process(10,buf);
assert(rr.m_render_blocks.size()==3);
rr.process(20,buf);
assert(rr.m_render_blocks.size()==4);
rr.process(5,buf);
assert(rr.m_render_blocks.size()==2);
target.init(10,5,0);
rr.process(10,buf);
assert(rr.m_render_blocks.size()==5);
}