00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #ifndef _VrAudioEncoder_H_
00039 #define _VrAudioEncoder_H_
00040 #include <math.h>
00041
00042 #include <../G711_G721_G723/g72x.h>
00043
00044
00045 #include <VrDecimatingSigProc.h>
00046
00047 int pack_output(unsigned,int,char *);
00048 const unsigned outputBytes=120;
00049 const int headerSize=3;
00050 const unsigned outputBlockSize=outputBytes+headerSize;
00051
00052 #if defined (ENABLE_MMX)
00053 #include <VrMMX.h>
00054 #endif
00055
00056
00057
00058
00059
00060
00061 template<class iType>
00062 class VrAudioEncoder : public VrDecimatingSigProc<iType,iType> {
00063 short blockNum;
00064 int position;
00065 int enc_bits;
00066 int in_coding;
00067 struct g72x_state state;
00068 int (*enc_routine)(int, int, g72x_state *);
00069 protected:
00070
00071 #if defined (ENABLE_MMX)
00072 mmxTaps** processedTaps;
00073 #endif
00074
00075 public:
00076 VrAudioEncoder(int bits){
00077
00078 enc_bits=bits;
00079 in_coding = AUDIO_ENCODING_ULAW;
00080 g72x_init_state(&state);
00081
00082 switch (bits){
00083 case 3:
00084 enc_routine = g723_24_encoder;
00085 break;
00086 case 4:
00087 enc_routine = g721_encoder;
00088 break;
00089 case 5:
00090 enc_routine = g723_40_encoder;
00091 break;
00092 }
00093 }
00094 virtual const char *name() { return "VrAudioEncoder"; }
00095 virtual int work(VrSampleRange output, iType *o[],
00096 VrSampleRange inputs[], iType *i[]);
00097 virtual int forecast(VrSampleRange output, VrSampleRange inputs[]);
00098 virtual void initialize();
00099 int num;
00100 };
00101
00102 template<class iType> int
00103 VrAudioEncoder<iType>::forecast(VrSampleRange output,
00104 VrSampleRange inputs[]) {
00105
00106 double inbits= sizeof(iType)*8;
00107 double ratio = inbits/double(enc_bits);
00108 int numBlocks=output.size/outputBlockSize;
00109
00110 inputs[0].size=(unsigned long)(numBlocks*outputBytes*ratio);
00111 inputs[0].index=(unsigned)(double(output.index)*ratio);
00112
00113 cout <<"ratio= "<<ratio<<" numblocks= "<< numBlocks<<" to get outputsize of "<<output.size<<" starting at " <<output.index<< " you need "<<inputs[0].size<< " starting at "<<inputs[0].index<<endl;
00114 return 0;
00115 }
00116
00117 template<class iType> int
00118 VrAudioEncoder<iType>::work(VrSampleRange output, iType *o[],
00119 VrSampleRange inputs[], iType *i[]) {
00120
00121 int numBlocks=output.size/outputBlockSize;
00122 cout <<__FUNCTION__<<" starting output.size ="<<output.size<<" numblocks= "<<numBlocks<<endl;
00123
00124 iType *curOutPos=o[0];
00125 iType *curInPos=i[0];
00126 char code;
00127 unsigned int out_buffer = 0;
00128 int out_bits = 0;
00129 char out_byte;
00130
00131 unsigned bytes_written=0,total_bytes_written=0;;
00132
00133 for (int count=0;count<numBlocks;count++){
00134 *curOutPos=(char)(enc_bits);
00135 curOutPos++;
00136 *curOutPos=(char)(blockNum>>8);
00137 curOutPos++;
00138 *curOutPos=(char)(blockNum);
00139 curOutPos++;
00140 blockNum++;
00141 bytes_written=headerSize;
00142
00143 while (bytes_written<outputBlockSize){
00144 code = (*enc_routine)(*curInPos,
00145 in_coding, &state);
00146
00147 curInPos++;
00148
00149 out_buffer |= (code << out_bits);
00150 out_bits += enc_bits;
00151 if (out_bits >= 8) {
00152 out_byte = out_buffer & 0xff;
00153 out_bits -= 8;
00154 out_buffer >>= 8;
00155
00156 *(curOutPos++)=out_byte;
00157 bytes_written++;
00158 }
00159
00160 }
00161 total_bytes_written+=bytes_written;
00162 }
00163
00164 if (total_bytes_written !=output.size)
00165 cout <<__FUNCTION__<<" not outputting correct amount of data "<<bytes_written <<" instead of "<<output.size<<endl;
00166
00167 cout <<__FUNCTION__<<" ending"<<endl;
00168
00169 return output.size;
00170
00171 }
00172
00173
00174
00175
00176 template<class iType>
00177 void VrAudioEncoder<iType>::initialize()
00178 {
00179 setOutputSize(outputBlockSize);
00180 blockNum=0;
00181 }
00182
00183 #endif