Ignore:
Timestamp:
Sep 5, 2006 10:52:26 PM (18 years ago)
Author:
bennylp
Message:

Added volume control to indivual tone enqueued to the tone generator.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjmedia/src/pjmedia/tonegen.c

    r693 r694  
    4343     * This produces good quality tone in relatively faster time than 
    4444     * the normal sin() generator. 
    45      * Speed = 32,500 cycles (to generate 100 msec single-tone). 
     45     * Speed = 40.6 cycles per sample. 
    4646     */ 
    4747#   include <math.h> 
     
    5454                                 var.s0 = A; \ 
    5555                                 var.s1 = 0 
    56 #   define GEN_SAMP(val,var,A)   var.s0 = var.s0 - var.a * var.s1; \ 
     56#   define GEN_SAMP(val,var)     var.s0 = var.s0 - var.a * var.s1; \ 
    5757                                 var.s1 = var.s1 + var.a * var.s0; \ 
    5858                                 val = (short) var.s0 
    5959 
    6060 
    61 #elif defined(PJ_HAS_FLOATING_POINT) && PJ_HAS_FLOATING_POINT!=0 
     61#elif !defined(PJ_HAS_FLOATING_POINT) || PJ_HAS_FLOATING_POINT==0 
    6262    /*  
    6363     * Fallback algorithm when floating point is disabled. 
     
    6666     *    http://www.audiomulch.com/~rossb/code/sinusoids/  
    6767     * Quality wise not so good, but it's blazing fast! 
    68      * Speed = 9,776 cycles (to generate 100 msec single-tone). 
     68     * Speed:  
     69     *  - with volume adjustment: 14 cycles per sample  
     70     *  - without volume adjustment: 12.22 cycles per sample 
    6971     */ 
    7072    PJ_INLINE(int) approximate_sin3(unsigned x) 
     
    8183        unsigned add; 
    8284        unsigned c; 
     85        unsigned vol; 
    8386    }; 
    8487 
    8588#   define MAXI                 ((unsigned)0xFFFFFFFF) 
    8689#   define SIN                  approximate_sin3 
    87 #   define GEN_INIT(var,R,F,A)  var.add = MAXI/R * F, var.c=0 
    88 #   define GEN_SAMP(val,var,A)  val = (short) (SIN(var.c) >> 16); \ 
     90#   if 1    /* set this to 0 to disable volume adjustment */ 
     91#       define VOL(var,v)       (((v) * var.vol) >> 16) 
     92#   else 
     93#       define VOL(var,v)       (v) 
     94#   endif 
     95#   define GEN_INIT(var,R,F,A)  var.add = MAXI/R * F, var.c=0, var.vol=A 
     96#   define GEN_SAMP(val,var)    val = (short) VOL(SIN(var.c)>>16));\ 
    8997                                var.c += var.add 
    9098 
     
    96104     * Should never really reach here, but anyway it's provided for reference. 
    97105     * This is the good old tone generator using sin(). 
    98      * Speed = 178,000 cycles (to generate 100 msec single-tone). 
     106     * Speed = 222.5 cycles per sample. 
    99107     */ 
    100108    struct gen 
     
    102110        DATA add; 
    103111        DATA c; 
     112        DATA vol; 
    104113    }; 
    105114 
    106 #   define GEN_INIT(var,R,F,A) var.add = ((DATA)F)/R, var.c=0 
    107 #   define GEN_SAMP(val,var,A) val = (short) (sin(var.c * 2 * M_PI) * A); \ 
     115#   define GEN_INIT(var,R,F,A) var.add = ((DATA)F)/R, var.c=0, var.vol=A 
     116#   define GEN_SAMP(val,var)   val = (short)(sin(var.c * 2 * M_PI) * var.vol);\ 
    108117                               var.c += var.add 
    109118 
     
    120129static void init_generate_single_tone(struct gen_state *state, 
    121130                                      unsigned clock_rate,  
    122                                       unsigned freq) 
    123 { 
    124     GEN_INIT(state->tone1,clock_rate,freq,AMP); 
     131                                      unsigned freq, 
     132                                      unsigned vol) 
     133{ 
     134    GEN_INIT(state->tone1,clock_rate,freq,vol); 
    125135    state->has_tone2 = PJ_FALSE; 
    126136} 
     
    136146 
    137147        while (buf < end) { 
    138             GEN_SAMP(*buf++, state->tone1, AMP); 
     148            GEN_SAMP(*buf++, state->tone1); 
    139149        } 
    140150 
     
    142152 
    143153        while (buf < end) { 
    144             GEN_SAMP(*buf, state->tone1, AMP); 
     154            GEN_SAMP(*buf, state->tone1); 
    145155            *(buf+1) = *buf; 
    146156            buf += 2; 
     
    153163                                    unsigned clock_rate,  
    154164                                    unsigned freq1, 
    155                                     unsigned freq2) 
    156 { 
    157     GEN_INIT(state->tone1,clock_rate,freq1,AMP); 
    158     GEN_INIT(state->tone2,clock_rate,freq2,AMP); 
     165                                    unsigned freq2, 
     166                                    unsigned vol) 
     167{ 
     168    GEN_INIT(state->tone1,clock_rate,freq1,vol); 
     169    GEN_INIT(state->tone2,clock_rate,freq2,vol); 
    159170    state->has_tone2 = PJ_TRUE; 
    160171} 
     
    171182        int val, val2; 
    172183        while (buf < end) { 
    173             GEN_SAMP(val, state->tone1, AMP); 
    174             GEN_SAMP(val2, state->tone2, AMP); 
     184            GEN_SAMP(val, state->tone1); 
     185            GEN_SAMP(val2, state->tone2); 
    175186            *buf++ = (short)((val+val2) >> 1); 
    176187        } 
     
    179190        while (buf < end) { 
    180191 
    181             GEN_SAMP(val, state->tone1, AMP); 
    182             GEN_SAMP(val2, state->tone2, AMP); 
     192            GEN_SAMP(val, state->tone1); 
     193            GEN_SAMP(val2, state->tone2); 
    183194            val = (val + val2) >> 1; 
    184195 
     
    193204                               unsigned clock_rate,  
    194205                               unsigned freq1, 
    195                                unsigned freq2) 
     206                               unsigned freq2, 
     207                               unsigned vol) 
    196208{ 
    197209    if (freq2) 
    198         init_generate_dual_tone(state, clock_rate, freq1, freq2); 
     210        init_generate_dual_tone(state, clock_rate, freq1, freq2 ,vol); 
    199211    else 
    200         init_generate_single_tone(state, clock_rate, freq1); 
     212        init_generate_single_tone(state, clock_rate, freq1,vol); 
    201213} 
    202214 
     
    384396        if (tonegen->dig_samples == 0) { 
    385397            init_generate_tone(&tonegen->state, port->info.clock_rate, 
    386                                dig->freq1, dig->freq2); 
     398                               dig->freq1, dig->freq2, dig->volume); 
    387399        } 
    388400 
     
    439451{ 
    440452    struct tonegen *tonegen = (struct tonegen*) port; 
     453    unsigned i; 
    441454 
    442455    PJ_ASSERT_RETURN(port && port->info.signature == SIGNATURE && 
     
    447460                     PJ_ETOOMANY); 
    448461 
     462    /* Copy digits */ 
    449463    pj_memcpy(tonegen->digits + tonegen->count, 
    450464              tones, count * sizeof(pjmedia_tone_desc)); 
     465     
     466    /* Normalize volume */ 
     467    for (i=0; i<count; ++i) { 
     468        pjmedia_tone_desc *t = &tonegen->digits[i+tonegen->count]; 
     469        if (t->volume == 0) 
     470            t->volume = AMP; 
     471        else if (t->volume < 0) 
     472            t->volume = (short) -t->volume; 
     473    } 
     474 
    451475    tonegen->count += count; 
    452476 
     
    488512        tones[i].on_msec = digits[i].on_msec; 
    489513        tones[i].off_msec = digits[i].off_msec; 
     514        tones[i].volume = digits[i].volume; 
    490515    } 
    491516 
Note: See TracChangeset for help on using the changeset viewer.