?? mp_stft.c
字號:
/*..........................................................................*//* *//* L a s t W a v e P a c k a g e 'mp' 2.1 *//* *//* Copyright (C) 2002 Remi Gribonval. *//* 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"extern SUBDICT NewSubDict();extern SUBDICT PrivateAddSubDict(DICT dict,SUBDICT subDict);/************************************************************************//* * This part is specific to STFT sub-dictionaries * TODO : help on these functions *//************************************************************************//* * Setting/Getting a STFT sub-dictionary */// Get a sub-dictionary that contains a stft with given {type,windowShape,windowSize}// If none exists, return NULL.// TODO : add a listv parameter that will contain Harmo/HighRes additional parametersSUBDICT GetStftSubDict(DICT dict,unsigned char channel,char type,char windowShape,unsigned long windowSize,LISTV options) { unsigned short i; SUBDICT subDict; STFT stft; // Basic checking if(options!=NULL && type!=HarmoStft && type!=HighResStft) Errorf("GetStftSubDict : non NULL options for '%s' &stft",StftType2Name(type)); /* Does such a subDict exist ? */ for(i = 0; i < dict->size; i++) { subDict = dict->subDicts[i]; if(subDict->channel!=channel) continue; if(GetTypeValue(subDict->dataContainer)!=stftType) continue; stft = (STFT)(subDict->dataContainer); if(stft->type != type) continue; if(stft->windowShape != windowShape) continue; if(stft->windowSize != windowSize) continue; // TODO : treat case where there are additional options if(options != NULL) { switch(type) { case HarmoStft : case HighResStft : Errorf("GetStftSubDict : options not treated for '%s' sub-dictionaries yet",StftType2Name(type)); } } return(subDict); } return(NULL);}// Add a stft sub-dictionary (does NOT check whether it already exists)SUBDICT PrivateAddStftSubDict(DICT dict,unsigned char channel,char flagMain, char type,char windowShape,unsigned long windowSize,LISTV harmoOptions) { STFT stft; SUBDICT subDict; unsigned short i; unsigned char n; // Some default values for the moment char borderType = BorderPad0; char depthHighRes = 0; unsigned short timeRedund=STFT_DEFAULT_TIMEREDUND ,freqRedund = STFT_DEFAULT_FREQREDUND; char flagHarmonic = NO; LWFLOAT freq0Min = 0,freq0Max = 0; LWFLOAT freq0IdMin = 0,freq0IdMax = 0; unsigned short dim = STFTHARMO_DEFAULT_DIMHARMO; unsigned char iFMO = STFTHARMO_DEFAULT_IFMO; // Some basic checking // Basic checking if(channel>dict->nChannels) Errorf("PrivateAddStftSubDict : channel is too big"); if(harmoOptions==NULL&&type==HarmoStft) Errorf("PrivateAddStftSubDict : NULL harmoOptions for 'harmo' &stft"); if(harmoOptions!=NULL) { if(type!=HarmoStft) Errorf("PrivateAddStftSubDict : non NULL harmoOptions for '%s' &stft",StftType2Name(type)); if(GetTypeValue(harmoOptions)!=listvType || harmoOptions->length<2) Errorf("PrivateAddStftSubDict : bad harmoOptions",StftType2Name(type)); } // Do we need some auxiliary sub-dicts first ? // It is better to put them first in the list if they do not exist already ! switch(type) { case ComplexStft : if(channel==dict->nChannels) Errorf("PrivateAddStftSubDict : multichannel ComplexStft do not exist!"); break; case PhaseStft : if(channel==dict->nChannels) Errorf("PrivateAddStftSubDict : multichannel PhaseStft do not exist!"); if(GetStftSubDict(dict,channel,ComplexStft,windowShape,windowSize,NULL)==NULL) PrivateAddStftSubDict(dict,channel,NO,ComplexStft,windowShape,windowSize,NULL); break; case RealStft : // Case of a monochannel RealStft if(channel<dict->nChannels) { if(GetStftSubDict(dict,channel,ComplexStft,windowShape,windowSize,NULL)==NULL) PrivateAddStftSubDict(dict,channel,NO,ComplexStft,windowShape,windowSize,NULL); } else { // Case of multichannel RealStft (the sum of monochannel ones) for(n = 0; n < dict->nChannels; n++) { if(GetStftSubDict(dict,n,RealStft,windowShape,windowSize,NULL)==NULL) PrivateAddStftSubDict(dict,n,NO,RealStft,windowShape,windowSize,NULL); } } break; case HarmoStft : if(dict->nChannels>1 && channel!=dict->nChannels) Errorf("PrivateAddStftSubDict (Weired) : monochannel HarmoStft do not exist in multichannel dictionaries!"); if(GetStftSubDict(dict,channel,RealStft,windowShape,windowSize,NULL)==NULL) // When we add a harmonic sub-dictionary as a main dictionary, a plain Gabor // sub-dictionary with the same window should also be included as a main sub-dictionary PrivateAddStftSubDict(dict,channel,flagMain,RealStft,windowShape,windowSize,NULL); break; case HighResStft : Errorf("PrivateAddStftSubDict : highres not implemented (depthHighRes not parameter..."); if(channel<dict->nChannels) { if(GetStftSubDict(dict,channel,RealStft,windowShape,windowSize/2,NULL)==NULL) PrivateAddStftSubDict(dict,channel,NO,RealStft,windowShape,windowSize/2,NULL); if(GetStftSubDict(dict,channel,RealStft,windowShape,windowSize,NULL)==NULL) PrivateAddStftSubDict(dict,channel,NO,RealStft,windowShape,windowSize,NULL); if(GetStftSubDict(dict,channel,PhaseStft,windowShape,windowSize/2,NULL)==NULL) PrivateAddStftSubDict(dict,channel,NO,PhaseStft,windowShape,windowSize/2,NULL); if(GetStftSubDict(dict,channel,PhaseStft,windowShape,windowSize,NULL)==NULL) PrivateAddStftSubDict(dict,channel,NO,PhaseStft,windowShape,windowSize,NULL); } // TODO : decide what should be done about multichannel HighRes ? break; default : Errorf("Stft of type '%s' cannot be added to a &dict",StftType2Name(type)); } // Now it is time to add the stft we asked for stft = NewStft(); CopyFieldsTFContent(dict,stft); switch(type) { case ComplexStft : case RealStft: case PhaseStft: SizeStft(stft,windowShape,windowSize,timeRedund,freqRedund,borderType,type,0,0,0,0); break; case HarmoStft: // First we should parse the harmonic options TODO: parse dim and iFMO too if given! if(harmoOptions->length!=2) Errorf("PrivateAddStftSubDict : bad harmo options"); freq0Min = GetListvNthFloat(harmoOptions,0); freq0Max = GetListvNthFloat(harmoOptions,1); freq0IdMin = Freq2FreqId(stft,freq0Min); freq0IdMax = Freq2FreqId(stft,freq0Max); SizeStft(stft,windowShape,windowSize,timeRedund,freqRedund,borderType,type,freq0IdMin,freq0IdMax,iFMO,dim); // There are cases where, due to the orthogonality condition between partials of harmonic atoms, the // 'harmo' stft is empty. Then we don't add it! // TODO : clean that ? if(stft->real==NULL) {#ifdef DEBUG_HARMO Warningf("AddStftSubDict : deleting empty 'harmo' stft");#endif // DEBUG_HARMO stft = DeleteStft(stft); return(NULL); } break; case HighResStft: SizeStft(stft,windowShape,windowSize,timeRedund,freqRedund,borderType,type,0,0,0,0); break; } // Now we can create a new sub-dictionary with 'stft' as data content subDict = NewSubDict(); subDict->methods = &StftMethods; subDict->flagMain = flagMain; subDict->channel = channel; subDict->dataContainer = (VALUE)stft; // In the next update of the dictionary, the newly added STFT sub-dictionary // will have to be updated, so we need to to reset [updateTimeIdMin updateTimeIdMax] dict->updateTimeIdMin = 0; dict->updateTimeIdMax = dict->signalSize-1; return(PrivateAddSubDict(dict,subDict));}void UpdateStftSubDict(SUBDICT subDict){ STFT stft = (STFT)(subDict->dataContainer); DICT dict = subDict->dict; SUBDICT subDictAux; STFT stftAux = NULL,stftAux1 = NULL,stftAux2 = NULL,stftAux3 = NULL; unsigned char n; short scaleFactorHighRes = 2; // Some checking if(GetTypeValue(stft)!=stftType) Errorf("UpdateStftSubDict (Weired) : data is not of type '%s'!",stftType); // If already up to date, do nothing if(subDict->flagUpToDate) return; // If we have something to do, it depends on the type of the stft switch(stft->type) { case ComplexStft :// Printf("[C]"); UpdateStftComplex(stft,GetChannel(dict,subDict->channel),dict->updateTimeIdMin,dict->updateTimeIdMax);// XXTerminalCursorGoBackward(3); break; case PhaseStft: // Update the auxiliary sub-dictionaries first if((subDictAux = GetStftSubDict(dict,subDict->channel,ComplexStft,stft->windowShape,stft->windowSize,NULL))==NULL) Errorf("UpdateStftSubDict (Weired) : missing auxiliary sub-dictionary ComplexStft for PhaseStft"); UpdateSubDict(subDictAux); stftAux = (STFT)subDictAux->dataContainer; // Update the asked sub-dictionary now// Printf("[R]"); UpdateStftRealOrPhase(stft,stftAux,dict->updateTimeIdMin,dict->updateTimeIdMax);// XXTerminalCursorGoBackward(3); break; case RealStft: // Case of monochannel RealStft if(subDict->channel<dict->nChannels) { // Update the auxiliary sub-dictionaries first if((subDictAux = GetStftSubDict(dict,subDict->channel,ComplexStft,stft->windowShape,stft->windowSize,NULL))==NULL) Errorf("UpdateStftSubDict (Weired) : missing auxiliary sub-dictionary ComplexStft for RealStft"); UpdateSubDict(subDictAux); stftAux = (STFT)subDictAux->dataContainer; // Update the asked sub-dictionary now// Printf("[R]"); UpdateStftRealOrPhase(stft,stftAux,dict->updateTimeIdMin,dict->updateTimeIdMax);// XXTerminalCursorGoBackward(3); } else { // Case of multichannel RealStft ZeroStft(stft,dict->updateTimeIdMin,dict->updateTimeIdMax); for(n = 0; n < dict->nChannels; n++) { // Update the auxiliary sub-dictionaries first if((subDictAux = GetStftSubDict(dict,n,RealStft,stft->windowShape,stft->windowSize,NULL))==NULL) Errorf("UpdateStftSubDict (Weired) : missing auxiliary sub-dictionary RealStft[%d] for Multichannel RealStft",n); UpdateSubDict(subDictAux); stftAux = (STFT)subDictAux->dataContainer; // Update the asked sub-dictionary now// Printf("[MR]"); AddStft(stft,stftAux,dict->updateTimeIdMin,dict->updateTimeIdMax);// XXTerminalCursorGoBackward(3); } } break; case HarmoStft : if(dict->nChannels>1 && subDict->channel!=dict->nChannels) Errorf("UpdateStftSubDict (Weired) : monochannel HarmoStft should not exist in multichannel dictionaries!"); // Update the auxiliary sub-dictionaries first if((subDictAux = GetStftSubDict(dict,subDict->channel,RealStft,stft->windowShape,stft->windowSize,NULL))==NULL) Errorf("UpdateStftSubDict (Weired) : missing auxiliary sub-dictionary RealStft for HarmoStft");
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -