⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mp_notes.c

📁 LastWave
💻 C
📖 第 1 页 / 共 2 页
字号:
/*..........................................................................*//*                                                                          *//*      L a s t W a v e    P a c k a g e 'mp' 2.1                           *//*                                                                          *//*      Copyright (C) 2000 Remi Gribonval, Emmanuel Bacry and Javier Abadia.*//*      email  : remi.gribonval@inria.fr                                    *//*      email  : lastwave@cmap.polytechnique.fr                             *//*                                                                          *//*..........................................................................*//*                                                                          *//*      This program is a 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 (in a file named COPYRIGHT);                *//*      if not, write to the Free Software Foundation, Inc.,                *//*      59 Temple Place, Suite 330, Boston, MA  02111-1307  USA             *//*                                                                          *//*..........................................................................*/ #include "lastwave.h"#include "mp_book.h"/* javi: dealing with notes */typedef struct note{    LWFLOAT onset;    LWFLOAT end;    LWFLOAT pitch;} *NOTE;extern void   	Notes(BOOK book,int nMin,int nMax,NOTE *note);extern int	SearchNote(BOOK book,ATOM mainAtom,int numAtom,int *flagNotes,LWFLOAT *pp, LWFLOAT * bb, LWFLOAT * ee);extern void 	ComputeEnergyProfile(BOOK book,ATOM mainAtom,SIGNAL energyProfile);extern int	MarkAtoms(BOOK book,ATOM mainAtom,int numAtom,int *flagNotes,LWFLOAT * begin,LWFLOAT end);extern void 	NotesSynthesis(NOTE *note,SIGNAL synthesis,BOOK book,int attack);extern void 	AddAtomEnergyEnvelope(SIGNAL energyEnvelope,ATOM atom,ATOM mainAtom);extern void	GetBestPartial(MOLECULE molecule,ATOM bestPartial);extern void	GetFundamental(MOLECULE molecule,ATOM bestPartial);extern void 	GetNearestPartial(MOLECULE molecule,ATOM mainAtom,ATOM nearestPartial);extern void 	GetBeginEndNote(SIGNAL energyProfile,ATOM atom,LWFLOAT energyTh,LWFLOAT *beginNote,LWFLOAT *endNote,LWFLOAT *endMark);extern LWFLOAT 	GetEnergyMax(SIGNAL energyProfile,ATOM atom);extern NOTE 	NewNote(void); extern void 	DeleteNote(NOTE note); // The parameters for the note detection algorithmstatic LWFLOAT minNoteDuration = 0.03; /* Delta t_min : minimum duration of the notes */static LWFLOAT stopCoeff2Ratio = 0.01; /* ?? When to stop in the book */static LWFLOAT maxFundRatio    = 0.03; /* ?? Minimum energy of the fundamental (compared to the most energetic one) */static LWFLOAT thresholdNoteDB = -14;  /* theta_beg = theta_end :					Used to find begining and end of a note */static LWFLOAT freqSigmaFact = 8;      /* Controls the bandwidth (in Hertz)				      * of a FoF at octave 12 (windowSize 4096)				      * and sampling frequency 16000 */static LWFLOAT markRatio = 0.00002;    /* Controls how different from the				      * fundamental frequency the frequency				      * of a marked atom can be */static LWFLOAT deltaFreq = 5;NOTE NewNote(void)  {  NOTE notes;#ifdef DEBUGALLOC  DebugType = "Note";#endif  notes = (NOTE) Malloc(sizeof(struct note));  notes->onset = 0.0;  notes->end = 0.0;  notes->pitch = 0.0;	   return(notes);} void DeleteNote(NOTE n){#ifdef DEBUGALLOC  DebugType = "Note";#endif  Free(n);}// COMMANDvoid C_Notes(char **argv)    		{  int nMax,nMin;  BOOK book = NULL;  NOTE note[500],*note1;  char flagSynthesis;  int i;  char opt;  SIGNAL synSig;  char **list,**list1;  int attack;    LISTV reslist;  LISTV res;  argv = ParseArgv(argv,tBOOK,&book,-1);  CheckBookNotEmpty(book);    /* Default values */  nMin = 0;  nMax = book->size-1;  flagSynthesis = NO;  /* Reading options */  while(( opt = ParseOption(&argv))) {    switch(opt) {    case 'n' : /* nMin nMax */      argv = ParseArgv(argv,tINT,&nMin,tINT_,-1,&nMax,-1);      if(nMax == -1)	nMax = nMin;      break;    case 's' : /* synthesis of the notes */      argv = ParseArgv(argv,tSIGNAL,&synSig,tINT_,1000,&attack,tLIST,&list,-1);      flagSynthesis = YES;      break;    default :       ErrorOption(opt);    }  }  NoMoreArgs(argv);/*    Printf("nMin:%d , nMax:%d\n",nMin,nMax); */    // Synthesis if asked  if (flagSynthesis) {    note1 = note;    while (*list) {      *note1 = NewNote();      ParseList(*list,&list1);      ParseArgv(list1,tFLOAT,&((*note1)->pitch),tFLOAT,&((*note1)->onset),tFLOAT,&((*note1)->end),0);      note1++;      list++;    }    *note1 = NULL;    NotesSynthesis(note,synSig,book,attack);    for (i=0;note[i]!=NULL;i++) {      DeleteNote(note[i]);    }    return;  }  // Computing the notes from the molecules of the book  Notes(book,nMin,nMax,note);   // Setting the resulting list  reslist = TNewListv();  for (i=0;note[i]!=NULL;i++) {    res = TNewListv();    AppendFloat2Listv(res,note[i]->pitch);    AppendFloat2Listv(res,note[i]->onset);    AppendFloat2Listv(res,note[i]->end);    AppendValue2Listv(reslist,(VALUE)res);    DeleteNote(note[i]);  }}static     int *blackList = NULL;void Notes(BOOK book,int nMin,int nMax,NOTE *note){  unsigned long n;  int i;  int minOctave;  int flagNote = NO;  LWFLOAT maxMoleculeCoeff2,maxFundCoeff2;  static MOLECULE molecule = NULL;  static ATOM fundamental = NULL;  int noteNum;  LWFLOAT pp,ee,bb;  noteNum = 0;  note[0] = NULL;  CheckBookNotEmpty(book);  /* Initializing */  if (fundamental == NULL) {    fundamental = NewAtom();    molecule = NewMolecule();  }  if (blackList != NULL) Free(blackList);  blackList = IntAlloc(book->size);  for (i = 0;i < book->size;i++) *(blackList + i) = 0;  minOctave = (int) floor(log(floor(minNoteDuration/(book->dx)))/log(2));  Printf("minOctave:%d\n",minOctave);  molecule = GetBookMolecule(book,0);  GetFundamental(molecule,fundamental);   maxMoleculeCoeff2 = molecule->coeff2;  maxFundCoeff2 = fundamental->coeff2;   /* Main loop to search notes */  for (n=nMin; n<=nMax; n++) {    if (*(blackList+n-1)) continue;    molecule = GetBookMolecule(book,n);    // Condition to stop the notes search    if ( molecule->coeff2 < maxMoleculeCoeff2*stopCoeff2Ratio ) break;       // Else we take the fundamental in the current molecule    GetFundamental(molecule,fundamental);    // We don't take into account small atoms    /* ????? bof */    if (fundamental->windowSize <= 1<<minOctave) continue;    if (fundamental->coeff2 < maxFundCoeff2*maxFundRatio) continue;    /* ShortPrintAtom(fundamental); */    Printf("ATOM:%d ->\n",n);    flagNote = SearchNote(book,fundamental,n,blackList,&pp,&bb,&ee);    if (!flagNote) continue;    if (ee-bb < minNoteDuration ) {      Printf("\tToo small!\n");      continue;    }    Printf(" NOTE:%d (pitch:%f, begin:%f, end:%f)\n",noteNum+1,pp,bb,ee);            note[noteNum] = NewNote();    note[noteNum]->onset = bb;    note[noteNum]->end   = ee;    note[noteNum]->pitch = pp;    noteNum++;    note[noteNum] = NULL;  }}void NotesSynthesis(NOTE *note,SIGNAL synthesis,BOOK book,int attack){   int i,j;  int begin,end;  LWFLOAT dx;      SizeSignal(synthesis,book->signalSize,YSIG);  ZeroSig(synthesis);  synthesis->dx = book->dx;  synthesis->x0 = book->x0;  dx = synthesis->dx;    for (i=0;note[i]!=NULL;i++) {    begin 	= (int) ((note[i]->onset)/dx);    end 	= (int) ((note[i]->end)/dx);    for (j=begin;j<=begin+attack;j++) {      synthesis->Y[j] += (1-cos(0.5*M_PI*(j-begin)/((LWFLOAT) attack)))*sin(2*M_PI*(note[i]->pitch)*j*dx);    }    for (;j<=end-attack;j++) {      synthesis->Y[j] += sin(2*M_PI*(note[i]->pitch)*j*dx);    }    for (;j<=end;j++) {      synthesis->Y[j] += (1-cos(.5*M_PI*(end-j)/((LWFLOAT) attack)))*sin(2*M_PI*(note[i]->pitch)*j*dx);    }  }}int SearchNote(BOOK book,ATOM mainAtom,int numAtom,int *flagNotes,LWFLOAT *pp, LWFLOAT * bb, LWFLOAT * ee){  static SIGNAL energyProfile = NULL;    int foundAtoms;  LWFLOAT pitchNote,pitchNoteId;  LWFLOAT beginNote,endNote;  LWFLOAT beginNoteId,endNoteId,endMarkId;      /* Init the energy profile signal */  if (energyProfile == NULL) energyProfile = NewSignal();  /* Compute the energy profile */  ComputeEnergyProfile(book,mainAtom,energyProfile);      /* we find the onset and the end of the note taking into account a threshold of energy */  GetBeginEndNote(energyProfile,mainAtom,thresholdNoteDB,&beginNoteId,&endNoteId,&endMarkId);    pitchNote =  FreqId2Freq(mainAtom,mainAtom->freqId);  pitchNoteId = mainAtom->freqId;  beginNote =  mainAtom->dx*beginNoteId;  endNote   =  mainAtom->dx*endNoteId;    /*    Printf("\tNOTE:( pitch: %f(%d), begin: %f(%d), end: %f(%d) )\n",pitchNote,(int)(mainAtom->freqId),beginNote,(int)(beginNoteId),endNote,(int)(endNoteId)); */  *pp = pitchNote;  *bb = beginNote;  *ee = MAX(endNote,beginNote+mainAtom->dx*0.5*mainAtom->windowSize);        /* look for atoms which seem to belong to the same note */   foundAtoms = MarkAtoms(book,mainAtom,numAtom,flagNotes,&beginNoteId,endMarkId);  Printf("foundAtoms:%d\n",foundAtoms);       if (foundAtoms > 0) {     Printf("\n");    return(YES);  }  else {    Printf("\t\tNOT A NOTE!\n");    return(NO);  }}void ComputeEnergyProfile(BOOK book,ATOM mainAtom,SIGNAL energyProfile){  static ATOM partial = NULL;  static MOLECULE moleculeSearch = NULL;   unsigned long n;  int i;  LWFLOAT energyMax;    // Allocation (once)  if (partial == NULL) {    partial    = NewAtom();    moleculeSearch = NewMolecule();  }    // Initialize the energyProfile  SizeSignal(energyProfile,book->signalSize,YSIG);  energyProfile->dx = book->dx;  energyProfile->x0 = book->x0;  for (i = 0; i <energyProfile->size; i++) energyProfile->Y[i] = 1e-7;    /* Now we add the envelope of the others atoms with a frequency correction */  for (n = 0; n<book->size; n++) {    moleculeSearch = GetBookMolecule(book,n);    /* we take the best partial in this molecule  */    GetNearestPartial(moleculeSearch,mainAtom,partial);    /* we add the envelope of the best partial */    AddAtomEnergyEnvelope(energyProfile,partial,mainAtom);	  }  /* linear -> dB */  energyMax = GetEnergyMax(energyProfile,mainAtom);  for (i = 0; i <energyProfile->size; i++)    energyProfile->Y[i] = 10*log10(energyProfile->Y[i]/energyMax);}  /* COMMAND */void C_CreateProfile(char **argv){  BOOK book;  SIGNAL signal;  unsigned long n;  MOLECULE molecule;  static ATOM atom = NULL;  LWFLOAT delta;  LWFLOAT begin,end,end1;  if (atom == NULL) {    atom    = NewAtom();  }    argv = ParseArgv(argv,tBOOK,&book,tSIGNAL,&signal,tINT,&n,tFLOAT_,deltaFreq,&delta,0);  deltaFreq = delta;    molecule = GetBookMolecule(book,n);  GetFundamental(molecule,atom);  ComputeEnergyProfile(book,atom,signal);  GetBeginEndNote(signal,atom,thresholdNoteDB,&begin,&end,&end1);//  /*signal->Y[(int) (begin+.5)] = 10;     signal->Y[(int) (end+.5)] = 10; */}int MarkAtoms(BOOK book,ATOM mainAtom,int numAtom,int *flagNotes,LWFLOAT * beginNoteId,LWFLOAT endNoteId){  static ATOM partial = NULL;  static MOLECULE moleculeSearch = NULL;     static ATOM fund = NULL;       unsigned long n;  int timesFreq;  int foundAtoms;  int partialSize;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -