mirror of
https://gitlab.com/then-try-this/samplebrain.git
synced 2025-05-12 10:37:20 +00:00
some working tests, some segfaults
This commit is contained in:
parent
20ff4e5f52
commit
9ed6fd3e3d
39
samplebrain/configure
vendored
39
samplebrain/configure
vendored
@ -2990,6 +2990,45 @@ _ACEOF
|
||||
|
||||
fi
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lsndfile" >&5
|
||||
$as_echo_n "checking for main in -lsndfile... " >&6; }
|
||||
if ${ac_cv_lib_sndfile_main+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
ac_check_lib_save_LIBS=$LIBS
|
||||
LIBS="-lsndfile $LIBS"
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
return main ();
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"; then :
|
||||
ac_cv_lib_sndfile_main=yes
|
||||
else
|
||||
ac_cv_lib_sndfile_main=no
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
LIBS=$ac_check_lib_save_LIBS
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sndfile_main" >&5
|
||||
$as_echo "$ac_cv_lib_sndfile_main" >&6; }
|
||||
if test "x$ac_cv_lib_sndfile_main" = xyes; then :
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define HAVE_LIBSNDFILE 1
|
||||
_ACEOF
|
||||
|
||||
LIBS="-lsndfile $LIBS"
|
||||
|
||||
fi
|
||||
|
||||
|
||||
ac_ext=cpp
|
||||
ac_cpp='$CXXCPP $CPPFLAGS'
|
||||
|
@ -5,6 +5,7 @@ AC_CHECK_LIB(m, cos)
|
||||
AC_CHECK_LIB(fftw3, main)
|
||||
AC_CHECK_LIB(portaudio, main)
|
||||
AC_CHECK_LIB(jellyfish, main)
|
||||
AC_CHECK_LIB(sndfile, main)
|
||||
|
||||
AC_PROG_CXX
|
||||
AC_LANG(C++)
|
||||
|
@ -0,0 +1,103 @@
|
||||
#include <iostream>
|
||||
#include <sndfile.h>
|
||||
#include "brain.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace spiralcore;
|
||||
|
||||
brain::brain()
|
||||
{
|
||||
}
|
||||
|
||||
// load, chop up and add to brain
|
||||
// todo: add tags
|
||||
sample brain::load_sound(std::string filename) {
|
||||
SF_INFO sfinfo;
|
||||
sfinfo.format=0;
|
||||
SNDFILE* f=sf_open(filename.c_str(), SFM_READ, &sfinfo);
|
||||
sample s(sfinfo.frames);
|
||||
sf_read_float(f, s.get_non_const_buffer(), s.get_length());
|
||||
sf_close(f);
|
||||
m_samples.push_back(s);
|
||||
return s;
|
||||
}
|
||||
|
||||
// rewrites whole brain
|
||||
void brain::init(u32 block_size, u32 overlap) {
|
||||
m_blocks.clear();
|
||||
for (vector<sample>::iterator i=m_samples.begin(); i!=m_samples.end(); ++i) {
|
||||
chop_and_add(*i, block_size, overlap);
|
||||
}
|
||||
}
|
||||
|
||||
void brain::chop_and_add(const sample &s, u32 block_size, u32 overlap) {
|
||||
u32 pos=0;
|
||||
while (pos+block_size-1<s.get_length()) {
|
||||
sample region;
|
||||
s.get_region(region,pos,pos+block_size-1);
|
||||
m_blocks.push_back(brain_block("",region,44100));
|
||||
pos += block_size-overlap;
|
||||
}
|
||||
}
|
||||
|
||||
// returns index to block
|
||||
u32 brain::search(const brain_block &target, float ratio) {
|
||||
double closest = 999999999;
|
||||
u32 closest_index = 0;
|
||||
u32 index = 0;
|
||||
for (vector<brain_block>::iterator i=m_blocks.begin(); i!=m_blocks.end(); ++i) {
|
||||
double diff = target.compare(*i,ratio);
|
||||
if (diff<closest) {
|
||||
closest=diff;
|
||||
closest_index = index;
|
||||
}
|
||||
++index;
|
||||
}
|
||||
return closest_index;
|
||||
}
|
||||
|
||||
// take another brain and rebuild this brain from bits of that one
|
||||
// (presumably this one is made from a single sample)
|
||||
sample brain::resynth(const brain &other, float ratio){
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool brain::unit_test() {
|
||||
brain b;
|
||||
assert(b.m_samples.size()==0);
|
||||
assert(b.m_blocks.size()==0);
|
||||
|
||||
sample s=b.load_sound("test_data/100f32.wav");
|
||||
assert(b.m_samples.size()==1);
|
||||
assert(s.get_length()==100);
|
||||
|
||||
s=b.load_sound("test_data/100i16.wav");
|
||||
assert(b.m_samples.size()==2);
|
||||
assert(s.get_length()==100);
|
||||
|
||||
b.init(10, 0);
|
||||
assert(b.m_samples.size()==2);
|
||||
assert(b.m_blocks.size()==20);
|
||||
b.init(10, 5);
|
||||
assert(b.m_samples.size()==2);
|
||||
assert(b.m_blocks.size()==38);
|
||||
b.init(20, 5);
|
||||
assert(b.m_samples.size()==2);
|
||||
assert(b.m_blocks.size()==12);
|
||||
|
||||
// replicate brain
|
||||
brain b2;
|
||||
b2.load_sound("test_data/100f32.wav");
|
||||
b2.load_sound("test_data/100f32.wav");
|
||||
assert(b.m_samples.size()==2);
|
||||
b.init(10, 0);
|
||||
assert(b.m_blocks.size()==20);
|
||||
|
||||
assert(b.search(b2.m_blocks[0],1)==0);
|
||||
assert(b.search(b2.m_blocks[19],1)==19);
|
||||
|
||||
|
||||
return true;
|
||||
}
|
@ -1,6 +1,13 @@
|
||||
#include <vector>
|
||||
#include "sample.h"
|
||||
#include "fft.h"
|
||||
#include <string>
|
||||
#include "jellyfish/core/types.h"
|
||||
#include "jellyfish/fluxa/sample.h"
|
||||
#include "brain_block.h"
|
||||
|
||||
#ifndef BRAIN
|
||||
#define BRAIN
|
||||
|
||||
namespace spiralcore {
|
||||
|
||||
class brain {
|
||||
public:
|
||||
@ -9,15 +16,26 @@ public:
|
||||
// rewrites whole brain
|
||||
void init(u32 block_size, u32 overlap);
|
||||
|
||||
// load, chop up and add to brain
|
||||
// todo: add tags
|
||||
sample load_sound(std::string filename);
|
||||
|
||||
// take another brain and rebuild this brain from bits of that one
|
||||
// (presumably this one is made from a single sample)
|
||||
sample resynth(const sample_brain *other, ratio);
|
||||
sample resynth(const brain &other, float ratio);
|
||||
|
||||
static bool unit_test();
|
||||
|
||||
private:
|
||||
|
||||
vector<brain_block> m_blocks;
|
||||
u32 search(const brain_block &target, float ratio);
|
||||
void chop_and_add(const sample &s, u32 block_size, u32 overlap);
|
||||
|
||||
u32 m_block_size;
|
||||
u32 m_overlap;
|
||||
vector<brain_block> m_blocks;
|
||||
vector<sample> m_samples;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
@ -1,19 +1,44 @@
|
||||
#include <assert.h>
|
||||
#include <iostream>
|
||||
|
||||
#include "libmfcc.h"
|
||||
#include "brain_block.h"
|
||||
|
||||
using namespace spiralcore;
|
||||
|
||||
FFT *brain_block::m_fftw;
|
||||
|
||||
brain_block::brain_block(const sample &pcm) :
|
||||
brain_block::brain_block(const string &filename, const sample &pcm, u32 rate) :
|
||||
m_pcm(pcm),
|
||||
m_fft(pcm.get_length()),
|
||||
m_mfcc(13)
|
||||
m_mfcc(13),
|
||||
m_block_size(pcm.get_length()),
|
||||
m_rate(rate),
|
||||
m_orig_filename(filename)
|
||||
{
|
||||
init_fft(m_pcm.get_length());
|
||||
|
||||
m_fft = m_fftw(impulse2freq(m_pcm.get_non_const_buffer(),
|
||||
m_fft.get_non_const_buffer())
|
||||
for (u32 i=0; i<m_block_size; i++) {
|
||||
// convert from float to double
|
||||
m_fftw->m_in[i] = m_pcm[i];
|
||||
}
|
||||
|
||||
m_fftw->raw_impulse2freq();
|
||||
|
||||
double *spectrum = new double[m_block_size];
|
||||
|
||||
for (u32 i=0; i<m_block_size; i++) {
|
||||
// convert from complex to float for storage
|
||||
m_fft[i] = m_fftw->m_spectrum[i][0];
|
||||
// convert from complex to double for mfcc calc
|
||||
spectrum[i] = m_fftw->m_spectrum[i][0];
|
||||
}
|
||||
|
||||
for (u32 i=0; i<13; i++) {
|
||||
m_mfcc[i] = GetCoefficient(spectrum, rate, 48, m_block_size, i);
|
||||
}
|
||||
|
||||
delete[] spectrum;
|
||||
}
|
||||
|
||||
void brain_block::init_fft(u32 block_size)
|
||||
@ -23,3 +48,45 @@ void brain_block::init_fft(u32 block_size)
|
||||
m_fftw = new FFT(block_size);
|
||||
}
|
||||
}
|
||||
|
||||
double brain_block::compare(const brain_block &other, float ratio) const {
|
||||
double acc=0;
|
||||
// just mfcc
|
||||
//if (ratio==1)
|
||||
{
|
||||
for (u32 i=0; i<13; ++i) {
|
||||
acc+=(m_mfcc[i]-other.m_mfcc[i]) * (m_mfcc[i]-other.m_mfcc[i]);
|
||||
}
|
||||
}
|
||||
return acc;
|
||||
}
|
||||
|
||||
|
||||
bool brain_block::unit_test() {
|
||||
sample data(20);
|
||||
for (u32 i=0; i<data.get_length(); i++) {
|
||||
data[i]=i/(float)data.get_length();
|
||||
}
|
||||
|
||||
brain_block bb("test",data,44100);
|
||||
|
||||
assert(bb.m_pcm.get_length()==data.get_length());
|
||||
assert(bb.m_fft.get_length()==data.get_length());
|
||||
assert(bb.m_mfcc.get_length()==13);
|
||||
assert(bb.m_orig_filename==string("test"));
|
||||
assert(bb.m_rate==44100);
|
||||
assert(bb.m_block_size==data.get_length());
|
||||
|
||||
brain_block bb2("test",data,44100);
|
||||
assert(bb.compare(bb2,1)==0);
|
||||
|
||||
sample data2(20);
|
||||
for (u32 i=0; i<data.get_length(); i++) {
|
||||
data[i]=i;
|
||||
}
|
||||
|
||||
brain_block bb3("test",data2,44100);
|
||||
assert(bb.compare(bb3,1)!=0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -1,25 +1,36 @@
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include "jellyfish/fluxa/sample.h"
|
||||
#include "jellyfish/core/types.h"
|
||||
#include "fft.h"
|
||||
|
||||
using namespace spiralcore;
|
||||
#ifndef BRAIN_BLOCK
|
||||
#define BRAIN_BLOCK
|
||||
|
||||
namespace spiralcore {
|
||||
|
||||
class brain_block {
|
||||
public:
|
||||
// runs analysis on pcm
|
||||
brain_block(const sample &pcm);
|
||||
brain_block(const std::string &filename, const sample &pcm, u32 rate);
|
||||
|
||||
// returns distance based on ratio of fft-mfcc values
|
||||
float compare(const brain_block &other, float ratio);
|
||||
double compare(const brain_block &other, float ratio) const;
|
||||
|
||||
static void init_fft(u32 block_size);
|
||||
static bool unit_test();
|
||||
|
||||
private:
|
||||
sample m_pcm;
|
||||
sample m_fft;
|
||||
sample m_mfcc;
|
||||
|
||||
u32 m_block_size;
|
||||
u32 m_rate;
|
||||
std::string m_orig_filename;
|
||||
static FFT *m_fftw;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -6,44 +6,20 @@
|
||||
/* Define to 1 if you have the <iostream> header file. */
|
||||
#undef HAVE_IOSTREAM
|
||||
|
||||
/* Define to 1 if you have the `bcm_host' library (-lbcm_host). */
|
||||
#undef HAVE_LIBBCM_HOST
|
||||
/* Define to 1 if you have the `fftw3' library (-lfftw3). */
|
||||
#undef HAVE_LIBFFTW3
|
||||
|
||||
/* Define to 1 if you have the `dl' library (-ldl). */
|
||||
#undef HAVE_LIBDL
|
||||
|
||||
/* Define to 1 if you have the `EGL' library (-lEGL). */
|
||||
#undef HAVE_LIBEGL
|
||||
|
||||
/* Define to 1 if you have the `GL' library (-lGL). */
|
||||
#undef HAVE_LIBGL
|
||||
|
||||
/* Define to 1 if you have the `GLESv1_CM' library (-lGLESv1_CM). */
|
||||
#undef HAVE_LIBGLESV1_CM
|
||||
|
||||
/* Define to 1 if you have the `glut' library (-lglut). */
|
||||
#undef HAVE_LIBGLUT
|
||||
|
||||
/* Define to 1 if you have the `jpeg' library (-ljpeg). */
|
||||
#undef HAVE_LIBJPEG
|
||||
|
||||
/* Define to 1 if you have the `lo' library (-llo). */
|
||||
#undef HAVE_LIBLO
|
||||
/* Define to 1 if you have the `jellyfish' library (-ljellyfish). */
|
||||
#undef HAVE_LIBJELLYFISH
|
||||
|
||||
/* Define to 1 if you have the `m' library (-lm). */
|
||||
#undef HAVE_LIBM
|
||||
|
||||
/* Define to 1 if you have the `png' library (-lpng). */
|
||||
#undef HAVE_LIBPNG
|
||||
|
||||
/* Define to 1 if you have the `portaudio' library (-lportaudio). */
|
||||
#undef HAVE_LIBPORTAUDIO
|
||||
|
||||
/* Define to 1 if you have the `pthread' library (-lpthread). */
|
||||
#undef HAVE_LIBPTHREAD
|
||||
|
||||
/* Define to 1 if you have the `X11' library (-lX11). */
|
||||
#undef HAVE_LIBX11
|
||||
/* Define to 1 if you have the `sndfile' library (-lsndfile). */
|
||||
#undef HAVE_LIBSNDFILE
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#undef HAVE_MEMORY_H
|
||||
|
@ -1,5 +1,7 @@
|
||||
#include <fft.h>
|
||||
|
||||
using namespace spiralcore;
|
||||
|
||||
static const int MAX_FFT_LENGTH = 4096;
|
||||
|
||||
FFT::FFT(int length) :
|
||||
@ -52,3 +54,8 @@ void FFT::impulse2freq(float *imp, float *out)
|
||||
out[i] = m_spectrum[i][0];
|
||||
}
|
||||
}
|
||||
|
||||
void FFT::raw_impulse2freq()
|
||||
{
|
||||
fftw_execute(m_plan);
|
||||
}
|
||||
|
@ -1,13 +1,19 @@
|
||||
#include <fftw3.h>
|
||||
|
||||
#ifndef SPIRALCORE_FFT
|
||||
#define SPIRALCORE_FFT
|
||||
|
||||
//#define __FFTWFLOAT__
|
||||
|
||||
namespace spiralcore {
|
||||
|
||||
class FFT
|
||||
{
|
||||
public:
|
||||
FFT(int length);
|
||||
~FFT();
|
||||
void impulse2freq(float *imp, float *out);
|
||||
void raw_impulse2freq();
|
||||
|
||||
#ifndef __FFTWFLOAT__
|
||||
fftw_plan m_plan;
|
||||
@ -21,3 +27,7 @@ public:
|
||||
fftwf_complex *m_spectrum;
|
||||
#endif
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -20,9 +20,19 @@
|
||||
|
||||
#include "jellyfish/audio.h"
|
||||
|
||||
#include "brain_block.h"
|
||||
#include "brain.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
audio_device *a = new audio_device("samplebrain",44100,2048);
|
||||
cerr<<"testing brain_block"<<endl;
|
||||
if (brain_block::unit_test()) cerr<<"passed"<<endl;
|
||||
else cerr<<"failed"<<endl;
|
||||
cerr<<"testing brain"<<endl;
|
||||
if (brain::unit_test()) cerr<<"passed"<<endl;
|
||||
else cerr<<"failed"<<endl;
|
||||
|
||||
//audio_device *a = new audio_device("samplebrain",44100,2048);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user