Main Page | Class List | File List | Class Members

WSOLA4Audiere.H

00001 /* Copyright 2001-2005 Matt Flax <flatmax@ieee.org>
00002    This file is part of MFFM Time Scale Modification for Audio.
00003 
00004    MFFM Time Scale Modification for Audio is free software; you can redistribute
00005  it and/or modify
00006    it under the terms of the GNU General Public License as published by
00007    the Free Software Foundation; either version 2 of the License, or
00008    (at your option) any later version.
00009    
00010    MFFM Time Scale Modification for Audio is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013    GNU General Public License for more details.
00014    
00015    You have received a copy of the GNU General Public License
00016    along with MFFM Time Scale Modification for Audio
00017  */
00018 #ifndef WSOLA4AUDIERE_H
00019 #define WSOLA4AUDIERE_H
00020 
00021 
00022 #include <audiere.h>
00023 #include "WSOLA.H"
00024 
00025 using namespace audiere;
00026 
00027 #define DEF_TAU 1.0
00028 
00029 namespace audiere {
00030 
00055   class WSOLA4Audiere : public RefImplementation<SampleSource> {
00056     
00058     int WSOLARead(int frame_count){
00059       int lastFrame=0;
00060       int framesProcessed=(int)((double)windowSize/2.0/(double)channels);
00061       //exit strategy
00062       if ((wsola->getSourceIndex()/channels+framesProcessed)>input.getEnd()){
00063         std::cout<<"last frame : exit as you wish"<<endl;
00064         lastFrame=1;
00065         //input-=framesProcessed;
00066         //setPosition(getLength());
00067         //              reset();
00068         //      return 0;
00069         std::cout<<"input.getEnd() "<<input.getEnd()<<"wsola->getSourceIndex()/channels "<<wsola->getSourceIndex()/channels<<endl;
00070         framesProcessed=input.getEnd()-wsola->getSourceIndex()/channels;
00071         std::cout<<"last frame : "<<framesProcessed<<" frames dropped"<<endl;
00072         if (lastFrameCallback)
00073           lastFrameCallback(callBackData);
00074         //                              if (callBackData)
00075         //                                      ::SendMessage((HWND)callBackData, WM_MESSAGETOAMIS, amis::AUDIO_CLIP_FINISHED, 0);
00076         return 0;
00077       }
00078       
00079       if (firstFrame){
00080         std::cout<<"firstFrame"<<endl;
00081         //load the input data to the buffer and then to wsola
00082         m_source->setPosition(wsola->getSourceIndex()/channels);//seek to the correct location
00083         int readCnt=m_source->read(wsola->getSourceLength()/channels, &(*input.window)[0]);
00084         //std::cout<<"read "<<readCnt<<" frames from the source : wanted "<<wsola->getSourceLength()/channels<<" frames"<<endl;
00085         wsola->initProcess(&(*input.window)[0], tau);
00086         //std::cout<<"wsola->getSourceLength() "<<wsola->getSourceLength()<<endl;
00087         //std::cout<<"readCnt="<<readCnt<<endl;
00088         firstFrame=0;
00089       }
00090       
00091       //load the input data to the buffer and then to wsola
00092       m_source->setPosition(wsola->getSourceIndex()/channels);//seek to the correct location
00093       //std::cout<<"here"<<endl;
00094       int readCnt;
00095       readCnt=m_source->read(wsola->getSourceLength()/channels, &(*input.window)[0]);
00096       //std::cout<<"read "<<readCnt<<" frames from the source : wanted "<<wsola->getSourceLength()/channels<<" frames"<<endl;
00097       wsola->loadSourceInput(&(*input.window)[0]);
00098       
00099       //Load desired input data
00100       m_source->setPosition(wsola->getDesiredIndex()/channels);//seek to the correct location
00101       readCnt=m_source->read(wsola->getDesiredLength()/channels, &(*input.window)[0]);
00102       
00103       wsola->loadDesiredInput(&(*input.window)[0]);
00104       
00105       //Process outputting to the local memory buffer 
00106       int ret=wsola->processFrame(output, tau); //process halfWindow
00107       if (ret<0){
00108         if (ret==WSOLA::INPUT_READ2DF_ERR)
00109           std::cout<<"Destination frame read error, most probably using a factor >=1.0 and at the end of the input file"<<endl;
00110         else if (ret==WSOLA::INPUT_READ2SF_ERR)
00111           std::cout<<"Source frame read error, most probably using a factor <1.0, and at the end of the input file"<<endl;
00112         else if (ret==WSOLA::WRITE_ERR)
00113           std::cout<<"Is your disk full, we encountered a write error"<<endl;
00114         else if (ret==WSOLA::PROCFFT_ERR)
00115           std::cout<<"Please contact the author - this error shouldn't occur."<<endl;
00116         else if (ret==WSOLA::DEFAULT_ERR)
00117           std::cout<<"Un-known default error encountered"<<endl;
00118         else //Handle other errors here
00119           std::cout<<"Unknown error - unreliable failure"<<endl;
00120       }
00121       
00122       if (lastFrame)
00123         reset();
00124       //        return WSOLA::FINISHED_NORMALLY;
00125       
00126       //std::cout<<input<<endl;
00127       return framesProcessed;
00128     }
00129   public:
00130     
00137     WSOLA4Audiere(SampleSourcePtr source, double ta=DEF_TAU, int startPoint=0, int endPoint=0, void (*lastFrameCallback_in)(void *)=NULL, void *callBackData_in=NULL) {
00138       m_source=source;
00139       if(source){
00140         source->getFormat(channels,fs,mSampleFormat);
00141         std::cout<<"file length is : "<<source->getLength()<<endl;
00142       } else {
00143         std::cout<<"WSOLA4Audiere(SampleSourcePtr source) : source doesn't exist !"<<endl;
00144         exit(-1);
00145       }
00146       
00147       //check source is seekable
00148       if (!m_source->isSeekable()){
00149         std::cout<<"WSOLA4Audiere(SampleSourcePtr source) : source is not seekable.\nspeed change may not work !"<<endl;
00150       }
00151       
00152       windowSize =channels*HANNING_LENGTH(fs);
00153       std::cout<<"windowSize="<<windowSize<<endl;
00154       // Make sure that the half window size is an integer number of channels
00155       while (remainder((double)windowSize /2.0/(double)channels, floor((double)windowSize /2.0/(double)channels)) != 0.0){
00156         windowSize ++;
00157       }
00158       std::cout<<"windowSize="<<windowSize<<endl;
00159       tau = ta;
00160       firstFrame = 1;
00161       wsola=0;
00162       wsola = new WSOLA (windowSize, fs, channels);//Version 2 instantiation;   
00163       if (!wsola){
00164         std::cout<<"WSOLA4Audiere(SampleSourcePtr source) : couldn't instantiate WSOLA"<<endl;
00165         exit(-1);
00166       }
00167       
00168       output=NULL; //Null the input / output buffers
00169       
00170       //Reserve local memory stores
00171       
00172       //set the input time code which holds the length of the audio
00173       // as well as the beginning, current and end locations
00174       // as well as a window for the input data
00175       input.init(startPoint,m_source->getLength()+1); //the point we want to start from
00176       setPosition(startPoint);
00177       (*input.window)=wsola->getSourceLength(); //Set the window size
00178       input.setFinish(m_source->getLength()+1); //Set the absolute length
00179       //std::cout<<input<<endl;
00180       //std::cout<<"endpoint "<<endPoint<<endl;
00181       if (endPoint!=0)//Guard against dummy entry
00182         if (endPoint<=input.getFinish()-1)
00183           input.setEnd(endPoint); //the point we want to end at
00184         else
00185           input.setEnd(input.getFinish()-1); //Force end at end of stream
00186       //This is default ...
00187       //input.setBeginning(0); //starts at zero time
00188       std::cout<<"input:\n"<<input<<endl;
00189       
00190       //Set up the output array
00191       output = new ATYPE[windowSize]; //The output store
00192       if (output==NULL){
00193         std::cout<<"error defining output memory"<<endl;
00194         exit(-2);
00195       }
00196       
00197       //set up the callback funciton
00198       lastFrameCallback=lastFrameCallback_in;
00199       callBackData=callBackData_in;
00200     }
00201     
00203     ~WSOLA4Audiere(){
00204       if (wsola) delete wsola; wsola=NULL;
00205       if (output) delete [] output; output=NULL;
00206     }
00207     
00209     void ADR_CALL getFormat(int& channel_count, int& sample_rate, SampleFormat& sample_format){
00210       m_source->getFormat(channel_count,sample_rate,sample_format);
00211       std::cout<<"channel_count,sample_rate,sample_format"<<channel_count<<'\t'<<sample_rate<<'\t'<<sample_format<<endl;
00212       if (GetSampleSize(sample_format)!=wsola->getFrameSize())
00213         printf("Difference between Audiere (%d bytes) and WSOLA (%d bytes) frame sizes ... should be OK as long as WSOLA > Audiere",GetSampleSize(sample_format),wsola->getFrameSize());
00214     }
00215     
00217     int ADR_CALL read(int frame_count, void* buffer) {
00218       //std::cout<<"request frame_count "<<frame_count<<endl;
00219       int framesProcessed=0, realSize=(int)((double)windowSize/2.0/(double)channels);
00220       //std::cout<<"framesProcessed "<<framesProcessed<<" realSize "<<realSize<<endl;
00221       while ((framesProcessed+realSize)<frame_count){
00222         int oneCycleCnt=WSOLARead(realSize);
00223         if (oneCycleCnt>0){
00224           memcpy(&((ATYPE*)buffer)[framesProcessed*channels], output,oneCycleCnt*channels*sizeof(ATYPE));
00225           framesProcessed+=oneCycleCnt;
00226         } else
00227           break;
00228       }
00229       //std::cout<<"returning "<<framesProcessed<<" wanted "<<frame_count<<endl;
00230       return framesProcessed;
00231     }
00232     
00234     void ADR_CALL reset() {
00235       m_source->reset();
00236       wsola->reset();
00237     }
00238     
00240     bool ADR_CALL isSeekable() {
00241       return m_source->isSeekable();
00242     }
00244     int  ADR_CALL getLength() {
00245       return m_source->getLength();
00246     }
00247     
00249     void ADR_CALL setPosition(int position){
00250       m_source->setPosition(position);
00251       wsola->setPosition(position*channels);
00252       input=position;
00253     }
00254     
00256     int  ADR_CALL getPosition(){
00257       std::cout<<"getpos"<<endl;
00258       //return input.getCount();
00259       return m_source->getPosition();
00260     }
00261     
00263     bool ADR_CALL getRepeat() {
00264       return m_source->getRepeat();
00265     }
00267     void ADR_CALL setRepeat(bool repeat){
00268       m_source->setRepeat(repeat);
00269     }
00271     void  setTau(float ta) {
00272       std::cout<<"setTau "<<ta<<endl;
00273       this->tau = ta;
00274       std::cout<<"tau is now "<<this->tau<<endl;
00275     }
00277     float getTau(){
00278       return tau;
00279     }
00280     
00282     int getTagCount() {return m_source->getTagCount();}
00284     const char* getTagKey(int i) {return m_source->getTagKey(i);}
00286     const char* getTagValue(int i) {return m_source->getTagValue(i);}
00288     const char* getTagType(int i) {return m_source->getTagType(i);}
00289     
00290   private:
00292     SampleSourcePtr m_source;
00293     
00295     WSOLA *wsola;
00296     
00298     int channels;
00300     int fs;
00302     SampleFormat mSampleFormat;
00304     int windowSize;
00305     
00307     float tau;
00309     int firstFrame;
00310     
00312     TIMECODETYPE_W input;
00314     ATYPE *output;
00315     
00316   public:
00320     void (*lastFrameCallback)(void *);
00322     void *callBackData;
00323   };
00324 }
00325 #endif

Generated on Thu Apr 21 00:33:47 2005 by  doxygen 1.4.2