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
|
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_ext=cpp
|
||||||
ac_cpp='$CXXCPP $CPPFLAGS'
|
ac_cpp='$CXXCPP $CPPFLAGS'
|
||||||
|
@ -5,6 +5,7 @@ AC_CHECK_LIB(m, cos)
|
|||||||
AC_CHECK_LIB(fftw3, main)
|
AC_CHECK_LIB(fftw3, main)
|
||||||
AC_CHECK_LIB(portaudio, main)
|
AC_CHECK_LIB(portaudio, main)
|
||||||
AC_CHECK_LIB(jellyfish, main)
|
AC_CHECK_LIB(jellyfish, main)
|
||||||
|
AC_CHECK_LIB(sndfile, main)
|
||||||
|
|
||||||
AC_PROG_CXX
|
AC_PROG_CXX
|
||||||
AC_LANG(C++)
|
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 <vector>
|
||||||
#include "sample.h"
|
#include <string>
|
||||||
#include "fft.h"
|
#include "jellyfish/core/types.h"
|
||||||
|
#include "jellyfish/fluxa/sample.h"
|
||||||
|
#include "brain_block.h"
|
||||||
|
|
||||||
|
#ifndef BRAIN
|
||||||
|
#define BRAIN
|
||||||
|
|
||||||
|
namespace spiralcore {
|
||||||
|
|
||||||
class brain {
|
class brain {
|
||||||
public:
|
public:
|
||||||
@ -9,15 +16,26 @@ public:
|
|||||||
// rewrites whole brain
|
// rewrites whole brain
|
||||||
void init(u32 block_size, u32 overlap);
|
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
|
// take another brain and rebuild this brain from bits of that one
|
||||||
// (presumably this one is made from a single sample)
|
// (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:
|
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;
|
vector<brain_block> m_blocks;
|
||||||
u32 m_overlap;
|
vector<sample> m_samples;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
@ -1,19 +1,44 @@
|
|||||||
|
#include <assert.h>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "libmfcc.h"
|
||||||
#include "brain_block.h"
|
#include "brain_block.h"
|
||||||
|
|
||||||
|
using namespace spiralcore;
|
||||||
|
|
||||||
FFT *brain_block::m_fftw;
|
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_pcm(pcm),
|
||||||
m_fft(pcm.get_length()),
|
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());
|
init_fft(m_pcm.get_length());
|
||||||
|
|
||||||
m_fft = m_fftw(impulse2freq(m_pcm.get_non_const_buffer(),
|
for (u32 i=0; i<m_block_size; i++) {
|
||||||
m_fft.get_non_const_buffer())
|
// 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)
|
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);
|
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/fluxa/sample.h"
|
||||||
#include "jellyfish/core/types.h"
|
#include "jellyfish/core/types.h"
|
||||||
#include "fft.h"
|
#include "fft.h"
|
||||||
|
|
||||||
using namespace spiralcore;
|
#ifndef BRAIN_BLOCK
|
||||||
|
#define BRAIN_BLOCK
|
||||||
|
|
||||||
|
namespace spiralcore {
|
||||||
|
|
||||||
class brain_block {
|
class brain_block {
|
||||||
public:
|
public:
|
||||||
// runs analysis on pcm
|
// 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
|
// 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 void init_fft(u32 block_size);
|
||||||
|
static bool unit_test();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
sample m_pcm;
|
sample m_pcm;
|
||||||
sample m_fft;
|
sample m_fft;
|
||||||
sample m_mfcc;
|
sample m_mfcc;
|
||||||
|
|
||||||
|
u32 m_block_size;
|
||||||
|
u32 m_rate;
|
||||||
|
std::string m_orig_filename;
|
||||||
static FFT *m_fftw;
|
static FFT *m_fftw;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
@ -6,44 +6,20 @@
|
|||||||
/* Define to 1 if you have the <iostream> header file. */
|
/* Define to 1 if you have the <iostream> header file. */
|
||||||
#undef HAVE_IOSTREAM
|
#undef HAVE_IOSTREAM
|
||||||
|
|
||||||
/* Define to 1 if you have the `bcm_host' library (-lbcm_host). */
|
/* Define to 1 if you have the `fftw3' library (-lfftw3). */
|
||||||
#undef HAVE_LIBBCM_HOST
|
#undef HAVE_LIBFFTW3
|
||||||
|
|
||||||
/* Define to 1 if you have the `dl' library (-ldl). */
|
/* Define to 1 if you have the `jellyfish' library (-ljellyfish). */
|
||||||
#undef HAVE_LIBDL
|
#undef HAVE_LIBJELLYFISH
|
||||||
|
|
||||||
/* 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 `m' library (-lm). */
|
/* Define to 1 if you have the `m' library (-lm). */
|
||||||
#undef HAVE_LIBM
|
#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). */
|
/* Define to 1 if you have the `portaudio' library (-lportaudio). */
|
||||||
#undef HAVE_LIBPORTAUDIO
|
#undef HAVE_LIBPORTAUDIO
|
||||||
|
|
||||||
/* Define to 1 if you have the `pthread' library (-lpthread). */
|
/* Define to 1 if you have the `sndfile' library (-lsndfile). */
|
||||||
#undef HAVE_LIBPTHREAD
|
#undef HAVE_LIBSNDFILE
|
||||||
|
|
||||||
/* Define to 1 if you have the `X11' library (-lX11). */
|
|
||||||
#undef HAVE_LIBX11
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <memory.h> header file. */
|
/* Define to 1 if you have the <memory.h> header file. */
|
||||||
#undef HAVE_MEMORY_H
|
#undef HAVE_MEMORY_H
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
#include <fft.h>
|
#include <fft.h>
|
||||||
|
|
||||||
|
using namespace spiralcore;
|
||||||
|
|
||||||
static const int MAX_FFT_LENGTH = 4096;
|
static const int MAX_FFT_LENGTH = 4096;
|
||||||
|
|
||||||
FFT::FFT(int length) :
|
FFT::FFT(int length) :
|
||||||
@ -52,3 +54,8 @@ void FFT::impulse2freq(float *imp, float *out)
|
|||||||
out[i] = m_spectrum[i][0];
|
out[i] = m_spectrum[i][0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FFT::raw_impulse2freq()
|
||||||
|
{
|
||||||
|
fftw_execute(m_plan);
|
||||||
|
}
|
||||||
|
@ -1,13 +1,19 @@
|
|||||||
#include <fftw3.h>
|
#include <fftw3.h>
|
||||||
|
|
||||||
|
#ifndef SPIRALCORE_FFT
|
||||||
|
#define SPIRALCORE_FFT
|
||||||
|
|
||||||
//#define __FFTWFLOAT__
|
//#define __FFTWFLOAT__
|
||||||
|
|
||||||
|
namespace spiralcore {
|
||||||
|
|
||||||
class FFT
|
class FFT
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FFT(int length);
|
FFT(int length);
|
||||||
~FFT();
|
~FFT();
|
||||||
void impulse2freq(float *imp, float *out);
|
void impulse2freq(float *imp, float *out);
|
||||||
|
void raw_impulse2freq();
|
||||||
|
|
||||||
#ifndef __FFTWFLOAT__
|
#ifndef __FFTWFLOAT__
|
||||||
fftw_plan m_plan;
|
fftw_plan m_plan;
|
||||||
@ -21,3 +27,7 @@ public:
|
|||||||
fftwf_complex *m_spectrum;
|
fftwf_complex *m_spectrum;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
@ -20,9 +20,19 @@
|
|||||||
|
|
||||||
#include "jellyfish/audio.h"
|
#include "jellyfish/audio.h"
|
||||||
|
|
||||||
|
#include "brain_block.h"
|
||||||
|
#include "brain.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
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