Changeset 4508
- Timestamp:
- 07/25/07 15:36:33 (6 years ago)
- Location:
- components/CVSD/trunk/CVSD/src
- Files:
-
- 5 modified
-
CVSD.cpp (modified) (2 diffs)
-
CVSD.h (modified) (1 diff)
-
CVSDDecoder.cpp (modified) (5 diffs)
-
CVSDEncoder.cpp (modified) (7 diffs)
-
CVSDEncoder.h (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
components/CVSD/trunk/CVSD/src/CVSD.cpp
r4506 r4508 25 25 #include "CVSD.h" 26 26 27 //----------------------------------------------------------------------------- 28 // 29 // CVSD base class 30 // 31 //----------------------------------------------------------------------------- 32 27 33 // Constructor 28 34 CVSD::CVSD() 29 35 { 36 // algorithm variables 37 num_adjacent_bits = 3; 38 bits = 0; 39 ref = 0; 40 delta = 4096; 41 delta_min = 64; 42 delta_max = 16384; 43 output_limit = 16000; 44 45 // initialize bit mask 46 bitmask = 0; 47 for (unsigned int i=0; i<num_adjacent_bits; i++) 48 bitmask = (bitmask << 1) | 1; 30 49 } 31 50 … … 35 54 } 36 55 56 //----------------------------------------------------------------------------- 57 // 58 // CVSD Encoder (DSP) 59 // 60 //----------------------------------------------------------------------------- 61 62 char CVSDEncoderDSP::Encode(short v) { 63 64 char b; 65 66 if ( ref > v ) { 67 b = BIT0; 68 } else { 69 b = BIT1; 70 } 71 72 // shift last bit into variable 73 bits = (bits << 1) | (b >= BIT1); 74 bits = bits & bitmask; 75 76 // update delta 77 if ( (bits==0) || (bits==bitmask) ) { 78 delta <<= 1; // double delta 79 } else { 80 delta >>= 1; // halve delta 81 } 82 83 if (delta > delta_max) { 84 delta = delta_max; 85 //DEBUG(5, CVSDEncoder, "limiting delta to " << delta_max); 86 } else if (delta < delta_min) { 87 delta = delta_min; 88 //DEBUG(7, CVSDEncoder, "limiting delta to " << delta_min); 89 } else { 90 // do nothing 91 } 92 93 // update reference value 94 ref += (b<=BIT0) ? -delta : delta; 95 ref = (ref > output_limit) ? output_limit : ref; 96 ref = (ref < -output_limit) ? -output_limit : ref; 97 98 return b; 99 } 100 101 102 //----------------------------------------------------------------------------- 103 // 104 // CVSD Decoder (DSP) 105 // 106 //----------------------------------------------------------------------------- 107 108 109 short CVSDDecoderDSP::Decode(char b) { 110 /// shift newest bit into variable 111 bits = (bits << 1) | b; 112 bits = bits & bitmask; 113 114 /// Update delta value: 115 /// - double delta if last N bits are all 1's or 0's 116 /// - halve delta otherwise 117 if ( (bits==0) || (bits==bitmask) ) { 118 delta >>= 1; // delta *= 2 119 } else { 120 delta <<= 1; // delta /= 2 121 } 122 123 /// Limit delta value. This is a necessary step, particularly 124 /// limiting to delta_min. 125 if (delta > delta_max) { 126 delta = delta_max; 127 //DEBUG(5, CVSDDecoder, "delta limited to " << delta_max) 128 } else if ( delta < delta_min ) { 129 delta = delta_min; 130 //DEBUG(7, CVSDDecoder, "delta limited to " << delta_min) 131 } else; 132 133 /// update reference value 134 ref += ( b==0 ) ? -delta : delta; 135 ref = (ref > output_limit) ? output_limit : ref; 136 ref = (ref < -output_limit) ? -output_limit : ref; 137 138 return ref; 139 } -
components/CVSD/trunk/CVSD/src/CVSD.h
r4506 r4508 42 42 43 43 protected: 44 unsigned short num_adjacent_bits; ///< read in from properties 44 /// Number of sequential identical bits observed before delta value 45 /// is increased 46 unsigned short num_adjacent_bits; 47 45 48 unsigned short bits; ///< historical bit sequence 49 unsigned short bitmask; ///< bit mask 46 50 signed short ref; ///< current referenced CVSD audio value 47 51 signed short delta; ///< current step size 48 52 signed short delta_min; ///< minimum step size 49 53 signed short delta_max; ///< maximum step size 50 signed short output_limit; ///< maximum output value 54 signed short output_limit; ///< maximum output value (hard clipping) 51 55 52 56 }; -
components/CVSD/trunk/CVSD/src/CVSDDecoder.cpp
r4506 r4508 37 37 dataIn = new standardInterfaces_i::realChar_p("dataIn"); 38 38 39 // algorithm variables40 num_adjacent_bits = 3; // to be read in from properties (default is 3)41 bits = 0; // register to store N sequential input bits42 ref = 0; // decoded reference value43 delta = 4096; // initial delta value44 delta_min = 64; // minimum delta value45 delta_max = 16384; // maximum delta value46 output_limit = 16000; // hard output limit (clip)47 48 39 // Design low-pass audio filter 49 40 float * h(NULL); 50 41 unsigned int h_len; 51 42 SigProc::DesignRRCFilter(2, 2, 0.5f, h, h_len); 52 if ( h != NULL ) 53 { 43 if ( h != NULL ) { 54 44 audio_filter = new SigProc::fir_filter(h, h_len); 55 45 delete [] h; … … 128 118 DEBUG(3, CVSDDecoder, "props length : " << props.length()) 129 119 130 for (unsigned int i = 0; i <props.length(); i++) 131 { 120 for (unsigned int i = 0; i <props.length(); i++) { 132 121 DEBUG(3, CVSDDecoder, "Property id : " << props[i].id) 133 122 134 if (strcmp(props[i].id, "DCE:eddb21b7-1d3a-45da-8831-5a3ca8ec63b5") == 0) 135 { 123 if (strcmp(props[i].id, "DCE:eddb21b7-1d3a-45da-8831-5a3ca8ec63b5") == 0) { 136 124 CORBA::Short n; 137 125 props[i].value >>= n; … … 141 129 << num_adjacent_bits) 142 130 } 143 144 131 } 145 132 } 146 133 147 void CVSDDecoder_i::run_loop() 148 { 134 void CVSDDecoder_i::run_loop() { 149 135 DEBUG(3, CVSDDecoder, "process_data thread started") 150 136 … … 156 142 short bitmask(0); // mask for N sequential bits 157 143 short ref_flt; // filtered output reference 144 short v; // reference value (decoded output) 158 145 159 146 for (i=0; i<num_adjacent_bits; i++) 160 147 bitmask = (bitmask << 1) | 1; // shift a bit into the variable 161 148 162 while(1) 163 { 149 while(true) { 164 150 dataIn->getData(bitsIn); 165 151 N = bitsIn->length(); … … 169 155 for (i=0; i<N; i++) { 170 156 171 // /make hard bit decision here if not done already157 // make hard bit decision here if not done already 172 158 (*bitsIn)[i] = ( (*bitsIn)[i]>0 ) ? 1 : 0; 173 159 174 /// shift newest bit into variable 175 bits = (bits << 1) | (*bitsIn)[i]; 176 bits = bits & bitmask; 160 // Decode audio signal from bit sequence 161 v = Decode( (*bitsIn)[i] ); 177 162 178 /// Update delta value: 179 /// - double delta if last N bits are all 1's or 0's 180 /// - halve delta otherwise 181 if ( (bits==0) || (bits==bitmask) ) { 182 delta *= 2; 183 } else { 184 delta /= 2; 185 } 186 187 /// Limit delta value. This is a necessary step, particularly 188 /// limiting to delta_min. 189 if (delta > delta_max) { 190 delta = delta_max; 191 DEBUG(5, CVSDDecoder, "delta limited to " << delta_max) 192 } else if ( delta < delta_min ) { 193 delta = delta_min; 194 DEBUG(7, CVSDDecoder, "delta limited to " << delta_min) 195 } else; 196 197 /// update reference value 198 ref += ((*bitsIn)[i]==0) ? -delta : delta; 199 ref = (ref > output_limit) ? output_limit : ref; 200 ref = (ref < -output_limit) ? -output_limit : ref; 201 202 /// Apply low-pass filter 203 /// If the reference was hard-limited to at least 16,000, the output 204 /// value can be doubled without clipping 205 audio_filter->do_work( true, 2*ref, ref_flt ); 163 // Apply low-pass filter 164 // If the reference was hard-limited to at least 16,000, the output 165 // value can be doubled without clipping 166 audio_filter->do_work( true, 2*v, ref_flt ); 206 167 L_out[i] = ref_flt; // left audio 207 168 R_out[i] = ref_flt; // right audio -
components/CVSD/trunk/CVSD/src/CVSDEncoder.cpp
r4506 r4508 43 43 dataIn = new standardInterfaces_i::complexShort_p("audioIn"); 44 44 45 // algorithm variables 46 num_adjacent_bits = 3; // eventually read in from properties 47 bits = 0; 48 ref = 0; 49 delta = 4096; 50 delta_min = 64; 51 delta_max = 16384; 52 output_limit = 16000; 45 // Initialize CORBA input pointers 46 L_in = NULL; 47 R_in = NULL; 53 48 54 49 // -- AGC -- … … 149 144 DEBUG(3, CVSDEncoder, "CVSDEncoder: number of adjacent bits: " << num_adjacent_bits) 150 145 } else { 151 std::cerr << "CVSDEncoder: Unknown Property." << std::endl; 152 throw 0; 153 /// \todo throw CF::PropertySet::InvalidConfiguration 146 std::cerr << "CVSDEncoder: Unknown Property." << std::endl; 147 throw CF::PropertySet::InvalidConfiguration(); 154 148 } 155 149 … … 157 151 } 158 152 159 void CVSDEncoder_i::run_loop() 160 { 153 void CVSDEncoder_i::run_loop() { 161 154 DEBUG(3, CVSDEncoder, "run_loop thread started") 162 PortTypes::ShortSequence * I_in(NULL), *Q_in(NULL);155 PortTypes::ShortSequence *L_in(NULL), *R_in(NULL); 163 156 164 157 PortTypes::CharSequence bitsOut; … … 174 167 while( true ) 175 168 { 176 dataIn->getData( I_in, Q_in);177 N = I_in->length();169 dataIn->getData(L_in, R_in); 170 N = L_in->length(); 178 171 bitsOut.length(N); 179 172 180 173 maxval = 0; 181 174 for (i=0; i<N; i++) { 182 if ( abs((* I_in)[i])>maxval )183 maxval = abs((* I_in)[i]);175 if ( abs((*L_in)[i])>maxval ) 176 maxval = abs((*L_in)[i]); 184 177 } 185 178 … … 189 182 /// \todo Compress audio such that clipping does not occur 190 183 184 /// Precondition the input audio signal: 185 /// - automatic gain control, ref prop_agc_strength 186 /// - prefilter (not net implemented) 187 /// - compress transient spikes (currently clips) 188 /// - vox, \ref prop_vox 191 189 maxval = 0; 192 190 for (i=0; i<N; i++) { 193 191 194 192 // -- AGC -- 195 audio_agc->ApplyGain((* I_in)[i], (*Q_in)[i]);193 audio_agc->ApplyGain((*L_in)[i], (*R_in)[i]); 196 194 197 195 float g, e; … … 201 199 float g_th(0.8f*max_gain); 202 200 float hga(1.0f); // high gain attenuator 203 if ( g > g_th ) 204 { 201 if ( g > g_th ) { 205 202 hga = (max_gain-g)/max_gain; 206 (* I_in)[i] = short((*I_in)[i]*hga);203 (*L_in)[i] = short((*L_in)[i]*hga); 207 204 } 208 205 209 206 // calculate maximum 210 if (abs((* I_in)[i])>maxval)211 maxval = abs((* I_in)[i]);207 if (abs((*L_in)[i])>maxval) 208 maxval = abs((*L_in)[i]); 212 209 213 210 // limit input (clip) 214 if ((* I_in)[i]>output_limit) {215 (* I_in)[i] = output_limit;211 if ((*L_in)[i]>output_limit) { 212 (*L_in)[i] = output_limit; 216 213 DEBUG(4, CVSDEncoder, " clipping audio! (+)") 217 } else if ((* I_in)[i] < -output_limit) {218 (* I_in)[i] = -output_limit;214 } else if ((*L_in)[i] < -output_limit) { 215 (*L_in)[i] = -output_limit; 219 216 DEBUG(4, CVSDEncoder, " clipping audio! (-)") 220 217 } else { … … 222 219 } 223 220 224 if (ref > (*I_in)[i]) { 225 bitsOut[i] = BIT0; 226 } else { 227 bitsOut[i] = BIT1; 228 } 229 230 // shift last bit into variable 231 bits = (bits << 1) | (bitsOut[i] >= BIT1); 232 bits = bits & bitmask; 233 234 // update delta 235 if ( (bits==0) || (bits==bitmask) ) { 236 delta <<= 1; // double delta 237 } else { 238 delta >>= 1; // halve delta 239 } 240 241 if (delta > delta_max) { 242 delta = delta_max; 243 DEBUG(5, CVSDEncoder, "limiting delta to " << delta_max); 244 } else if (delta < delta_min) { 245 delta = delta_min; 246 DEBUG(7, CVSDEncoder, "limiting delta to " << delta_min); 247 } else { 248 // do nothing 249 } 250 251 // update reference value 252 ref += (bitsOut[i]<=BIT0) ? -delta : delta; 253 ref = (ref > output_limit) ? output_limit : ref; 254 ref = (ref < -output_limit) ? -output_limit : ref; 255 221 } 222 223 // Encode signal 224 for (i=0; i<N; i++) { 225 bitsOut[i] = Encode( (*L_in)[i] ); 256 226 } 257 227 -
components/CVSD/trunk/CVSD/src/CVSDEncoder.h
r4506 r4508 46 46 { 47 47 public: 48 /// Initializing constructor 48 49 CVSDEncoder_i(const char *uuid, omni_condition *sem); 50 51 /// Destructor 49 52 ~CVSDEncoder_i(); 50 53 … … 58 61 static void run( void * data ); 59 62 60 CORBA::Object_ptr getPort( const char* portName ) throw (CF::PortSupplier::UnknownPort, CORBA::SystemException); 63 CORBA::Object_ptr getPort( const char* portName ) 64 throw (CF::PortSupplier::UnknownPort, CORBA::SystemException); 61 65 62 66 void releaseObject() throw (CF::LifeCycle::ReleaseError, CORBA::SystemException); … … 71 75 /// - \ref prop_agc_strength 72 76 /// - \ref prop_vox 73 void configure(const CF::Properties&) throw (CORBA::SystemException, CF::PropertySet::InvalidConfiguration, CF::PropertySet::PartialConfiguration); 77 void configure(const CF::Properties&) 78 throw (CORBA::SystemException, 79 CF::PropertySet::InvalidConfiguration, 80 CF::PropertySet::PartialConfiguration); 74 81 75 82 private: 83 /// Disallow default constructor 76 84 CVSDEncoder_i(); 85 86 /// Disallow copy constructor 77 87 CVSDEncoder_i(CVSDEncoder_i&); 78 88 79 89 /// Main signal processing loop 80 90 void run_loop(); 81 91 82 92 omni_condition *component_running; ///< for component shutdown 83 93 omni_thread *processing_thread; ///< for component writer function … … 88 98 CORBA::ShortSeq *simplesequence_ptr; 89 99 100 /// Input L/R audio signal 101 PortTypes::ShortSequence *L_in, *R_in; 102 90 103 // list components provides and uses ports 91 104 standardInterfaces_i::realChar_u *dataOut; ///< port: audio-encoded bits out 92 105 standardInterfaces_i::complexShort_p *dataIn; ///< port: audio samples in 93 94 // algorithm variables95 /*96 unsigned short num_adjacent_bits; ///< read in from properties97 unsigned short bits; ///< historical bit sequence98 signed short ref; ///< current referenced CVSD audio value99 signed short delta; ///< current step size100 signed short delta_min; ///< minimum step size101 signed short delta_max; ///< maximum step size102 signed short output_limit; ///< maximum output value103 */104 106 105 107 // -- AGC -- … … 114 116 SigProc::AutomaticGainControl * audio_agc; 115 117 116 117 118 118 }; 119 119 #endif