diff --git a/samplebrain/Makefile.in b/samplebrain/Makefile.in index f84305b..97208fd 100644 --- a/samplebrain/Makefile.in +++ b/samplebrain/Makefile.in @@ -1,15 +1,17 @@ TARGET := samplebrain TARGET_LIB := libsamplebrain.a -SRCS := src/fft.cpp \ - src/brain.cpp \ - src/brain_block.cpp \ - src/libmfcc.cpp \ - src/main.cpp \ - src/mfcc.cpp \ - src/aquila/filter/MelFilterBank.cpp \ - src/aquila/filter/MelFilter.cpp \ - src/aquila/transform/Dct.cpp +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 diff --git a/samplebrain/src/brain.cpp b/samplebrain/src/brain.cpp index 46a6022..c871bc7 100644 --- a/samplebrain/src/brain.cpp +++ b/samplebrain/src/brain.cpp @@ -54,7 +54,7 @@ void brain::chop_and_add(const sample &s, u32 block_size, u32 overlap, bool ditc cerr<<"adding: "<::const_iterator i=m_blocks.begin(); i!=m_blocks.end(); ++i) { + for (vector::const_iterator i=m_blocks.begin(); i!=m_blocks.end(); ++i) { double diff = target.compare(*i,ratio); if (diff::iterator i=m_blocks.begin(); i!=m_blocks.end(); ++i) { + for (vector::iterator i=m_blocks.begin(); i!=m_blocks.end(); ++i) { cerr<<'\r'; cerr<<"searching: "< #include "jellyfish/core/types.h" #include "jellyfish/fluxa/sample.h" -#include "brain_block.h" +#include "block.h" #ifndef BRAIN #define BRAIN @@ -24,11 +24,11 @@ public: void resynth(const std::string &filename, const brain &other, float ratio); const sample &get_block_pcm(u32 index) const; - const brain_block &get_block(u32 index) const; - const u32 &get_block_size() const { return m_block_size; } - const u32 &get_overlap() const { return m_overlap; } + const block &get_block(u32 index) const; + const u32 get_block_size() const { return m_block_size; } + const u32 get_overlap() const { return m_overlap; } - u32 search(const brain_block &target, float ratio) const; + u32 search(const block &target, float ratio) const; static bool unit_test(); @@ -36,7 +36,7 @@ private: void chop_and_add(const sample &s, u32 block_size, u32 overlap, bool ditchpcm=false); - vector m_blocks; + vector m_blocks; vector m_samples; u32 m_block_size; @@ -44,6 +44,6 @@ private: }; -#endif - } + +#endif diff --git a/samplebrain/src/brain_block.cpp b/samplebrain/src/brain_block.cpp deleted file mode 100644 index 4235c96..0000000 --- a/samplebrain/src/brain_block.cpp +++ /dev/null @@ -1,138 +0,0 @@ -#include -#include - -#include "libmfcc.h" -#include "brain_block.h" - -using namespace spiralcore; - -FFT *brain_block::m_fftw; -Aquila::Mfcc *brain_block::m_mfcc_proc; - -static const int MFCC_FILTERS=12; - -void enveloper(sample &s, u32 start, u32 end) { - for(u32 i=0; iimpulse2freq(m_pcm.get_non_const_buffer()); - - std::vector> mfspec; - - for (u32 i=0; im_spectrum[i][0]; - - mfspec.push_back(std::complex(m_fftw->m_spectrum[i][0], - m_fftw->m_spectrum[i][1])); - } - - if (m_block_size>100) m_fft.crop_to(100); - if (ditchpcm) m_pcm.clear(); - - // calculate mfcc - std::vector m = m_mfcc_proc->calculate(mfspec,MFCC_FILTERS); - - for (u32 i=0; im_length!=block_size) { - if (m_fftw == NULL) delete m_fftw; - m_fftw = new FFT(block_size); - if (m_mfcc_proc == NULL) delete m_mfcc_proc; - m_mfcc_proc = new Aquila::Mfcc(block_size); - } -} - -double brain_block::compare(const brain_block &other, float ratio) const { - double mfcc_acc=0; - double fft_acc=0; - - if (ratio==0) { - for (u32 i=0; i -#include "jellyfish/fluxa/sample.h" -#include "jellyfish/core/types.h" -#include "fft.h" -#include "mfcc.h" - -#ifndef BRAIN_BLOCK -#define BRAIN_BLOCK - -namespace spiralcore { - -class brain_block { -public: - // runs analysis on pcm - brain_block(const std::string &filename, const sample &pcm, u32 rate, bool ditchpcm=false); - - // returns distance based on ratio of fft-mfcc values - double compare(const brain_block &other, float ratio) const; - - static void init_fft(u32 block_size); - static bool unit_test(); - - const sample &get_pcm() const { return m_pcm; } - -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; - static Aquila::Mfcc *m_mfcc_proc; - -}; - -} - -#endif diff --git a/samplebrain/src/libmfcc.cpp b/samplebrain/src/libmfcc.cpp deleted file mode 100644 index 3efb14b..0000000 --- a/samplebrain/src/libmfcc.cpp +++ /dev/null @@ -1,165 +0,0 @@ -/* - * libmfcc.c - Code implementation for libMFCC - * Copyright (c) 2010 Jeremy Sawruk - * - * This code is released under the MIT License. - * For conditions of distribution and use, see the license in LICENSE - */ - -#include -#include "libmfcc.h" - -/* - * Computes the specified (mth) MFCC - * - * spectralData - array of mfcc_reals containing the results of FFT computation. This data is already assumed to be purely real - * samplingRate - the rate that the original time-series data was sampled at (i.e 44100) - * NumFilters - the number of filters to use in the computation. Recommended value = 48 - * binSize - the size of the spectralData array, usually a power of 2 - * m - The mth MFCC coefficient to compute - * - */ -mfcc_real GetCoefficient(mfcc_real* spectralData, unsigned int samplingRate, unsigned int NumFilters, unsigned int binSize, unsigned int m) -{ - mfcc_real result = 0.0f; - mfcc_real outerSum = 0.0f; - mfcc_real innerSum = 0.0f; - unsigned int k, l; - - // 0 <= m < L - if(m >= NumFilters) - { - // This represents an error condition - the specified coefficient is greater than or equal to the number of filters. The behavior in this case is undefined. - return 0.0f; - } - - result = NormalizationFactor(NumFilters, m); - - - for(l = 1; l <= NumFilters; l++) - { - // Compute inner sum - innerSum = 0.0f; - for(k = 0; k < binSize - 1; k++) - { - innerSum += fabs(spectralData[k] * GetFilterParameter(samplingRate, binSize, k, l)); - } - - if(innerSum > 0.0f) - { - innerSum = log(innerSum); // The log of 0 is undefined, so don't use it - } - - innerSum = innerSum * cos(((m * PI) / NumFilters) * (l - 0.5f)); - - outerSum += innerSum; - } - - result *= outerSum; - - return result; -} - -/* - * Computes the Normalization Factor (Equation 6) - * Used for internal computation only - not to be called directly - */ -mfcc_real NormalizationFactor(int NumFilters, int m) -{ - mfcc_real normalizationFactor = 0.0f; - - if(m == 0) - { - normalizationFactor = sqrt(1.0f / NumFilters); - } - else - { - normalizationFactor = sqrt(2.0f / NumFilters); - } - - return normalizationFactor; -} - -/* - * Compute the filter parameter for the specified frequency and filter bands (Eq. 2) - * Used for internal computation only - not the be called directly - */ -mfcc_real GetFilterParameter(unsigned int samplingRate, unsigned int binSize, unsigned int frequencyBand, unsigned int filterBand) -{ - mfcc_real filterParameter = 0.0f; - - mfcc_real boundary = (frequencyBand * samplingRate) / binSize; // k * Fs / N - mfcc_real prevCenterFrequency = GetCenterFrequency(filterBand - 1); // fc(l - 1) etc. - mfcc_real thisCenterFrequency = GetCenterFrequency(filterBand); - mfcc_real nextCenterFrequency = GetCenterFrequency(filterBand + 1); - - if(boundary >= 0 && boundary < prevCenterFrequency) - { - filterParameter = 0.0f; - } - else if(boundary >= prevCenterFrequency && boundary < thisCenterFrequency) - { - filterParameter = (boundary - prevCenterFrequency) / (thisCenterFrequency - prevCenterFrequency); - filterParameter *= GetMagnitudeFactor(filterBand); - } - else if(boundary >= thisCenterFrequency && boundary < nextCenterFrequency) - { - filterParameter = (boundary - nextCenterFrequency) / (thisCenterFrequency - nextCenterFrequency); - filterParameter *= GetMagnitudeFactor(filterBand); - } - else if(boundary >= nextCenterFrequency && boundary < samplingRate) - { - filterParameter = 0.0f; - } - - return filterParameter; -} - -/* - * Compute the band-dependent magnitude factor for the given filter band (Eq. 3) - * Used for internal computation only - not the be called directly - */ -mfcc_real GetMagnitudeFactor(unsigned int filterBand) -{ - mfcc_real magnitudeFactor = 0.0f; - - if(filterBand >= 1 && filterBand <= 14) - { - magnitudeFactor = 0.015; - } - else if(filterBand >= 15 && filterBand <= 48) - { - magnitudeFactor = 2.0f / (GetCenterFrequency(filterBand + 1) - GetCenterFrequency(filterBand -1)); - } - - return magnitudeFactor; -} - -/* - * Compute the center frequency (fc) of the specified filter band (l) (Eq. 4) - * This where the mel-frequency scaling occurs. Filters are specified so that their - * center frequencies are equally spaced on the mel scale - * Used for internal computation only - not the be called directly - */ -mfcc_real GetCenterFrequency(unsigned int filterBand) -{ - mfcc_real centerFrequency = 0.0f; - mfcc_real exponent; - - if(filterBand == 0) - { - centerFrequency = 0; - } - else if(filterBand >= 1 && filterBand <= 14) - { - centerFrequency = (200.0f * filterBand) / 3.0f; - } - else - { - exponent = filterBand - 14.0f; - centerFrequency = pow(1.0711703, exponent); - centerFrequency *= 1073.4; - } - - return centerFrequency; -} diff --git a/samplebrain/src/libmfcc.h b/samplebrain/src/libmfcc.h deleted file mode 100644 index ec7615c..0000000 --- a/samplebrain/src/libmfcc.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * libmfcc.h - Header for libMFCC - * Copyright (c) 2010 Jeremy Sawruk - * - * This code is released under the MIT License. - * For conditions of distribution and use, see the license in LICENSE - */ - -#pragma once - -typedef float mfcc_real; - -#define PI 3.14159265358979323846264338327 - -// Returns the specified (mth) MFCC -mfcc_real GetCoefficient(mfcc_real* spectralData, unsigned int samplingRate, unsigned int NumFilters, unsigned int binSize, unsigned int m); - -// Compute the normalization factor (For internal computation only - not to be called directly) -mfcc_real NormalizationFactor(int NumFilters, int m); - -// Compute the filter parameter for the specified frequency and filter bands (For internal computation only - not the be called directly) -mfcc_real GetFilterParameter(unsigned int samplingRate, unsigned int binSize, unsigned int frequencyBand, unsigned int filterBand); - -// Compute the band-dependent magnitude factor for the given filter band (For internal computation only - not the be called directly) -mfcc_real GetMagnitudeFactor(unsigned int filterBand); - -// Compute the center frequency (fc) of the specified filter band (l) (For internal computation only - not the be called directly) -mfcc_real GetCenterFrequency(unsigned int filterBand); diff --git a/samplebrain/src/main.cpp b/samplebrain/src/main.cpp index ae1d7ba..5e7c238 100644 --- a/samplebrain/src/main.cpp +++ b/samplebrain/src/main.cpp @@ -17,50 +17,68 @@ #include #include #include +#include #include "jellyfish/audio.h" -#include "brain_block.h" +#include "block.h" #include "brain.h" +#include "renderer.h" using namespace std; void unit_test() { - cerr<<"testing brain_block"<left_out.zero(); + renderer *rr = (renderer*)c; + rr->process(frames,a->left_out.get_non_const_buffer()); + +// sleep(1); } int main(int argc, char *argv[]) { - unit_test(); +// unit_test(); cerr<<"starting"<m_client.set_callback(run_audio, &rr); + //target.resynth("shosta-dream-0.5.wav",source,0.5); - + while (true) sleep(1); } diff --git a/samplebrain/src/realtime_renderer.cpp b/samplebrain/src/realtime_renderer.cpp deleted file mode 100644 index b97fbce..0000000 --- a/samplebrain/src/realtime_renderer.cpp +++ /dev/null @@ -1,81 +0,0 @@ -#include "realtime_renderer.h" - -using namespace spiralcore; - -void realtime_renderer::init(const brain &source, const brain &target, float ratio) { - m_source=source; - m_target=target; - m_render_time=0; - m_render_blocks.clear(); - m_ratio = ratio; -} - -void realtime_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/m_tgt_shift; - u32 tgt_end = (m_render_time+nframes)/m_tgt_shift; - - // get indices for current buffer - for (u32 tgt_index = tgt_start; tgt_index::iterator i=m_render_blocks.begin(); i!=m_render_blocks.end(); ++i) { - sample &pcm=m_source.get_block_pcm(i->m_index); - // get the sample offset into the buffer - s32 offset = i->m_time-m_render_time; - - // assume midway through block - u32 block_start = offset; - u32 buffer_start = 0; - if (block_start<0) { - block_start=-block_start; - } else { // block is midway through buffer - block_start=0; - buffer_start=offset; - if (buffer_start>nframes) i->m_finished=true; - } - - if (!i->m_finished) { - // mix in - u32 buffer_pos = buffer_start; - u32 block_pos = block_start; - u32 block_end = block_start+pcm.get_length(); - while (block_pos::iterator i=m_render_blocks.begin(); - list::iterator ni=m_render_blocks.begin(); - while(i!=m_render_blocks.end()) { - ni++; - if (i->m_finished) m_render_blocks.delete(i); - i=ni; - } -} - -bool realtime_renderer::unit_test() { - brain source; - source.load_sound("test_data/up.wav"); - brain target; - target.load_sound("test_data/up.wav"); - - realtime_renderer rr(); - rr.init(source,target,1); - - float *buf=new float[10]; - rr.process(10,buf); - -} diff --git a/samplebrain/src/realtime_renderer.h b/samplebrain/src/realtime_renderer.h deleted file mode 100644 index 92c24fe..0000000 --- a/samplebrain/src/realtime_renderer.h +++ /dev/null @@ -1,32 +0,0 @@ -#include -#include - -namespace spiralcore { - -class realtime_renderer { -public: - void init(const brain &source, const brain &target); - void process(u32 nframes, float *buf); - - bool unit_test(); - -private: - - // realtime stuff - class render_block { - public: - render_block(u32 index, u32 time) : - m_index(index), m_time(time), m_finished(false) {} - u32 m_index; - u32 m_time; // in samples - bool m_finished; - }; - - const brain &m_source; - const brain &m_target; - - list m_render_blocks; - u32 m_render_time; -}; - -}