Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

VrAudioDecoder.h

Go to the documentation of this file.
00001 /* -*- Mode: c++ -*- */
00002 /*
00003  * Copyright 2001 Free Software Foundation, Inc.
00004  * 
00005  * This file is part of GNU Radio
00006  * 
00007  * GNU Radio is free software; you can redistribute it and/or modify
00008  * it under the terms of the GNU General Public License as published by
00009  * the Free Software Foundation; either version 2, or (at your option)
00010  * any later version.
00011  * 
00012  * GNU Radio is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  * 
00017  * You should have received a copy of the GNU General Public License
00018  * along with GNU Radio; see the file COPYING.  If not, write to
00019  * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00020  * Boston, MA 02111-1307, USA.
00021  */
00022 /*
00023  *  Copyright 1997 Massachusetts Institute of Technology
00024  * 
00025  *  Permission to use, copy, modify, distribute, and sell this software and its
00026  *  documentation for any purpose is hereby granted without fee, provided that
00027  *  the above copyright notice appear in all copies and that both that
00028  *  copyright notice and this permission notice appear in supporting
00029  *  documentation, and that the name of M.I.T. not be used in advertising or
00030  *  publicity pertaining to distribution of the software without specific,
00031  *  written prior permission.  M.I.T. makes no representations about the
00032  *  suitability of this software for any purpose.  It is provided "as is"
00033  *  without express or implied warranty.
00034  * 
00035  */
00036 
00037 
00038 #ifndef _VrDECODER
00039 #define _VrDECODER
00040 #include <VrDecimatingSigProc.h>
00041 #include <string.h>
00042 #include <../G711_G721_G723/g72x.h>
00043 #if defined (ENABLE_MMX)
00044 #include <VrMMX.h>
00045 #endif
00046 
00047 
00048 // ********************************************************
00049 
00050 // FIXME why is this a subclass of VrDecimatingSigProc and not VrSigProc??? -eb
00051 
00052 
00053 template<class iType> 
00054 class VrAudioDecoder : public VrDecimatingSigProc<iType,iType> {
00055 protected:
00056 
00057 #if defined (ENABLE_MMX)
00058   mmxTaps** processedTaps; //Precomputed constants, shifted four times
00059 #endif
00060 
00061 const int outputBytes=120; //120 is smallest number divisible by 3,4,5,8,
00062 const int headerSize=3;
00063 const int outputBlockSize=outputBytes+headerSize;
00064 
00065 public: 
00066   int outputsize,inputsize;
00067   int num;
00068   short blockNum;
00069   int position;
00070   int enc_bits;
00071   int in_coding;
00072   int difference;
00073   struct g72x_state     state;
00074   int (*dec_routine)(int, int, g72x_state *);
00075 
00076   void choose_decoder(int bits){
00077     enc_bits=bits;
00078     switch (bits){
00079     case 3:
00080        dec_routine = g723_24_decoder;
00081        break;
00082      case 4:
00083        dec_routine = g721_decoder;
00084        break;
00085      case 5:
00086        dec_routine = g723_40_decoder;
00087        break;
00088      }
00089   }
00090   
00091   VrAudioDecoder(){
00092     num=0;      
00093     difference=0;
00094     g72x_init_state(&state);
00095   }
00096 
00097   virtual const char *name() { return "VrAudioDecoder"; }
00098 
00099   virtual int work(VrSampleRange output, iType *o[],
00100                    VrSampleRange inputs[], iType *i[]);
00101 
00102   virtual int forecast(VrSampleRange output,
00103                        VrSampleRange inputs[]);
00104 
00105   virtual void initialize();
00106 
00107 
00108 };
00109 
00110 template<class iType> int
00111 VrAudioDecoder<iType>::forecast(VrSampleRange output,
00112                                            VrSampleRange inputs[]) {
00113   
00114   cout <<"forecast called.  module "<<name()<<endl;
00115   double maxratio=double(5.0)/(double)8.0;
00116 
00117   inputs[0].index=(long unsigned)((int)output.index-difference);
00118 
00119   int numblocks=output.size/outputBlockSize;  
00120 
00121   inputs[0].size=double(output.size)*maxratio*outputBlockSize/outputBytes;
00122   
00123   cout <<"ratio= "<<maxratio<<" to get outputsize of "<<output.size<<" starting at " <<output.index<< " you need "<<inputs[0].size<< " starting at "<<inputs[0].index<<endl;
00124 
00125   cout <<"forecast FINISHED.  module "<<name()<<endl;
00126 
00127   return 0;
00128 
00129 }  
00130 
00131 
00132 template<class iType> int 
00133 VrAudioDecoder<iType>::work(VrSampleRange output, iType *o[], VrSampleRange inputs[], iType *i[]) {
00134 
00135   unsigned int  in_buffer = 0;
00136   int           in_bits = 0;
00137   unsigned char         in_byte;
00138   int code;
00139   cout <<"work called.  module "<<name()<<endl;;
00140   cout <<__FUNCTION__<<" starting output.size ="<<output.size<<"starting output.index "<<output.index<<endl;
00141 
00142   iType *curInPos=i[0],*curOutPos=o[0];
00143   double ratio;
00144   short blocknum=0;
00145   unsigned char outputChar;
00146 
00147   int bytes_read;    
00148   unsigned total_bytes_written=0,total_bytes_read=0;
00149 
00150   while (total_bytes_written<output.size){
00151     choose_decoder((int)*curInPos);
00152     ratio=double(*curInPos)/double(8);
00153     cout <<"using " << ratio<<" ratio "<<total_bytes_written<<" out of "<<output.size<<endl;
00154 
00155     curInPos++;
00156     blocknum=((unsigned char)*curInPos)<<8;
00157     curInPos++;
00158     blocknum|=(unsigned char) *curInPos;
00159     curInPos++;
00160     bytes_read=headerSize;
00161     int written =0;
00162     cout <<"Decoding block "<<blocknum<<endl;
00163 
00164 
00165     while(bytes_read<outputBlockSize|| (in_bits>0)){
00166       if (in_bits < enc_bits) {
00167         in_byte = *(curInPos++);
00168         bytes_read++;
00169         in_buffer |= (in_byte << in_bits);
00170         in_bits += 8;
00171       }
00172       code = in_buffer & ((1 << enc_bits) - 1);
00173       in_buffer >>= enc_bits;
00174       in_bits -= enc_bits;
00175       outputChar = (*dec_routine)(code, AUDIO_ENCODING_ULAW, &state);
00176       written++;
00177       *(curOutPos++)=outputChar;
00178     }
00179     
00180 
00181 
00182     total_bytes_written+=written;
00183     total_bytes_read+=bytes_read;
00184 
00185     cout <<bytes_read<< " bytes read. "<< written << " bytes written"<<endl;
00186   }
00187     if (in_bits!=0)
00188       cout <<__FUNCTION__<<" extra bits left over..."<<endl;
00189 
00190     cout <<total_bytes_read<< " total bytes read. "<< total_bytes_written << " total bytes written"<<endl;
00191 
00192     int diff=total_bytes_written-total_bytes_read;
00193     difference+=diff;
00194     cout <<"difference for this cycle "<<diff<<endl;
00195 
00196     cout <<"work FINISHED.  module "<<name()<<endl;
00197     return output.size;
00198 }
00199 
00200 
00201 template<class iType> 
00202 void VrAudioDecoder<iType>::initialize()
00203 {
00204   setOutputSize(4800);
00205 }
00206 
00207 #endif

Generated on Tue Mar 15 23:47:08 2005 for GNU Radio by  doxygen 1.4.0