From 9ed6fd3e3ddb7dbaa77b38a558550ea0893247b5 Mon Sep 17 00:00:00 2001 From: Dave Griffiths Date: Wed, 8 Jul 2015 10:24:02 +0100 Subject: [PATCH] some working tests, some segfaults --- samplebrain/configure | 39 ++++++++++++ samplebrain/configure.ac | 1 + samplebrain/src/brain.cpp | 103 ++++++++++++++++++++++++++++++++ samplebrain/src/brain.h | 30 ++++++++-- samplebrain/src/brain_block.cpp | 75 +++++++++++++++++++++-- samplebrain/src/brain_block.h | 19 ++++-- samplebrain/src/config.h.in | 36 ++--------- samplebrain/src/fft.cpp | 7 +++ samplebrain/src/fft.h | 10 ++++ samplebrain/src/main.cpp | 12 +++- 10 files changed, 287 insertions(+), 45 deletions(-) diff --git a/samplebrain/configure b/samplebrain/configure index abb77dd..916006f 100755 --- a/samplebrain/configure +++ b/samplebrain/configure @@ -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' diff --git a/samplebrain/configure.ac b/samplebrain/configure.ac index c31454d..f5ccea2 100644 --- a/samplebrain/configure.ac +++ b/samplebrain/configure.ac @@ -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++) diff --git a/samplebrain/src/brain.cpp b/samplebrain/src/brain.cpp index e69de29..50bb5dd 100644 --- a/samplebrain/src/brain.cpp +++ b/samplebrain/src/brain.cpp @@ -0,0 +1,103 @@ +#include +#include +#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::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::iterator i=m_blocks.begin(); i!=m_blocks.end(); ++i) { + double diff = target.compare(*i,ratio); + if (diff -#include "sample.h" -#include "fft.h" +#include +#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 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 m_blocks; + vector m_samples; }; + +#endif + +} diff --git a/samplebrain/src/brain_block.cpp b/samplebrain/src/brain_block.cpp index 0024320..ff25ce7 100644 --- a/samplebrain/src/brain_block.cpp +++ b/samplebrain/src/brain_block.cpp @@ -1,19 +1,44 @@ +#include +#include + +#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; im_in[i] = m_pcm[i]; + } + m_fftw->raw_impulse2freq(); + double *spectrum = new double[m_block_size]; + for (u32 i=0; im_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 +#include #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 diff --git a/samplebrain/src/config.h.in b/samplebrain/src/config.h.in index 1f86776..992fc22 100644 --- a/samplebrain/src/config.h.in +++ b/samplebrain/src/config.h.in @@ -6,44 +6,20 @@ /* Define to 1 if you have the 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 header file. */ #undef HAVE_MEMORY_H diff --git a/samplebrain/src/fft.cpp b/samplebrain/src/fft.cpp index 372f07f..ef82cf5 100644 --- a/samplebrain/src/fft.cpp +++ b/samplebrain/src/fft.cpp @@ -1,5 +1,7 @@ #include +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); +} diff --git a/samplebrain/src/fft.h b/samplebrain/src/fft.h index 936dc35..046a40b 100644 --- a/samplebrain/src/fft.h +++ b/samplebrain/src/fft.h @@ -1,13 +1,19 @@ #include +#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 diff --git a/samplebrain/src/main.cpp b/samplebrain/src/main.cpp index 5228b32..f1dba0d 100644 --- a/samplebrain/src/main.cpp +++ b/samplebrain/src/main.cpp @@ -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"<