Code was shared previously on a github, but here's the offending article, and
the link.
The botherer is called mbc_lpc~.c
edkellytista9/LPCToolkitPd
|
|
|
| | |
|
|
|
| |
edkellytista9/LPCToolkitPd
LPCToolkitPd - Mark Cartwright's LPC Toolkit for Pure Data
|
|
|
_-_-_-_-_-_-_-^-_-_-_-_-_-_-_
For Lone Shark releases, Pure Data software and published Research, go to
http://sharktracks.co.uk
On Friday, 20 April 2018, 22:02:16 GMT+1, IOhannes m zmölnig
<[email protected]> wrote:
On 04/20/2018 04:38 PM, Ed Kelly via Pd-list wrote:
> Apologies - I'm trying to do this while buying a house...I don't know if that
> is simple in Austria but it isn't here.
good luck.
i'm sure it is a hell of stuff to do.
> After reading your email I assumed it was something new, but of course I had
> just copied, pasted and altered code from a previous external (and forgot>
> Perhaps it's to do with linking to libm, so I'll check the makefile
once I'm back in a reasonably stable (time-wise) environment.
in the meantime, you could also share your code with us.
> BUT - I've never really understood (in ~13 years of external development)
> what all those args to class_new() did before, and you've forced me to look
> deeper into m_pd.h
fwiw, each and every argument to class_new() is covered by the externals
howto.
> I should thank you for that - and yes, I learned how to write externals by
> reading your howto, in 2005 I believe.
:-)
gdsamr
IOhannes
_______________________________________________
[email protected] mailing list
UNSUBSCRIBE and account-management ->
https://lists.puredata.info/listinfo/pd-list
/*
* LPC Toolkit
* By Mark Cartwright
* Pure Data port by Edward Kelly 2018
* BSD licence
*
*
*/
#include "m_pd.h"
#include <math.h>
//#include <gsl/gsl_vector_float.h>
//#include <gsl/gsl_blas.h>
#ifdef _WIN32
# include <malloc.h> /* MSVC or mingw on windows */
#elif defined(__linux__) || defined(__APPLE__)
# include <alloca.h> /* linux, mac, mingw, cygwin */
#else
# include <stdlib.h> /* BSDs for example */
#endif
static t_class *mbc_lpc_class;
#define MAX_ORDER 200
#define NLOG2(x) (ceil(log2(x)))
#define POW2(x) (1 << x)
#define TWOPI M_PI * 2
#define DEFAULT_FS 44100
#define DEFAULT_FRAMERATE 100
#define DEFAULT_V_SIZE 64
#define DEFAULT_ORDER 32
typedef struct _DSPcomplex
{
//gsl_vector_float* real;
//gsl_vector_float* imag;
t_float* fReal;
t_float* fImag;
} t_DSPcomplex;
//#define REAL(z,i) gsl_vector_float_set(z,2*(i))
//#define IMAG(z,i) gsl_vector_float_setz(z,2*(i)+1)
typedef struct _lpc
{
t_object x_obj; // the object itself (t_pxobject in MSP)
t_float dummy;
//t_float* l_frame_buff; //input frame buffer
//gsl_vector_float* l_frame_buff; //input frame buffer
//t_float* l_winframe_buff; //windowed input frame buffer
//gsl_vector_float* l_winframe_buff; //windowed input frame buffer
//t_float* l_outCoeff_buff; //coefficient signal
//gsl_vector_float* l_outCoeff_buff; //coefficient signal
//t_float* l_outParcor_buff; //PARCOR coeffs
//gsl_vector_float* l_outParcor_buff; //PARCOR coeffs
//t_float* l_outError_buff; //error signal
//gsl_vector_float* l_outError_buff; //error signal
//t_float* l_win; //analysis window
//gsl_vector_float* l_win; //analysis window
//t_float* l_R;
//gsl_vector_float* l_R;
/*-------------- non-GSL versions --------------*/
t_float* frameBuffer;
t_float* winFrameBuffer;
t_float* outCoeffBuffer;
t_float* parcorBuffer;
t_float* errorSigBuffer;
t_float* window;
t_float* lR;
// t_float* vectorBuffer;
double* l_W;
double* l_E;
double* l_K;
double l_G;
double** l_A;
double l_x1; //last samples of pre-emphasis filter
float l_b1; //pre-emph coefficient
int l_order; //predictor order
int l_order_max; //max order according to fs = order * frame_rate
int l_preemph; //pre-epmhasis filter on/off
int l_frame_rate; //analysis frame rate
int l_frame_size; //analysis frame size, where fs = frame_rate * frame_size * 2
int l_hop_size; //hop_size = frame_size * 2 (b/c of overlap)
int l_inframe_idx; //current inframe buffer index
int l_outframe_idx; //current outframe buffer index
long l_v_size; //vector size
float l_fs; //sampling rate
int l_maxnfft; //fft length
int l_log2nfft; //log2(fft length)
int initOrder, initFramerate, initPreemph; // initialization values
int j;
// FFTSetup l_fftsetup; //FFTSetup for vDSP FFT functions
t_DSPcomplex split;
// DSPSplitComplex l_fftSplitTemp; //temp split complex vector structure
} t_lpc;
t_int *lpc_perform(t_int *w)
{
t_lpc *x = (t_lpc *) (w[1]);
t_float *in = (t_float *)(w[2]);
t_float *out_error = (t_float *)(w[3]);
t_float *out_gain = (t_float *)(w[4]);
t_float *out_coeff = (t_float *)(w[5]);
t_float *out_parcor = (t_float *)(w[6]);
t_float *out_index = (t_float *)(w[7]);
int n = (int) (w[8]);
int p = x->l_order;
int length = x->l_frame_size;
int log2nfft = NLOG2(length+p+1);
int nfft = POW2(log2nfft);
int nfftO2 = nfft/2;
t_float recipn = 1.0/nfft;
int inframeidx = x->l_inframe_idx;
int outframeidx = x->l_outframe_idx;
int i, j, i1, ji;
int in_idx = 0, out_idx = 0;
double val;
t_float scale, rCorr, re, im;
//gsl_vector_float *vectorBuffer;
//vectorBuffer = gsl_vector_float_calloc(MAX_ORDER); //input frame buffer
//x->vectorBuffer = (t_float *) getzbytes( nfftO2 * sizeof(t_float));
if (x->l_preemph)
{
while (n--)
{
val = in[in_idx];
in[in_idx] = val + x->l_b1 * x->l_x1;
x->l_x1 = val;
in_idx++;
}
n = (int)(w[8]);
in_idx = 0;
}
while (n--)
{
if (inframeidx < length) {
//copy input into frame buff
//also copy into winframe buff since GSL puts the result into one of the arg vectors
//gsl_vector_float_set(&x->l_frame_buff,inframeidx,in[in_idx]);// = x->l_frame_buff[inframeidx] = in[in_idx];
x->frameBuffer[inframeidx] = in[in_idx];
out_gain[out_idx] = x->l_G;
//out_error[out_idx] = gsl_vector_float_get(&x->l_outError_buff,outframeidx); //for now
out_error[out_idx] = x->errorSigBuffer[outframeidx];
if (outframeidx < x->l_order) {
//out_coeff[out_idx] = gsl_vector_float_get(&x->l_outCoeff_buff,outframeidx);
out_coeff[out_idx] = x->outCoeffBuffer[outframeidx];
//out_parcor[out_idx] = gsl_vector_float_get(&x->l_outParcor_buff,outframeidx);
out_parcor[out_idx] = x->parcorBuffer[outframeidx];
out_index[out_idx] = outframeidx + 1;
} else {
out_coeff[out_idx] = 0.0;
out_parcor[out_idx] = 0.0;
out_index[out_idx] = 0;
}
inframeidx++;
in_idx++;
outframeidx++;
out_idx++;
} else {
//gsl_vector_float_memcpy(&x->l_winframe_buff,&x->l_frame_buff);
//memcpy(&x->winFrameBuffer,&x->frameBuffer,x->l_maxnfft * sizeof(t_float));
x->winFrameBuffer = copybytes(x->frameBuffer, x->l_maxnfft * sizeof(t_float));
//perform durbin-levinson - for right now, just count to the order---------------
//clear memory, is this necessary?
for (i=0; i < p+1; i++){
x->lR[i] = 0.0;
x->l_W[i] = 0.0;
x->l_E[i] = 0.0;
x->l_K[i] = 0.0;
}
for(i=0; i<=p; i++) {
for(j=0; j < p; j++) x->l_A[i][j] = 0.0;
}
//window frame buff
//vDSP_vmul(x->l_frame_buff, 1, x->l_win, 1, x->l_winframe_buff, 1, length);
//gsl_vector_float_mul(&x->l_winframe_buff,&x->l_win);
for(i=0;i<x->l_maxnfft;i++)
{
x->winFrameBuffer[i] = x->winFrameBuffer[i] * x->window[i];
}
#ifdef DEBUG
for(i=0;i<length;i++)post("\nwinframe(%d) = %g;",i+1,x->winFrameBuffer[i]);
#endif
//create r from auto correlation
if ((2*nfft*log2(nfft)+nfft) > length*p) { //NOTE: change this to update only when order is changed!
//time domain method
//for(i=0; i < p+1; i++) vDSP_dotpr(x->l_winframe_buff,1,x->l_winframe_buff+i,1,x->l_R+i,length-i);
//gsl_vector_float_memcpy(vectorBuffer,&x->l_winframe_buff);
for(i=0; i < p+1; i++)
{
//gsl_blas_sdot(&x->l_winframe_buff,&x->l_winframe_buff+i,&rCorr);
//gsl_vector_float_set(&x->l_R,i,rCorr);
for(x->j=0;x->j < length - i; x->j++) x->lR[i] = x->winFrameBuffer[j] * x->winFrameBuffer[j+i];
}
} else {
//frequency domain method
// zero pad
//vDSP_vclr(x->l_winframe_buff+length,1,nfft-length);
for(i=length;i<nfft;i++)
{
//gsl_vector_float_set(&x->l_winframe_buff,i,0);
x->winFrameBuffer[i] = 0.0;
}
for(i=0;i<nfftO2;i++)
{
x->split.fReal[i] = x->winFrameBuffer[i*2];
x->split.fImag[i] = x->winFrameBuffer[i*2+1];
//convert to split complex vector
//gsl_vector_float_set(&x->split.real,i,gsl_vector_float_get(x->l_winframe_buff,i*2));
//gsl_vector_float_set(&x->split.imag,i,gsl_vector_float_get(x->l_winframe_buff,i*2+1));
}
//vDSP_ctoz( ( DSPComplex * ) x->l_winframe_buff, 2, &x->l_fftSplitTemp, 1, nfftO2);
//perform forward in place fft
//gsl_fft_complex_radix2_forward(&x->l_winframe_buff,1,nfft);
//EXTERN void mayer_fft(int n, t_sample *real, t_sample *imag);
//EXTERN void mayer_ifft(int n, t_sample *real, t_sample *imag);
mayer_fft(nfftO2,x->split.fReal,x->split.fImag);
//vDSP_fft_zrip(x->l_fftsetup, &x->l_fftSplitTemp, 1, log2nfft, FFT_FORWARD);
//scaling
scale = 0.5;
// Ed Kelly: scale real and imaginary parts and calculate magnitudes squared
for(i=0;i<nfftO2;i++)
{
j = i*2;
//re = gsl_vector_float_get(&x->l_winframe_buff,j);
re = x->split.fReal[j];
//im = gsl_vector_float_get(&x->l_winframe_buff,j+1);
im = x->split.fImag[j];
re *= scale;
re = fabs(re * re);
im *= scale;
im = fabs(im * im);
//gsl_vector_float_set(&x->split.real,i,re+im);
//gsl_vector_float_set(&x->split.imag,i,0.0);
//gsl_vector_float_set(vectorBuffer,j,re+im);
x->split.fReal[j] = re+im;
}
//vDSP_vsmul(x->l_fftSplitTemp.realp,1,&scale,x->l_fftSplitTemp.realp,1,nfftO2);
//vDSP_vsmul(x->l_fftSplitTemp.imagp,1,&scale,x->l_fftSplitTemp.imagp,1,nfftO2);
//compute PSD
//vDSP_zvmags(&x->l_fftSplitTemp,1,x->l_fftSplitTemp.realp,1,nfftO2);
//clear imaginary part
for(i=0;i<nfftO2;i++)
{
//IMAG(&x->l_winframe_buff,i) = 0.0;
//gsl_vector_float_set(&x->l_winframe_buff,i*2+1,0.0);
x->split.fImag[i] = 0;
}
//vDSP_vclr(x->l_fftSplitTemp.imagp,1,nfftO2);
//perform inverse in place fft
//gsl_fft_complex_radix2_backward(vectorBuffer,1,nfft);
//vDSP_fft_zrip(x->l_fftsetup, &x->l_fftSplitTemp, 1, log2nfft, FFT_INVERSE);
mayer_ifft(nfftO2,x->split.fReal,x->split.fImag);
//scaling
//vDSP_vsmul(x->l_fftSplitTemp.realp,1,&recipn,x->l_fftSplitTemp.realp,1,nfftO2);
//vDSP_vsmul(x->l_fftSplitTemp.imagp,1,&recipn,x->l_fftSplitTemp.imagp,1,nfftO2);
//gsl_vector_float_scale(vectorBuffer,&recipn);
for(i=0;i<nfftO2;i++)
{
x->lR[i*2] = x->split.fReal[i] * recipn;
x->lR[i*2+1] = x->split.fImag[i] * recipn;
}
//convert back to real number vector
//vDSP_ztoc(&x->l_fftSplitTemp, 1, (DSPComplex *)x->l_R, 2, nfftO2);
//gsl_vector_float_memcpy(x->l_R,vectorBuffer);
}
/*for(i=0; i < p+1; i++) {
x->l_R[i] = 0.0;
for(j=0; j < length - i; j++) {
x->l_R[i] += x->l_winframe_buff[j] * x->l_winframe_buff[i+j];
//x->l_R[i] += x->l_win[j] * x->l_win[i+j];
}
}*/
#ifdef DEBUG
for(i=0;i< p+1; i++) post("\nR(%d) = %f;",i+1,x->lR[i]);
#endif
//x->l_W[0] = gsl_vector_float_get(x->l_R,1);
//x->l_E[0] = gsl_vector_float_get(x->l_R,0);
x->l_W[0] = x->lR[1];
x->l_E[0] = x->lR[0];
for (i = 1; i <= p; i++) {
x->l_K[i] = x->l_W[i-1] / x->l_E[i-1];
x->l_A[i][i] = x->l_K[i];
i1 = i - 1;
if (i1 >= 1) {
for (j = 1; j <=i1; j++) {
ji = i - j;
x->l_A[j][i] = x->l_A[j][i1] - x->l_K[i] * x->l_A[ji][i1];
}
}
x->l_E[i] = x->l_E[i-1] * (1.0 - x->l_K[i] * x->l_K[i]);
if (i != p) {
x->l_W[i] = x->lR[i+1];
for (j = 1; j <= i; j++) {
x->l_W[i] -= x->l_A[j][i] * x->lR[i-j+1];
}
}
}
x->l_G = sqrt(x->l_E[p]);
for (i=0; i < p; i++) {
x->outCoeffBuffer[i] = (t_float)(x->l_A[i+1][p]);
x->parcorBuffer[i] = (t_float)(x->l_K[i+1]);
//#ifdef DEBUG
//post("\nParcor(%d) = %g;",i+1,x->l_K[i+1]);
//post("\nCoeff(%d) = %g;",i+1,x->l_A[i+1][p]);
//#endif
}
//--------------------------------------------------------------------------------
//copy right side to left side, move delayed input to output
for (i=0; i < x->l_hop_size; i++) {
x->errorSigBuffer[i] = x->frameBuffer[i];
x->frameBuffer[i] = x->frameBuffer[i + x->l_hop_size];
}
inframeidx = x->l_hop_size;
outframeidx = 0;
n++; //to avoid skipping a sample (since we already decremented
while (n--) {
x->frameBuffer[inframeidx] = in[in_idx];
out_gain[out_idx] = (t_float)(x->l_G);
out_error[out_idx] = x->errorSigBuffer[outframeidx]; //for now
if (outframeidx < x->l_order) {
out_coeff[out_idx] = x->outCoeffBuffer[outframeidx];
out_parcor[out_idx] = x->parcorBuffer[outframeidx];
out_index[out_idx] = (t_float)(outframeidx + 1);
} else {
out_coeff[out_idx] = 0.0;
out_parcor[out_idx] = 0.0;
out_index[out_idx] = 0;
}
inframeidx++;
in_idx++;
outframeidx++;
out_idx++;
}
break;
}
}
x->l_inframe_idx = inframeidx;
x->l_outframe_idx = outframeidx;
return (w+9);
}
void lpc_hanning(t_lpc *x)
{
t_float N = (t_float)x->l_frame_size;
int n;
for (n=0; n<(int)N; n++)
{
x->window[n] = 0.5 * (1.0 - cos((TWOPI*((t_float)n+1))/(N+1)));
}
post("Generating Hanning window for LPC analysis");
}
void lpc_hamming(t_lpc *x)
{
t_float N = (t_float)x->l_frame_size;
int n;
for (n=0; n<(int)N; n++)
{
x->window[n] = (0.54 - 0.46*cos((TWOPI*(t_float)n)/(N-1)));
}
post("Generating Hamming window for LPC analysis");
}
void lpc_bartlett(t_lpc *x)
{
t_float N = (t_float)x->l_frame_size;
int n;
for (n=0; n<(int)N; n++)
{
x->window[n] = 2.0/(N - 1) * ((N-1)/2 - fabs((t_float)n - (N-1)/2.0));
}
post("Generating Bartlett window for LPC analysis");
}
void lpc_preemph(t_lpc *x, t_floatarg n)
{
x->l_preemph = n != 0 ? 1 : 0;
}
void lpc_init(t_lpc *x) {
int i;
if (x->l_fs < (t_float)x->l_frame_rate * (t_float)x->l_order) {
x->l_frame_rate = (long)(x->l_fs / (t_float)x->l_order);
error("mbc.lpc~: framerate * order must be less than or equal to sampling rate. framerate has been changed to %d", x->l_frame_rate);
}
x->l_hop_size = (int)(x->l_fs / (t_float)x->l_frame_rate);
if (x->l_v_size > x->l_hop_size) {
error("mbc.lpc~: warning: frame_size is less than vector size. this may cause errors, please reduce the frame rate or increase the vector size");
}
x->l_order_max = x->l_fs / (t_float)x->l_frame_rate;
x->l_frame_size = x->l_hop_size * 2;
x->l_inframe_idx = x->l_hop_size;
x->l_outframe_idx = 0;
x->l_log2nfft = (int) NLOG2(x->l_frame_size+MAX_ORDER+1);
x->l_maxnfft = POW2(x->l_log2nfft);
// free memory if needed
lpc_free_arrays(x);
//allocate memory
//x->l_frame_buff = (t_float *) getzbytes( x->l_frame_size * sizeof(t_float));
//x->l_frame_buff = gsl_vector_float_calloc(x->l_frame_size);
x->frameBuffer = (t_float *) getzbytes( x->l_frame_size * sizeof(t_float));
x->winFrameBuffer = (t_float *) getzbytes( x->l_maxnfft * sizeof(t_float));
x->outCoeffBuffer = (t_float *) getzbytes(MAX_ORDER * sizeof(t_float));
x->parcorBuffer = (t_float *) getzbytes(MAX_ORDER * sizeof(t_float));
x->errorSigBuffer = (t_float *) getzbytes( x->l_hop_size * sizeof(t_float));
x->window = (t_float *) getzbytes( x->l_frame_size * sizeof(t_float));
x->lR = (t_float *) getzbytes( x->l_maxnfft * sizeof(t_float));
x->l_W = (double *) getzbytes( (MAX_ORDER + 1) * sizeof(double));
x->l_E = (double *) getzbytes( (MAX_ORDER + 1) * sizeof(double));
x->l_K = (double *) getzbytes( (MAX_ORDER + 1) * sizeof(double));
x->l_A = (double **) getzbytes( (MAX_ORDER + 1) * sizeof(double*));
for(i=0; i<MAX_ORDER; i++) {
x->l_A[i] = (double *)getzbytes( (MAX_ORDER + 1) * sizeof(double));
}
x->split.fReal = (float *)getzbytes( (x->l_maxnfft / 2) * sizeof(float));
x->split.fImag = (float *)getzbytes( (x->l_maxnfft / 2) * sizeof(float));
x->l_x1 = 0;
x->l_G = 0.0;
x->l_b1 = -0.98;
//calculate window
lpc_hamming(x);
//create FFTsetups
//x->l_fftsetup = vDSP_create_fftsetup(x->l_log2nfft,FFT_RADIX2);
//if (!x->l_fftsetup) error("mbc.lpc~: not enough available memory");
}
void lpc_order(t_lpc *x, t_floatarg n)
{
if (x->l_order_max < (int)n)
{
error("mbc.lpc~: framerate * order must be less than or equal to sampling rate. At the current setting maxorder is %d. For a higher order, lower the framerate.", x->l_order_max);
x->l_order = x->l_order_max;
}
else
{
x->l_order = (int)n > 4 ? (int)n : 4;
}
x->l_frame_rate = x->l_fs / x->l_order;
lpc_init(x);
//lpc_init(x) ?
}
void lpc_free_arrays(t_lpc *x)
{
//int i;
/*gsl_vector_float_free(x->l_frame_buff);
x->l_frame_buff = NULL;
gsl_vector_float_free(x->l_winframe_buff);
x->l_winframe_buff = NULL;
gsl_vector_float_free(x->l_outCoeff_buff);
x->l_outCoeff_buff = NULL;
gsl_vector_float_free(x->l_outError_buff);
x->l_outError_buff = NULL;
gsl_vector_float_free(x->l_outParcor_buff);
x->l_outParcor_buff = NULL;
gsl_vector_float_free(x->l_win);
x->l_win = NULL;
gsl_vector_float_free(x->l_R);
x->l_R = NULL;*/
//x->frameBuffer = (t_float *) getzbytes( x->l_frame_size * sizeof(t_float));
// x->winFrameBuffer = (t_float *) getzbytes( x->l_maxnfft * sizeof(t_float));
// x->OutCoeffBuffer = (t_float *) getzbytes(MAX_ORDER * sizeof(t_float));
// x->parcorBuffer = (t_float *) getzbytes(MAX_ORDER * sizeof(t_float));
// x->errorSigBuffer = (t_float *) getzbytes( x->l_hop_size * sizeof(t_float));
// x->window = (t_float *) getzbytes( x->l_frame_size * sizeof(t_float));
freebytes(x->frameBuffer, x->l_frame_size * sizeof(t_float));
freebytes(x->winFrameBuffer, x->l_maxnfft * sizeof(t_float));
freebytes(x->outCoeffBuffer, MAX_ORDER * sizeof(t_float));
freebytes(x->parcorBuffer, MAX_ORDER * sizeof(t_float));
freebytes(x->errorSigBuffer, x->l_hop_size * sizeof(t_float));
freebytes(x->window, x->l_frame_size * sizeof(t_float));
freebytes(x->lR, x->l_maxnfft * sizeof(t_float));
x->frameBuffer = NULL;
x->winFrameBuffer = NULL;
x->outCoeffBuffer = NULL;
x->parcorBuffer = NULL;
x->errorSigBuffer = NULL;
x->window = NULL;
x->lR = NULL;
if (x->l_W) {
freebytes(x->l_W, (MAX_ORDER + 1) * sizeof(double));
x->l_W = NULL;
}
if (x->l_E) {
freebytes(x->l_E, (MAX_ORDER + 1) * sizeof(double));
x->l_E = NULL;
}
if (x->l_K) {
freebytes(x->l_K, (MAX_ORDER + 1) * sizeof(double));
x->l_K = NULL;
}
if (x->l_A) {
freebytes(x->l_A, (MAX_ORDER + 1) * sizeof(double));
x->l_A = NULL;
}
/* if (x->l_fftSplitTemp.realp) {
sysmem_freeptr(x->l_fftSplitTemp.realp);
x->l_fftSplitTemp.realp = NULL;
}
if (x->l_fftSplitTemp.imagp) {
sysmem_freeptr(x->l_fftSplitTemp.imagp);
x->l_fftSplitTemp.imagp = NULL;
}
if (x->l_fftsetup) {
vDSP_destroy_fftsetup(x->l_fftsetup);
x->l_fftsetup = NULL;
}*/
freebytes(x->split.fReal, (x->l_maxnfft / 2) * sizeof(t_float));
freebytes(x->split.fImag, (x->l_maxnfft / 2) * sizeof(t_float));
x->split.fReal = NULL;
x->split.fImag = NULL;
}
void lpc_window(t_lpc *x, t_floatarg f)
{
if(f == 1) lpc_bartlett(x);
else if(f == 2) lpc_hanning(x);
else lpc_hamming(x);
}
void lpc_dsp(t_lpc *x, t_signal **sp)
{
x->l_fs = sys_getsr();
if(sp[0]->s_n != x->l_v_size) x->l_v_size = sp[0]->s_n;
lpc_init(x);
// dsp_add(lpc_blit_perform, 4, x,
// sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
dsp_add(lpc_perform, 8, x, sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[3]->s_vec, sp[4]->s_vec, sp[5]->s_vec, sp[6]->s_vec, sp[0]->s_n);
}
void *lpc_new(int argc, t_atom *argv)
{
t_lpc *x = (t_lpc *)pd_new(mbc_lpc_class);
//#define DEFAULT_FS 44100
//#define DEFAULT_FRAMERATE 100
//#define DEFAULT_V_SIZE 64
//#define DEFAULT_ORDER 32
/*if(argc >= 3)
{
x->initOrder = atom_getfloat(argv);
x->initFramerate = atom_getfloat(argv+1);
x->initPreemph = atom_getfloat(argv+2);
}
else
if(argc == 2)*/
if(argc >= 2)
{
x->initOrder = atom_getfloat(argv);
//x->initFramerate = atom_getfloat(argv+1);
x->initPreemph = atom_getfloat(argv+1);
}
else if(argc == 1)
{
x->initOrder = atom_getfloat(argv);
//x->initFramerate = DEFAULT_FRAMERATE;
x->initPreemph = 0;
}
else
{
x->initOrder = DEFAULT_ORDER;
//x->initFramerate = DEFAULT_FRAMERATE;
x->initPreemph = 0;
}
if(x->initOrder < 1)
{
post("Order must be from 1 to 200! Setting to %d",DEFAULT_ORDER);
x->l_order = DEFAULT_ORDER;
}
else if(x->initOrder > MAX_ORDER)
{
post("Order cannot be greater than %d!",MAX_ORDER);
x->l_order = MAX_ORDER;
}
else
{
post("Setting order to %d",x->initOrder);
x->l_order = x->initOrder;
}
x->l_fs = sys_getsr();
x->l_frame_rate = (int)(x->l_fs / (t_float)x->l_order);
lpc_init(x);
//int length = x->l_frame_size;
//int log2nfft = NLOG2(length+p+1);
//int nfft = POW2(log2nfft);
//int nfftO2 = nfft/2;
//MAX_ORDER is wrong - check fft size calculation!
/* x->l_frame_buff = gsl_vector_float_calloc(MAX_ORDER); //input frame buffer
x->l_winframe_buff = gsl_vector_float_calloc(MAX_ORDER); //windowed input frame buffer
x->l_outCoeff_buff = gsl_vector_float_calloc(MAX_ORDER); //coefficient signal
x->l_outParcor_buff = gsl_vector_float_calloc(MAX_ORDER); //PARCOR coeffs
x->l_outError_buff = gsl_vector_float_calloc(MAX_ORDER); //error signal
x->l_win = gsl_vector_float_calloc(MAX_ORDER); //analysis window
*/
inlet_new (&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
//floatinlet_new (&x->x_obj, &x->f_win);
outlet_new(&x->x_obj, &s_signal);
outlet_new(&x->x_obj, &s_signal);
}
void lpc_setup(void)
{
mbc_lpc_class = class_new(gensym("mbc_lpc~"),
(t_newmethod)lpc_new,
0, sizeof(t_lpc),
CLASS_DEFAULT, A_DEFFLOAT, 0);
post("->mbc_lpc~");
post("->by Mark Cartwright");
post("->Pd port by Edward Kelly");
post("->2018");
class_addmethod(mbc_lpc_class,
(t_method)lpc_dsp, gensym("dsp"), 0);
CLASS_MAINSIGNALIN(mbc_lpc_class, t_lpc, dummy);
class_addmethod(mbc_lpc_class, (t_method)lpc_order, gensym("order"), A_DEFFLOAT, 12);
class_addmethod(mbc_lpc_class, (t_method)lpc_preemph, gensym("preemph"), A_DEFFLOAT, 0);
}
_______________________________________________
[email protected] mailing list
UNSUBSCRIBE and account-management ->
https://lists.puredata.info/listinfo/pd-list