Annonce

>>> Bienvenue sur codelab! >>> Première visite ? >>> quelques mots sur codelab //// une carte des membres//// (apéros) codelab


#1 2013-05-23 11:24:22 External lpc~ : problème de syntaxe

adur0
nouveau membre
Date d'inscription: 2013-05-23
Messages: 3

External lpc~ : problème de syntaxe



Bonjour à tous,

Voilà, j'essaye de porter un external PureData, qui effectue l'analyse LPC d'un signal dans Max/MSP. Le problème, c'est qu'il me semble qu'il y a une erreur de syntaxe dans le code source que je me suis procuré. Voici le code en question :

/*  Linear Predictive Coding - PARCOR and residual generation
*  Copyright (C) 2005 Nicolas Chetry <okin@altern.org>
*  and Edward Kelly <morph_2016@yahoo.co.uk>
*
*  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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

#include "m_pd.h"
#include <math.h>
#define MAXPOLES 100

static t_class *lpc_tilde_class;

typedef struct _lpc_schur
{
 t_float *c_input, *c_residual;
 /* just so we don't get clicks */
 t_atom x_last_parcors[MAXPOLES];
 t_atom x_parcors[MAXPOLES];
} t_lpc_schur;

typedef struct _lpc_tilde
{
 t_object x_obj;
 t_float f_dummy;
 t_float x_order, x_lastorder;
 t_outlet *parcor_list;
 t_lpc_schur x_schur;
} t_lpc_tilde;

t_int *lpc_tilde_perform(t_int *w)
{
 t_lpc_tilde     *x =     (t_lpc_tilde *)(w[1]);
 t_lpc_schur *schur =     (t_lpc_schur *)(w[2]);
 int              n =               (int)(w[3]);
 t_float        *in = schur->c_input;
 t_float       *res = schur->c_residual;
//  t_float   *parcors = schur->PARCORS;
//  t_float       *acf = schur->ACF;
//  t_float         *k = schur->K;
//  t_float         *p = schur->P;
//  t_float         *r = schur->r;
 t_int          ord = (int)x->x_order;
 t_int        l_ord = (int)x->x_lastorder;
//  t_float parcors[ord];
 float acf[ord+1];
 float k[ord+1];
 float p[ord+1];
 float r[ord+1];
 float mem[ord];
 int i, j, bid, y, z;
 int g, h;
 float tmp, temp, sav, di;
 float parcor_1;
 for (i=0; i<ord; i++)
 {
   SETFLOAT (&schur->x_parcors[i],0);
   mem[i] = 0.0;
 }
 for (j=0; j<=ord; j++)
 {
   acf[j] = 0;
   for (i=j; i<n; i++)
    {
      acf[j] += in[i]*in[i-j];
    }
 }
 if (acf[0] == 0)
 {
   for (i=0; i<ord; i++)
    {
   SETFLOAT (&schur->x_parcors[i],0);
    }
 }
 for (i=0; i<=ord; i++)
 {
   p[i]=acf[i];
    if (i > 0 && i < ord)
    {
      k[ord+1-i] = acf[i];
    }
 }
 /* Schurr recursion */
 for (y=1; y<=ord; y++)
 {
   if (p[0] < fabs (p[1]))
    {
      for (i=y; i<=ord; i++)
      {
        r[i] = 0;
      }
      for (bid=1; bid <=ord; bid++)
      {
           SETFLOAT (&schur->x_parcors[bid-1],r[bid]);
        //        x->x_parcors[bid-1] = r[bid];
      }
    }
    r[y] = fabs(p[1])/p[0];

    if (p[1] >0)
    {
      r[y] = -1.*r[y];
    }
    if (y==ord)
    {
      for (bid=1; bid <=ord; bid++)
      {
           SETFLOAT (&schur->x_parcors[bid-1],r[bid]);
        //        x->x_parcors[bid-1] = r[bid];
      }
    }
    p[0] += p[1]*r[y];

    for (z=1; z <=ord-y; z++)
    {
      p[z]        = p[z+1] + k[ord+1-z]*r[y];
      k[ord+1-z] += p[z+1] * r[y];
    }
 }
 for (bid=1; bid <=ord; bid++)
 {
   SETFLOAT (&schur->x_parcors[bid-1],r[bid]);
 }
 parcor_1 = atom_getfloatarg(0,ord,schur->x_parcors); /* in order to avoid nil coefficients */
 if (parcor_1 > 1e-5 || parcor_1 < -1e-5)
   {
     outlet_list(x->parcor_list,gensym("list"),ord,schur->x_parcors);

 /* Analysis FIR lattice filtering */
     for (g=0; g<n; g++)
    {

   /* Analysis - Lattice structure */
      sav = di = in[g];
      for (i=0; i<ord; i++)
        {
          t_float parcor = atom_getfloatarg (i,ord,schur->x_parcors);
          SETFLOAT (&schur->x_last_parcors[i],parcor);
          x->x_lastorder = ord;
          temp = mem[i] + parcor*di;
          di += parcor*mem[i];
          mem[i] = sav;
          sav = temp;
        }
      res[g] = di;

      }  /* next g */
   }
 else
   {
     outlet_list(x->parcor_list,gensym("list"),l_ord,schur->x_last_parcors);
     for (g=0; g<n; g++)
    {
      res[g] = 0;
    }
   }
 return(w+4);
}

void *lpc_tilde_dsp(t_lpc_tilde *x, t_signal **sp)
{
 x->x_schur.c_input = sp[0]->s_vec;
 x->x_schur.c_residual = sp[1]->s_vec;
 dsp_add(lpc_tilde_perform, 3, x, &x->x_schur, sp[0]->s_n);
 return (void *)x;
}

void *lpc_tilde_new(t_floatarg f)
{
 t_lpc_tilde *x = (t_lpc_tilde *)pd_new(lpc_tilde_class);
 x->x_order = f >= 1 ? (int)f : 5;

 floatinlet_new(&x->x_obj,&x->x_order);
 outlet_new(&x->x_obj, &s_signal);
 x->parcor_list = outlet_new(&x->x_obj, &s_list);
 return (void *)x;
}

void lpc_tilde_setup(void)
{
 lpc_tilde_class = class_new(gensym("lpc~"), (t_newmethod)lpc_tilde_new, 0, sizeof(t_lpc_tilde), CLASS_DEFAULT, A_DEFFLOAT, 0);

 post("\n. . Linear Predictive Coding. . . . . . . .");
 post(". . PARCOR coefficients from input. . . . .");
 post(". . by Nicolas Chetry <okin@altern.org> . .");
 post(". & Edward Kelly <morph_2016@yahoo.co.uk> .");

 class_addmethod(lpc_tilde_class, (t_method)lpc_tilde_dsp, gensym("dsp"), 0);


 CLASS_MAINSIGNALIN(lpc_tilde_class, t_lpc_tilde, f_dummy);
}

Comme vous pouvez le voir, au début de la fonction lpc_tilde_perform, il y a un moment une suite de déclarations de tableaux ( qui commence par "float acf[ord+1]") qui seraient fausses car il y en argument un entier non constant.

Est-ce que c'est bien une erreur ? Si oui, comment la réparer ? Et sinon, pourquoi ?

Merci d'avance pour votre aide.

Hors ligne

 

#2 2013-05-24 10:34:19 Re : External lpc~ : problème de syntaxe

jyg
membre
Lieu: montreuil
Date d'inscription: 2008-11-28
Messages: 143
Site web

Re: External lpc~ : problème de syntaxe



bonjour,
Le pb semble effectivement  venir de l'allocation dynamique de l'espace mémoire des tableaux.
A ta place je définirais une constante MAX_ORDER avec une valeur suffisament élevée pour ne jamais être atteinte en pratique (10000 ? ). et je ferais l'allocation des tableaux avec cette valeur. C'est gâcher un peu de l'espace mémoire, mais c'est pas très grave non plus.

float acf[MAX_ORDER];
 float k[MAX_ORDER];
 float p[MAX_ORDER];
 float r[MAX_ORDER];
 float mem[MAX_ORDER];

et au début dans le constructeur *lpc_tilde_new, je veillerais à ce que x->x_order soit toujours inférieur à
MAX_ORDER -1.

Ce n'est pas très esthétique, mais ça devrait fonctionner.

ça sert à quoi, ce code ?

Dernière modification par jyg (2013-05-24 10:35:37)


J.Y.G.

Hors ligne

 

#3 2013-05-24 11:01:35 Re : External lpc~ : problème de syntaxe

adur0
nouveau membre
Date d'inscription: 2013-05-23
Messages: 3

Re: External lpc~ : problème de syntaxe



Merci pour ta réponse, je pense que je vais faire ça oui.

C'est un external pour effectuer l'analyse LPC d'un signal (http://en.wikipedia.org/wiki/Linear_predictive_coding) : il sort le signal résidu et les coefficients du filtre correspondant aux formants. Idéalement, cela me servirait à analyser les formants dans un signal vocal (je voudrais détecter les voyelles prononcées)

Hors ligne

 

fil rss de cette discussion : rss

Pied de page des forums

Powered by FluxBB

codelab, graphisme & code : emoc / 2008-2024