// Copyright (C) 2022 Then Try This // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include #include #include #include "block.h" using namespace spiralcore; FFT *block::m_fftw; Aquila::Mfcc *block::m_mfcc_proc; static const int MFCC_FILTERS=12; static const int FFT_BIAS=200; double blend(double a, double b, double t) { return a*(1-t)+b*t; } double square(double a) { return a*a; } void normalise(spiralcore::sample &in) { // find min/max float max = 0; float min = FLT_MAX; for (u32 i=0; imax) max=in[i]; } float mid = min+(max-min)/2.0f; // remove dc for (u32 i=0; im_length!=block_size) { if (m_fftw == NULL) delete m_fftw; m_fftw = new FFT(block_size,100); if (m_mfcc_proc == NULL) delete m_mfcc_proc; m_mfcc_proc = new Aquila::Mfcc(block_size); } } void block::process(const sample &pcm, sample &fft, sample &mfcc, float &freq) { m_fftw->impulse2freq(pcm.get_buffer()); m_fftw->calculate_bins(); // calculate fft std::vector > mfspec; for (u32 i=0; i(m_fftw->m_spectrum[i][0], m_fftw->m_spectrum[i][1])); } freq = m_fftw->calculate_dominant_freq(); u32 fft_size = m_block_size; if (fft_size>100) { fft.crop_to(100); fft_size=100; } for (u32 i=0; im_bin[i]; } // calculate mfcc std::vector m = m_mfcc_proc->calculate(mfspec,MFCC_FILTERS); for (u32 i=0; i1) s||b.m_id; if (version>2) { s||b.m_dominant_freq; s||b.m_n_dominant_freq; } s||b.m_pcm||b.m_fft||b.m_mfcc; s||b.m_n_pcm||b.m_n_fft||b.m_n_mfcc; s||b.m_block_size||b.m_rate||b.m_orig_filename; stream_vector(s,b.m_synapse); return s; } bool block::unit_test() { stream_unit_test(); sample ntest(3); u32 idx=0; ntest[idx++]=-1; ntest[idx++]=1; ntest[idx++]=-1; idx=0; normalise(ntest); assert(feq(ntest[idx++],-1)); assert(feq(ntest[idx++],1)); assert(feq(ntest[idx++],-1)); idx=0; ntest[idx++]=-2; ntest[idx++]=2; ntest[idx++]=-2; normalise(ntest); idx=0; assert(feq(ntest[idx++],-1)); assert(feq(ntest[idx++],1)); assert(feq(ntest[idx++],-1)); idx=0; ntest[idx++]=19; ntest[idx++]=20; ntest[idx++]=19; normalise(ntest); idx=0; assert(feq(ntest[idx++],-1)); assert(feq(ntest[idx++],1)); assert(feq(ntest[idx++],-1)); sample data(200); for (u32 i=0; i