- Timestamp:
- Sep 5, 2006 10:52:26 PM (18 years ago)
- Location:
- pjproject/trunk/pjmedia
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjmedia/include/pjmedia/tonegen.h
r693 r694 63 63 short on_msec; /**< Playback ON duration, in miliseconds. */ 64 64 short off_msec; /**< Playback OFF duration, ini miliseconds. */ 65 short volume; /**< Volume (1-16383), or 0 for default. */ 65 66 } pjmedia_tone_desc; 66 67 … … 76 77 short on_msec; /**< Playback ON duration, in miliseconds. */ 77 78 short off_msec; /**< Playback OFF duration, ini miliseconds. */ 79 short volume; /**< Volume (1-16383), or 0 for default. */ 78 80 } pjmedia_tone_digit; 79 81 -
pjproject/trunk/pjmedia/src/pjmedia/tonegen.c
r693 r694 43 43 * This produces good quality tone in relatively faster time than 44 44 * the normal sin() generator. 45 * Speed = 32,500 cycles (to generate 100 msec single-tone).45 * Speed = 40.6 cycles per sample. 46 46 */ 47 47 # include <math.h> … … 54 54 var.s0 = A; \ 55 55 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; \ 57 57 var.s1 = var.s1 + var.a * var.s0; \ 58 58 val = (short) var.s0 59 59 60 60 61 #elif defined(PJ_HAS_FLOATING_POINT) && PJ_HAS_FLOATING_POINT!=061 #elif !defined(PJ_HAS_FLOATING_POINT) || PJ_HAS_FLOATING_POINT==0 62 62 /* 63 63 * Fallback algorithm when floating point is disabled. … … 66 66 * http://www.audiomulch.com/~rossb/code/sinusoids/ 67 67 * 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 69 71 */ 70 72 PJ_INLINE(int) approximate_sin3(unsigned x) … … 81 83 unsigned add; 82 84 unsigned c; 85 unsigned vol; 83 86 }; 84 87 85 88 # define MAXI ((unsigned)0xFFFFFFFF) 86 89 # 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));\ 89 97 var.c += var.add 90 98 … … 96 104 * Should never really reach here, but anyway it's provided for reference. 97 105 * 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. 99 107 */ 100 108 struct gen … … 102 110 DATA add; 103 111 DATA c; 112 DATA vol; 104 113 }; 105 114 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);\ 108 117 var.c += var.add 109 118 … … 120 129 static void init_generate_single_tone(struct gen_state *state, 121 130 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); 125 135 state->has_tone2 = PJ_FALSE; 126 136 } … … 136 146 137 147 while (buf < end) { 138 GEN_SAMP(*buf++, state->tone1 , AMP);148 GEN_SAMP(*buf++, state->tone1); 139 149 } 140 150 … … 142 152 143 153 while (buf < end) { 144 GEN_SAMP(*buf, state->tone1 , AMP);154 GEN_SAMP(*buf, state->tone1); 145 155 *(buf+1) = *buf; 146 156 buf += 2; … … 153 163 unsigned clock_rate, 154 164 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); 159 170 state->has_tone2 = PJ_TRUE; 160 171 } … … 171 182 int val, val2; 172 183 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); 175 186 *buf++ = (short)((val+val2) >> 1); 176 187 } … … 179 190 while (buf < end) { 180 191 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); 183 194 val = (val + val2) >> 1; 184 195 … … 193 204 unsigned clock_rate, 194 205 unsigned freq1, 195 unsigned freq2) 206 unsigned freq2, 207 unsigned vol) 196 208 { 197 209 if (freq2) 198 init_generate_dual_tone(state, clock_rate, freq1, freq2 );210 init_generate_dual_tone(state, clock_rate, freq1, freq2 ,vol); 199 211 else 200 init_generate_single_tone(state, clock_rate, freq1 );212 init_generate_single_tone(state, clock_rate, freq1,vol); 201 213 } 202 214 … … 384 396 if (tonegen->dig_samples == 0) { 385 397 init_generate_tone(&tonegen->state, port->info.clock_rate, 386 dig->freq1, dig->freq2 );398 dig->freq1, dig->freq2, dig->volume); 387 399 } 388 400 … … 439 451 { 440 452 struct tonegen *tonegen = (struct tonegen*) port; 453 unsigned i; 441 454 442 455 PJ_ASSERT_RETURN(port && port->info.signature == SIGNATURE && … … 447 460 PJ_ETOOMANY); 448 461 462 /* Copy digits */ 449 463 pj_memcpy(tonegen->digits + tonegen->count, 450 464 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 451 475 tonegen->count += count; 452 476 … … 488 512 tones[i].on_msec = digits[i].on_msec; 489 513 tones[i].off_msec = digits[i].off_msec; 514 tones[i].volume = digits[i].volume; 490 515 } 491 516
Note: See TracChangeset
for help on using the changeset viewer.