From d15e78188a9cdbd70640ac57e42d4a598c89b532 Mon Sep 17 00:00:00 2001 From: John Glover Date: Fri, 6 Jul 2012 14:53:01 +0100 Subject: [residual] Add C++ implementation of SMSResidual. --- src/simpl/residual.cpp | 81 +++++++++++++++++++++++++++++++++++++++++++++++++- src/simpl/residual.h | 33 ++++++++++++++++++-- src/sms/sms.h | 2 +- src/sms/synthesis.c | 4 +++ 4 files changed, 115 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/simpl/residual.cpp b/src/simpl/residual.cpp index a6ed226..5d3cb14 100644 --- a/src/simpl/residual.cpp +++ b/src/simpl/residual.cpp @@ -56,9 +56,88 @@ void Residual::synth_frame(Frame* frame) { } // Calculate and return a synthesised residual signal -Frames Residual::synth(Frames frames) { +Frames Residual::synth(Frames& frames) { for(int i = 0; i < frames.size(); i++) { synth_frame(frames[i]); } return frames; } + +Frames Residual::synth(int synth_size, sample* synth, + int original_size, sample* original) { + Frames frames; + + for(int i = 0; i < min(synth_size, original_size) - _hop_size; i += _hop_size) { + Frame* f = new Frame(_hop_size, true); + f->audio(&original[i]); + f->synth(&synth[i]); + synth_frame(f); + frames.push_back(f); + } + + return frames; +} + + +// --------------------------------------------------------------------------- +// SMSResidual +// --------------------------------------------------------------------------- + +SMSResidual::SMSResidual() { + sms_init(); + + sms_initResidualParams(&_residual_params); + _residual_params.hopSize = _hop_size; + sms_initResidual(&_residual_params); +} + +SMSResidual::~SMSResidual() { + sms_freeResidual(&_residual_params); + sms_free(); +} + +void SMSResidual::hop_size(int new_hop_size) { + _hop_size = new_hop_size; + + sms_freeResidual(&_residual_params); + _residual_params.hopSize = _hop_size; + sms_initResidual(&_residual_params); +} + +int SMSResidual::num_stochastic_coeffs() { + return _residual_params.nCoeffs; +} + +void SMSResidual::num_stochastic_coeffs(int new_num_stochastic_coeffs) { + sms_freeResidual(&_residual_params); + _residual_params.nCoeffs = new_num_stochastic_coeffs; + sms_initResidual(&_residual_params); +} + +// int SMSResidual::stochastic_type() { +// return _residual_params. +// } + +// void SMSResidual::stochastic_type(int new_stochastic_type) { +// } + +void SMSResidual::residual_frame(int synth_size, sample* synth, + int original_size, sample* original, + int residual_size, sample* residual) { + + sms_findResidual(synth_size, synth, original_size, original, &_residual_params); + + for(int i = 0; i < residual_size; i++) { + residual[i] = _residual_params.residual[i]; + } +} + +// Calculate and return one frame of the synthesised residual signal +void SMSResidual::synth_frame(Frame* frame) { + residual_frame(frame->size(), frame->synth(), + frame->size(), frame->audio(), + frame->size(), frame->residual()); + sms_approxResidual(frame->size(), frame->residual(), + frame->size(), frame->synth_residual(), + &_residual_params); +} diff --git a/src/simpl/residual.h b/src/simpl/residual.h index 5dd53f5..0125417 100644 --- a/src/simpl/residual.h +++ b/src/simpl/residual.h @@ -3,6 +3,10 @@ #include "base.h" +extern "C" { + #include "sms.h" +} + using namespace std; namespace simpl @@ -16,7 +20,7 @@ namespace simpl // --------------------------------------------------------------------------- class Residual { - private: + protected: int _frame_size; int _hop_size; int _sampling_rate; @@ -26,7 +30,7 @@ class Residual { int frame_size(); void frame_size(int new_frame_size); int hop_size(); - void hop_size(int new_hop_size); + virtual void hop_size(int new_hop_size); int sampling_rate(); void sampling_rate(int new_sampling_rate); @@ -38,10 +42,33 @@ class Residual { int residual_size, sample* residual); virtual void synth_frame(Frame* frame); - virtual Frames synth(Frames frames); + virtual Frames synth(Frames& frames); + virtual Frames synth(int synth_size, sample* synth, + int original_size, sample* original); }; +// --------------------------------------------------------------------------- +// SMSResidual +// --------------------------------------------------------------------------- +class SMSResidual : public Residual { + private: + SMSResidualParams _residual_params; + + public: + SMSResidual(); + ~SMSResidual(); + void hop_size(int new_hop_size); + int num_stochastic_coeffs(); + void num_stochastic_coeffs(int new_num_stochastic_coeffs); + // int stochastic_type(); + // void stochastic_type(int new_stochastic_type); + void residual_frame(int synth_size, sample* synth, + int original_size, sample* original, + int residual_size, sample* residual); + void synth_frame(Frame* frame); +}; + } // end of namespace Simpl #endif diff --git a/src/sms/sms.h b/src/sms/sms.h index 7372a8a..c72b6c1 100644 --- a/src/sms/sms.h +++ b/src/sms/sms.h @@ -193,7 +193,7 @@ typedef struct * This structure contains all the necessary settings and memory for residual synthesis. * */ -typedef struct +typedef struct SMSResidualParams { int samplingRate; int hopSize; diff --git a/src/sms/synthesis.c b/src/sms/synthesis.c index bc739d0..35e91a4 100644 --- a/src/sms/synthesis.c +++ b/src/sms/synthesis.c @@ -195,7 +195,9 @@ void sms_approxResidual(int sizeResidual, sfloat* residual, /* generate random phases */ for(i = 0; i < residualParams->sizeStocMagSpectrum; i++) + { residualParams->stocPhaseSpectrum[i] = TWO_PI * sms_random(); + } /* IFFT with 50% overlap */ sms_invQuickSpectrumW(residualParams->stocMagSpectrum, @@ -208,7 +210,9 @@ void sms_approxResidual(int sizeResidual, sfloat* residual, /* output */ for(i = 0; i < sizeApprox; i++) + { approx[i] = residualParams->approx[i] * residualParams->windowScale; + } } /*! \brief synthesizes one frame of SMS data -- cgit v1.2.3