Changeset 4508

Show
Ignore:
Timestamp:
07/25/07 15:36:33 (6 years ago)
Author:
jgaeddert
Message:

moving DSP for CVSD codecs to separate classes

Location:
components/CVSD/trunk/CVSD/src
Files:
5 modified

Legend:

Unmodified
Added
Removed
  • components/CVSD/trunk/CVSD/src/CVSD.cpp

    r4506 r4508  
    2525#include "CVSD.h" 
    2626 
     27//----------------------------------------------------------------------------- 
     28// 
     29// CVSD base class 
     30// 
     31//----------------------------------------------------------------------------- 
     32 
    2733// Constructor 
    2834CVSD::CVSD() 
    2935{ 
     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; 
    3049} 
    3150 
     
    3554} 
    3655 
     56//----------------------------------------------------------------------------- 
     57// 
     58// CVSD Encoder (DSP) 
     59// 
     60//----------------------------------------------------------------------------- 
     61 
     62char 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 
     109short 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  
    4242 
    4343  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 
    4548    unsigned short bits;                ///< historical bit sequence 
     49    unsigned short bitmask;             ///< bit mask 
    4650    signed short ref;                   ///< current referenced CVSD audio value 
    4751    signed short delta;                 ///< current step size 
    4852    signed short delta_min;             ///< minimum step size 
    4953    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) 
    5155 
    5256}; 
  • components/CVSD/trunk/CVSD/src/CVSDDecoder.cpp

    r4506 r4508  
    3737    dataIn = new standardInterfaces_i::realChar_p("dataIn"); 
    3838 
    39     // algorithm variables 
    40     num_adjacent_bits = 3;  // to be read in from properties (default is 3) 
    41     bits = 0;               // register to store N sequential input bits 
    42     ref = 0;                // decoded reference value 
    43     delta = 4096;           // initial delta value 
    44     delta_min = 64;         // minimum delta value 
    45     delta_max = 16384;      // maximum delta value 
    46     output_limit = 16000;   // hard output limit (clip) 
    47  
    4839    // Design low-pass audio filter 
    4940    float * h(NULL); 
    5041    unsigned int h_len; 
    5142    SigProc::DesignRRCFilter(2, 2, 0.5f, h, h_len); 
    52     if ( h != NULL ) 
    53     { 
     43    if ( h != NULL ) { 
    5444        audio_filter = new SigProc::fir_filter(h, h_len); 
    5545        delete [] h; 
     
    128118    DEBUG(3, CVSDDecoder, "props length : " << props.length()) 
    129119 
    130     for (unsigned int i = 0; i <props.length(); i++) 
    131     { 
     120    for (unsigned int i = 0; i <props.length(); i++) { 
    132121        DEBUG(3, CVSDDecoder, "Property id : " << props[i].id) 
    133122 
    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) { 
    136124            CORBA::Short n; 
    137125            props[i].value >>= n; 
     
    141129                      << num_adjacent_bits) 
    142130        } 
    143  
    144131    } 
    145132} 
    146133 
    147 void CVSDDecoder_i::run_loop() 
    148 { 
     134void CVSDDecoder_i::run_loop() { 
    149135    DEBUG(3, CVSDDecoder, "process_data thread started") 
    150136 
     
    156142    short bitmask(0); // mask for N sequential bits 
    157143    short ref_flt;    // filtered output reference 
     144    short v;          // reference value (decoded output) 
    158145 
    159146    for (i=0; i<num_adjacent_bits; i++) 
    160147        bitmask = (bitmask << 1) | 1; // shift a bit into the variable 
    161148 
    162     while(1) 
    163     { 
     149    while(true) { 
    164150        dataIn->getData(bitsIn); 
    165151        N = bitsIn->length(); 
     
    169155        for (i=0; i<N; i++) { 
    170156 
    171             /// make hard bit decision here if not done already 
     157            // make hard bit decision here if not done already 
    172158            (*bitsIn)[i] = ( (*bitsIn)[i]>0 ) ? 1 : 0; 
    173159 
    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] ); 
    177162 
    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 ); 
    206167            L_out[i] = ref_flt;  // left audio 
    207168            R_out[i] = ref_flt;  // right audio 
  • components/CVSD/trunk/CVSD/src/CVSDEncoder.cpp

    r4506 r4508  
    4343    dataIn = new standardInterfaces_i::complexShort_p("audioIn"); 
    4444 
    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; 
    5348 
    5449    // -- AGC -- 
     
    149144            DEBUG(3, CVSDEncoder, "CVSDEncoder: number of adjacent bits: " << num_adjacent_bits) 
    150145        } 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(); 
    154148        } 
    155149 
     
    157151} 
    158152 
    159 void CVSDEncoder_i::run_loop() 
    160 { 
     153void CVSDEncoder_i::run_loop() { 
    161154    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); 
    163156 
    164157    PortTypes::CharSequence bitsOut; 
     
    174167    while( true ) 
    175168    { 
    176         dataIn->getData(I_in, Q_in); 
    177         N = I_in->length(); 
     169        dataIn->getData(L_in, R_in); 
     170        N = L_in->length(); 
    178171        bitsOut.length(N); 
    179172 
    180173        maxval = 0; 
    181174        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]); 
    184177        } 
    185178 
     
    189182        /// \todo Compress audio such that clipping does not occur 
    190183 
     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 
    191189        maxval = 0; 
    192190        for (i=0; i<N; i++) { 
    193191 
    194192            // -- AGC -- 
    195             audio_agc->ApplyGain((*I_in)[i], (*Q_in)[i]); 
     193            audio_agc->ApplyGain((*L_in)[i], (*R_in)[i]); 
    196194 
    197195            float g, e; 
     
    201199            float g_th(0.8f*max_gain); 
    202200            float hga(1.0f); // high gain attenuator 
    203             if ( g > g_th ) 
    204             { 
     201            if ( g > g_th ) { 
    205202                hga = (max_gain-g)/max_gain; 
    206                 (*I_in)[i] = short((*I_in)[i]*hga); 
     203                (*L_in)[i] = short((*L_in)[i]*hga); 
    207204            } 
    208205 
    209206            // 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]); 
    212209 
    213210            // 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; 
    216213                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; 
    219216                DEBUG(4, CVSDEncoder, "  clipping audio! (-)") 
    220217            } else { 
     
    222219            } 
    223220 
    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] ); 
    256226        } 
    257227 
  • components/CVSD/trunk/CVSD/src/CVSDEncoder.h

    r4506 r4508  
    4646{ 
    4747  public: 
     48    /// Initializing constructor 
    4849    CVSDEncoder_i(const char *uuid, omni_condition *sem); 
     50 
     51    /// Destructor 
    4952    ~CVSDEncoder_i(); 
    5053 
     
    5861    static void run( void * data ); 
    5962 
    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); 
    6165 
    6266    void releaseObject() throw (CF::LifeCycle::ReleaseError, CORBA::SystemException); 
     
    7175    ///   - \ref prop_agc_strength 
    7276    ///   - \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); 
    7481 
    7582  private: 
     83    /// Disallow default constructor 
    7684    CVSDEncoder_i(); 
     85 
     86    /// Disallow copy constructor 
    7787    CVSDEncoder_i(CVSDEncoder_i&); 
    7888 
    7989    /// Main signal processing loop 
    8090    void run_loop(); 
    81     
     91 
    8292    omni_condition *component_running;  ///< for component shutdown 
    8393    omni_thread *processing_thread;     ///< for component writer function 
     
    8898    CORBA::ShortSeq *simplesequence_ptr;  
    8999     
     100    /// Input L/R audio signal 
     101    PortTypes::ShortSequence *L_in, *R_in; 
     102 
    90103    // list components provides and uses ports 
    91104    standardInterfaces_i::realChar_u *dataOut;     ///< port: audio-encoded bits out 
    92105    standardInterfaces_i::complexShort_p *dataIn;  ///< port: audio samples in 
    93  
    94     // algorithm variables 
    95     /* 
    96     unsigned short num_adjacent_bits; ///< read in from properties 
    97     unsigned short bits;              ///< historical bit sequence 
    98     signed short ref;                 ///< current referenced CVSD audio value 
    99     signed short delta;               ///< current step size 
    100     signed short delta_min;           ///< minimum step size 
    101     signed short delta_max;           ///< maximum step size 
    102     signed short output_limit;        ///< maximum output value 
    103     */ 
    104106 
    105107    // -- AGC -- 
     
    114116    SigProc::AutomaticGainControl * audio_agc;  
    115117     
    116      
    117      
    118118}; 
    119119#endif