mirror of
https://gitlab.com/then-try-this/samplebrain.git
synced 2025-05-12 18:47:21 +00:00
demo readish
This commit is contained in:
parent
cb1ca8e0e3
commit
7d7c7c82f6
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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,13 +122,13 @@ bool block::unit_test() {
|
||||
data[i]=i%10;
|
||||
}
|
||||
|
||||
block cpy("test",data,100);
|
||||
block cpy("test",data,100,4);
|
||||
{
|
||||
block bb3("test",data2,44100);
|
||||
assert(bb.compare(bb3,1)!=0);
|
||||
assert(bb.compare(bb3,0)!=0);
|
||||
assert(bb.compare(bb3,0.5)!=0);
|
||||
cpy=bb3;
|
||||
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);
|
||||
cpy=bb3;
|
||||
}
|
||||
|
||||
assert(cpy.m_pcm.get_length()==200);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user