Jose...

I've stuck my head in the lion's mouth so I may as well go in for one more 
bite, although I promise you that IOhannes Zmoelnig is a REALLY NICE GUY.

I agree that edkellytista9 is a pretty stupid github name. It was done in a 
hurry for working on another project, but I'm setting up a more serious one 
because...you know...presentation is important.

I'm using Makefile.pdlibbuilder now - very cool. And deken ekext-0.2 coming 
soon.

I have a house. It's a bit of a dump but has a studio. I don't live there yet. 
We need to get the builders in!

...and my mbc_lpc~ port compiles but spits out an error:

mbc_lpc~: initializing
mbc_lpc~: free memory...
mbc_lpc~: allocated memory
Generating Hamming window for LPC analysis
 mbc_lpc~
... didn't return a patchable object
 mbc_lpc~
... couldn't create

I still don't know why. Perhaps Iohannes can help?

Ed

_-_-_-_-_-_-_-^-_-_-_-_-_-_-_

For Lone Shark releases, Pure Data software and published Research, go to 
http://sharktracks.co.uk  

    On Monday, 7 May 2018, 09:54:49 GMT+1, padovani 
<[email protected]> wrote:  
 
 Got late into this discussion, but I'm really interested in this project and 
would like to help (even if I don't have much experience coding new objects and 
have been a little busy with my classes at the University).
Ed, any further success last weeks? well... also with the house... ;)
José H.

2018-04-23 4:45 GMT-03:00 IOhannes m zmoelnig <[email protected]>:

On 2018-04-23 00:50, Christof Ressi wrote:
>> - please mark all your functions as static. 
> 
> except for the setup function, of course. just to prevent a possible source 
> of further frustration :-).
>

ouch.
thanks for pointing that out!



______________________________ _________________
[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>

static t_class *mbc_lpc_tilde_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 _mbc_lpc_tilde 
{
  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
  long 	            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_mbc_lpc_tilde;

static t_int *mbc_lpc_tilde_perform(t_int *w) 
{
  t_mbc_lpc_tilde   *x          = (t_mbc_lpc_tilde *)  (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 = re * re;
	      im *= scale;
	      im = fabs(im);
	      im = 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);
}

static void mbc_lpc_tilde_hanning(t_mbc_lpc_tilde *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");  
}

static void mbc_lpc_tilde_hamming(t_mbc_lpc_tilde *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");
}

static void mbc_lpc_tilde_bartlett(t_mbc_lpc_tilde *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");
}

static void mbc_lpc_tilde_preemph(t_mbc_lpc_tilde *x, t_floatarg n)
{
  x->l_preemph = n != 0 ? 1 : 0;
}


void mbc_lpc_tilde_free_arrays(t_mbc_lpc_tilde *x)
{
  post("mbc_lpc~: free memory...");
	
  /*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;*/
  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;
  }
  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;
}

static void mbc_lpc_tilde_init(t_mbc_lpc_tilde *x) {
  int i;
  post("mbc_lpc~: initializing");	
  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 = MAX_ORDER;
  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
  mbc_lpc_tilde_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;
  if(x->split.fImag)post("mbc_lpc~: allocated memory");
  else post("mbc_lpc~: can't allocate memory!");
  //calculate window
  mbc_lpc_tilde_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");
  
}

static void mbc_lpc_tilde_order(t_mbc_lpc_tilde *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
    {
      if(n < 1) post("mbc_lpc~: order must be a positive integer between 1 and 200!");
      x->l_order = (int)n > 1 ? (int)n : 1;
    }
  x->l_frame_rate = (long)(x->l_fs / (t_float)x->l_order);
  mbc_lpc_tilde_init(x);  
}

static void mbc_lpc_tilde_window(t_mbc_lpc_tilde *x, t_floatarg f)
{
  if(f == 1) mbc_lpc_tilde_bartlett(x);
  else if(f == 2) mbc_lpc_tilde_hanning(x);
  else mbc_lpc_tilde_hamming(x);
}

static void mbc_lpc_tilde_dsp(t_mbc_lpc_tilde *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;
  //mbc_lpc_tilde_init(x);
  //  dsp_add(lpc_blit_perform, 4, x,
  //  sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);

  dsp_add(mbc_lpc_tilde_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[0]->s_n);
}

static void *mbc_lpc_tilde_new(t_floatarg order, t_floatarg preemph)
{
  t_mbc_lpc_tilde *x = (t_mbc_lpc_tilde *)pd_new(mbc_lpc_tilde_class);

  x->initOrder = (int)order;
  x->initPreemph = (int)preemph;
  
  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;
    }
  if(x->initPreemph != 0) x->l_preemph = 1;
  else x->l_preemph = 0;
  x->l_fs = sys_getsr();
  x->l_frame_rate = (long)(x->l_fs / (t_float)x->l_order);
  mbc_lpc_tilde_init(x);  

  //inlet_new (&x->x_obj, &s_signal);
  outlet_new(&x->x_obj, &s_signal);
  outlet_new(&x->x_obj, &s_signal);
  outlet_new(&x->x_obj, &s_signal);
  outlet_new(&x->x_obj, &s_signal);
  outlet_new(&x->x_obj, &s_signal);
  //post("mbc_lpc~ initialized!");
}

void mbc_lpc_tilde_setup(void)
{
  mbc_lpc_tilde_class = class_new(gensym("mbc_lpc~"), 
  (t_newmethod)mbc_lpc_tilde_new, 
  0, sizeof(t_mbc_lpc_tilde),
  CLASS_DEFAULT, A_DEFFLOAT, 0);

  post("->mbc_lpc~");
  post("->by Mark Cartwright");
  post("->Pd port by Edward Kelly");
  post("->2018");

  class_addmethod(mbc_lpc_tilde_class,
  (t_method)mbc_lpc_tilde_dsp, gensym("dsp"), 0);
  CLASS_MAINSIGNALIN(mbc_lpc_tilde_class, t_mbc_lpc_tilde, dummy);
  class_addmethod(mbc_lpc_tilde_class, (t_method)mbc_lpc_tilde_order, gensym("order"), A_DEFFLOAT, 0);
  class_addmethod(mbc_lpc_tilde_class, (t_method)mbc_lpc_tilde_preemph, gensym("preemph"), A_DEFFLOAT, 0);
  class_addmethod(mbc_lpc_tilde_class, (t_method)mbc_lpc_tilde_window, gensym("window"), A_DEFFLOAT, 0);
}
_______________________________________________
[email protected] mailing list
UNSUBSCRIBE and account-management -> 
https://lists.puredata.info/listinfo/pd-list

Reply via email to