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 \
|
SRCS := src/fft.cpp \
|
||||||
src/brain.cpp \
|
src/brain.cpp \
|
||||||
src/block.cpp \
|
src/block.cpp \
|
||||||
src/libmfcc.cpp \
|
|
||||||
src/main.cpp \
|
src/main.cpp \
|
||||||
src/mfcc.cpp \
|
src/mfcc.cpp \
|
||||||
src/renderer.cpp \
|
src/renderer.cpp \
|
||||||
src/aquila/filter/MelFilterBank.cpp \
|
src/aquila/filter/MelFilterBank.cpp \
|
||||||
src/aquila/filter/MelFilter.cpp \
|
src/aquila/filter/MelFilter.cpp \
|
||||||
src/aquila/transform/Dct.cpp \
|
src/aquila/transform/Dct.cpp \
|
||||||
src/renderer.cpp
|
|
||||||
|
|
||||||
TARGET_SRCS := src/main.cpp
|
TARGET_SRCS := src/main.cpp
|
||||||
|
|
||||||
|
@ -4,4 +4,4 @@ make distclean
|
|||||||
autoheader
|
autoheader
|
||||||
# build configure
|
# build configure
|
||||||
autoconf configure.ac > 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 <assert.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include "libmfcc.h"
|
|
||||||
#include "block.h"
|
#include "block.h"
|
||||||
|
|
||||||
using namespace spiralcore;
|
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_pcm(pcm),
|
||||||
m_fft(pcm.get_length()),
|
m_fft(pcm.get_length()),
|
||||||
m_mfcc(MFCC_FILTERS),
|
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_mfcc_proc!=NULL);
|
||||||
assert(m_fftw!=NULL);
|
assert(m_fftw!=NULL);
|
||||||
|
|
||||||
enveloper(m_pcm,50,50);
|
enveloper(m_pcm,env,env);
|
||||||
|
|
||||||
m_fftw->impulse2freq(m_pcm.get_non_const_buffer());
|
m_fftw->impulse2freq(m_pcm.get_non_const_buffer());
|
||||||
|
|
||||||
@ -104,7 +103,7 @@ bool block::unit_test() {
|
|||||||
data[i]=i/(float)data.get_length();
|
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_pcm.get_length()==data.get_length());
|
||||||
//assert(bb.m_fft.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_rate==44100);
|
||||||
assert(bb.m_block_size==data.get_length());
|
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,1)==0);
|
||||||
assert(bb.compare(bb2,0)==0);
|
assert(bb.compare(bb2,0)==0);
|
||||||
assert(bb.compare(bb2,0.5)==0);
|
assert(bb.compare(bb2,0.5)==0);
|
||||||
@ -123,13 +122,13 @@ bool block::unit_test() {
|
|||||||
data[i]=i%10;
|
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,1)!=0);
|
||||||
assert(bb.compare(bb3,0)!=0);
|
assert(bb.compare(bb3,0)!=0);
|
||||||
assert(bb.compare(bb3,0.5)!=0);
|
assert(bb.compare(bb3,0.5)!=0);
|
||||||
cpy=bb3;
|
cpy=bb3;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(cpy.m_pcm.get_length()==200);
|
assert(cpy.m_pcm.get_length()==200);
|
||||||
|
@ -12,7 +12,7 @@ namespace spiralcore {
|
|||||||
class block {
|
class block {
|
||||||
public:
|
public:
|
||||||
// runs analysis on pcm
|
// 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
|
// returns distance based on ratio of fft-mfcc values
|
||||||
double compare(const block &other, float ratio) const;
|
double compare(const block &other, float ratio) const;
|
||||||
|
@ -38,23 +38,23 @@ void save_sample(const string &filename, const sample s) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// rewrites whole brain
|
// 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_blocks.clear();
|
||||||
m_block_size = block_size;
|
m_block_size = block_size;
|
||||||
m_overlap = overlap;
|
m_overlap = overlap;
|
||||||
for (vector<sample>::iterator i=m_samples.begin(); i!=m_samples.end(); ++i) {
|
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;
|
u32 pos=0;
|
||||||
while (pos+block_size-1<s.get_length()) {
|
while (pos+block_size-1<s.get_length()) {
|
||||||
cerr<<'\r';
|
cerr<<'\r';
|
||||||
cerr<<"adding: "<<pos/(float)s.get_length()*100;
|
cerr<<"adding: "<<pos/(float)s.get_length()*100;
|
||||||
sample region;
|
sample region;
|
||||||
s.get_region(region,pos,pos+block_size-1);
|
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);
|
pos += (block_size-overlap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -123,13 +123,13 @@ bool brain::unit_test() {
|
|||||||
assert(b.m_samples.size()==2);
|
assert(b.m_samples.size()==2);
|
||||||
assert(s.get_length()==100);
|
assert(s.get_length()==100);
|
||||||
|
|
||||||
b.init(10, 0);
|
b.init(10, 0, 0);
|
||||||
assert(b.m_samples.size()==2);
|
assert(b.m_samples.size()==2);
|
||||||
assert(b.m_blocks.size()==20);
|
assert(b.m_blocks.size()==20);
|
||||||
b.init(10, 5);
|
b.init(10, 5, 0);
|
||||||
assert(b.m_samples.size()==2);
|
assert(b.m_samples.size()==2);
|
||||||
assert(b.m_blocks.size()==38);
|
assert(b.m_blocks.size()==38);
|
||||||
b.init(20, 5);
|
b.init(20, 5, 0);
|
||||||
assert(b.m_samples.size()==2);
|
assert(b.m_samples.size()==2);
|
||||||
assert(b.m_blocks.size()==12);
|
assert(b.m_blocks.size()==12);
|
||||||
|
|
||||||
@ -139,8 +139,8 @@ bool brain::unit_test() {
|
|||||||
brain b3;
|
brain b3;
|
||||||
b3.load_sound("test_data/up.wav");
|
b3.load_sound("test_data/up.wav");
|
||||||
|
|
||||||
b2.init(512, 0);
|
b2.init(512, 0, 20);
|
||||||
b3.init(512, 0);
|
b3.init(512, 0, 20);
|
||||||
assert(b3.search(b2.m_blocks[0],1)==0);
|
assert(b3.search(b2.m_blocks[0],1)==0);
|
||||||
assert(b3.search(b2.m_blocks[9],1)==9);
|
assert(b3.search(b2.m_blocks[9],1)==9);
|
||||||
assert(b3.search(b2.m_blocks[19],1)==19);
|
assert(b3.search(b2.m_blocks[19],1)==19);
|
||||||
|
@ -14,7 +14,7 @@ public:
|
|||||||
brain();
|
brain();
|
||||||
|
|
||||||
// rewrites whole 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
|
// load, chop up and add to brain
|
||||||
// todo: add tags
|
// todo: add tags
|
||||||
@ -25,6 +25,7 @@ public:
|
|||||||
|
|
||||||
const sample &get_block_pcm(u32 index) const;
|
const sample &get_block_pcm(u32 index) const;
|
||||||
const block &get_block(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_block_size() const { return m_block_size; }
|
||||||
const u32 get_overlap() const { return m_overlap; }
|
const u32 get_overlap() const { return m_overlap; }
|
||||||
|
|
||||||
@ -34,7 +35,7 @@ public:
|
|||||||
|
|
||||||
private:
|
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<block> m_blocks;
|
||||||
vector<sample> m_samples;
|
vector<sample> m_samples;
|
||||||
|
@ -53,20 +53,21 @@ void run_audio(void* c, unsigned int frames) {
|
|||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
// unit_test();
|
unit_test();
|
||||||
|
|
||||||
cerr<<"starting"<<endl;
|
cerr<<"starting"<<endl;
|
||||||
brain source, target;
|
brain source, target;
|
||||||
source.load_sound("../sound/source/shostakovich6.wav");
|
// source.load_sound("../sound/source/shostakovich6.wav");
|
||||||
// source.load_sound("../sound/source/808.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/sb-left.wav");
|
||||||
|
target.load_sound("../sound/source/apache.wav");
|
||||||
cerr<<"loaded sounds"<<endl;
|
cerr<<"loaded sounds"<<endl;
|
||||||
|
|
||||||
u32 len=3000;
|
u32 len=1024;
|
||||||
source.init(len,len-len);
|
source.init(len,len-len,50);
|
||||||
target.init(len,len-len/2);
|
target.init(len,len-len/4,50);
|
||||||
cerr<<"ready..."<<endl;
|
cerr<<"ready..."<<endl;
|
||||||
|
|
||||||
a = new audio_device("samplebrain",44100,2048);
|
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) {
|
void renderer::process(u32 nframes, float *buf) {
|
||||||
// get blocks from source for the current buffer
|
// 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_shift = m_target.get_block_size()-m_target.get_overlap();
|
||||||
|
|
||||||
u32 tgt_start = m_render_time/(float)tgt_shift;
|
u32 tgt_start = m_render_time/(float)tgt_shift;
|
||||||
u32 tgt_end = (m_render_time+nframes)/(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
|
// 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 time=tgt_index*tgt_shift;
|
||||||
u32 src_index = m_source.search(m_target.get_block(tgt_index), m_ratio);
|
u32 src_index = m_source.search(m_target.get_block(tgt_index), m_ratio);
|
||||||
// put them in the index list
|
// 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;
|
s32 offset = i->m_time-m_render_time;
|
||||||
|
|
||||||
// assume midway through block
|
// assume midway through block
|
||||||
s32 block_start = offset;
|
u32 block_start = offset;
|
||||||
u32 buffer_start = 0;
|
u32 buffer_start = 0;
|
||||||
if (block_start<0) {
|
if (offset<0) {
|
||||||
block_start=-block_start;
|
block_start=-offset;
|
||||||
if (block_start>=pcm.get_length()) i->m_finished=true;
|
if (block_start>=pcm.get_length()) i->m_finished=true;
|
||||||
} else { // block is midway through buffer
|
} else { // block is midway through buffer
|
||||||
block_start=0;
|
block_start=0;
|
||||||
buffer_start=offset;
|
buffer_start=offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// cerr<<"-----------------"<<endl;
|
||||||
|
// cerr<<"block start:"<<block_start<<endl;
|
||||||
|
// cerr<<"buffer start:"<<buffer_start<<endl;
|
||||||
|
|
||||||
if (!i->m_finished) {
|
if (!i->m_finished) {
|
||||||
// mix in
|
// mix in
|
||||||
u32 buffer_pos = buffer_start;
|
u32 buffer_pos = buffer_start;
|
||||||
u32 block_pos = block_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) {
|
while (block_pos<block_end && buffer_pos<nframes) {
|
||||||
buf[buffer_pos]+=pcm[block_pos];
|
buf[buffer_pos]+=pcm[block_pos]*0.2;
|
||||||
++buffer_pos;
|
++buffer_pos;
|
||||||
++block_pos;
|
++block_pos;
|
||||||
}
|
}
|
||||||
@ -75,26 +86,26 @@ void renderer::process(u32 nframes, float *buf) {
|
|||||||
bool renderer::unit_test() {
|
bool renderer::unit_test() {
|
||||||
brain source;
|
brain source;
|
||||||
source.load_sound("test_data/up.wav");
|
source.load_sound("test_data/up.wav");
|
||||||
source.init(10,0);
|
source.init(10,0,0);
|
||||||
|
|
||||||
brain target;
|
brain target;
|
||||||
target.load_sound("test_data/up.wav");
|
target.load_sound("test_data/up.wav");
|
||||||
target.init(10,0);
|
target.init(10,0,0);
|
||||||
|
|
||||||
renderer rr(source,target,1);
|
renderer rr(source,target,1);
|
||||||
float *buf=new float[10];
|
float *buf=new float[10];
|
||||||
rr.process(5,buf);
|
|
||||||
assert(rr.m_render_blocks.size()==1);
|
|
||||||
rr.process(10,buf);
|
rr.process(10,buf);
|
||||||
assert(rr.m_render_blocks.size()==1);
|
|
||||||
rr.process(20,buf);
|
|
||||||
assert(rr.m_render_blocks.size()==2);
|
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);
|
rr.process(10,buf);
|
||||||
|
assert(rr.m_render_blocks.size()==3);
|
||||||
|
rr.process(20,buf);
|
||||||
assert(rr.m_render_blocks.size()==4);
|
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