1 // Copyright (C) 2008-2011 David Sugar, Tycho Softworks.
2 //
3 // This file is part of GNU Bayonne.
4 //
5 // GNU Bayonne is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 3 of the License, or
8 // (at your option) any later version.
9 //
10 // GNU Bayonne is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with GNU Bayonne. If not, see <http://www.gnu.org/licenses/>.
17
18 #include <config.h>
19 #include <ucommon/ucommon.h>
20 #include <ucommon/export.h>
22
23 #ifdef HAVE_ENDIAN_H
24 #include <endian.h>
25 #endif
26
27 #ifdef HAVE_MATH_H
28 #include <math.h>
29 #endif
30
31 #include <ctype.h>
32
34 using namespace UCOMMON_NAMESPACE;
35
36 #ifndef M_PI
37 #define M_PI 3.14159265358979323846
38 #endif
39
40 #if !defined(__BIG_ENDIAN)
41 #define __LITTLE_ENDIAN 1234
42 #define __BIG_ENDIAN 4321
43 #define __PDP_ENDIAN 3412
44 #define __BYTE_ORDER __LITTLE_ENDIAN
45 #endif
46
47 #if _MSC_VER > 1400 // windows broken dll linkage issue...
48 #else
49 const unsigned Audio::ndata = (unsigned)(-1);
50 #endif
51
52 Audio::level_t Audio::tolevel(float dbm)
53 {
54 double l = pow(10.0, (dbm -
M_PI)/20.0)*(32768.0*0.70711);
55 return (level_t)(l*l);
56 }
57
58 float Audio::todbm(level_t l)
59 {
60 return (
float)(log10(sqrt((
float)l)/(32768.0*0.70711))*20.0 +
M_PI);
61 }
62
63 const char *Audio::getExtension(encoding_t encoding)
64 {
65 switch(encoding) {
66 case cdaStereo:
67 case pcm16Stereo:
68 case pcm32Stereo:
69 case cdaMono:
70 case pcm16Mono:
71 case pcm32Mono:
72 return ".wav";
73 case alawAudio:
74 return ".al";
75 case gsmVoice:
76 return ".gsm";
77 case msgsmVoice:
78 return ".wav";
79 case mp1Audio:
80 return ".mp1";
81 case mp2Audio:
82 return ".mp2";
83 case mp3Audio:
84 return ".mp3";
85 case voxADPCM:
86 return ".vox";
87 case speexVoice:
88 case speexAudio:
89 return ".spx";
90 case sx73Voice:
91 case sx96Voice:
92 return ".sx";
93 case g721ADPCM:
94 return ".adpcm";
95 case g723_2bit:
96 return ".a16";
97 case g723_3bit:
98 return ".a24";
99 case g723_5bit:
100 return ".a40";
101 case g729Audio:
102 return ".g729";
103 case ilbcAudio:
104 return ".ilbc";
105 default:
106 return ".au";
107 }
108 }
109
110 Audio::encoding_t Audio::getMono(encoding_t encoding)
111 {
112 switch(encoding) {
113 case cdaStereo:
114 return cdaMono;
115 case pcm8Stereo:
116 return pcm8Mono;
117 case pcm16Stereo:
118 return pcm16Mono;
119 case pcm32Stereo:
120 return pcm32Mono;
121 default:
122 return encoding;
123 }
124 }
125
126 Audio::encoding_t Audio::getStereo(encoding_t encoding)
127 {
128 switch(encoding) {
129 case cdaStereo:
130 case pcm8Stereo:
131 case pcm16Stereo:
132 case pcm32Stereo:
133 return encoding;
134 case cdaMono:
135 return cdaStereo;
136 case pcm8Mono:
137 return pcm8Stereo;
138 case pcm16Mono:
139 return pcm16Stereo;
140 case pcm32Mono:
141 return pcm32Stereo;
142 default:
143 return unknownEncoding;
144 }
145 }
146
147 Audio::encoding_t Audio::getEncoding(const char *name)
148 {
149 if(!stricmp(name, "ulaw") || !stricmp(name, "mulaw") || !stricmp(name, "pcmu"))
150 return mulawAudio;
151 else if(!stricmp(name, "alaw") || !stricmp(name, "pcma"))
152 return alawAudio;
153 else if(!stricmp(name, "linear") || !stricmp(name, "pcm16") || !stricmp(name, "pcm") || !stricmp(name, "l16"))
154 return pcm16Mono;
155 else if(!stricmp(name, "stereo"))
156 return pcm16Stereo;
157 else if(!stricmp(name, "cda"))
158 return cdaStereo;
159 else if(!stricmp(name, "gsm"))
160 return gsmVoice;
161 else if(!stricmp(name, "msgsm"))
162 return msgsmVoice;
163 else if(!stricmp(name, "pcm8") || !stricmp(name, "l8"))
164 return pcm8Mono;
165 else if(!stricmp(name, "pcm32"))
166 return pcm32Mono;
167 else if(!stricmp(name, "adpcm"))
168 return g721ADPCM;
169 else if(!stricmp(name, "g721") || !stricmp(name, "g.721"))
170 return g721ADPCM;
171 else if(!stricmp(name, "g726-32"))
172 return g721ADPCM;
173 else if(!stricmp(name, "g729") || !stricmp(name, "g.729"))
174 return g729Audio;
175 else if(!stricmp(name, "ilbc"))
176 return ilbcAudio;
177 else if(!stricmp(name, "mp1"))
178 return mp1Audio;
179 else if(!stricmp(name, "mp2"))
180 return mp2Audio;
181 else if(!stricmp(name, "mp3"))
182 return mp3Audio;
183 else if(!stricmp(name, "oki"))
184 return okiADPCM;
185 else if(!stricmp(name, "vox"))
186 return voxADPCM;
187 else if(!stricmp(name, "sx73"))
188 return sx73Voice;
189 else if(!stricmp(name, "sx96"))
190 return sx96Voice;
191 else if(!stricmp(name, "spx") || !stricmp(name, "speex"))
192 return speexVoice;
193 else if(!stricmp(name, "g723-16") || !stricmp(name, "g.723-16"))
194 return g723_2bit;
195 else if(!stricmp(name, "g723-24") || !stricmp(name, "g.723-24"))
196 return g723_3bit;
197 else if(!stricmp(name, "g723-40") || !stricmp(name, "g.723-40"))
198 return g723_5bit;
199 else if(!stricmp(name, ".al") || !stricmp(name, ".alaw"))
200 return alawAudio;
201 else if(!stricmp(name, ".ul") || !stricmp(name, ".ulaw") || !stricmp(name, ".mulaw"))
202 return mulawAudio;
203 else if(!stricmp(name, ".sw") || !stricmp(name, ".raw") || !stricmp(name, ".pcm"))
204 return pcm16Mono;
205 else if(!stricmp(name, ".vox") || !stricmp(name, "vox"))
206 return voxADPCM;
207 else if(!stricmp(name, ".adpcm"))
208 return g721ADPCM;
209 else if(!stricmp(name, ".g721"))
210 return g721ADPCM;
211 else if(!stricmp(name, ".a32") || !stricmp(name, "a32"))
212 return g721ADPCM;
213 else if(!stricmp(name, ".a24") || !stricmp(name, "a24"))
214 return g723_3bit;
215 else if(!stricmp(name, ".a16") || !stricmp(name, "a16"))
216 return g723_2bit;
217 else if(!stricmp(name, ".a40") || !stricmp(name, "a40"))
218 return g723_5bit;
219 else if(!stricmp(name, ".g723"))
220 return g723_3bit;
221 else if(!stricmp(name, ".g729"))
222 return g729Audio;
223 else if(!stricmp(name, ".ilbc"))
224 return ilbcAudio;
225 else if(!stricmp(name, ".a24"))
226 return g723_3bit;
227 else if(!stricmp(name, ".a40"))
228 return g723_5bit;
229 else if(!stricmp(name, ".cda"))
230 return cdaStereo;
231 else if(!stricmp(name, ".sx"))
232 return sx96Voice;
233 else if(!stricmp(name, ".gsm"))
234 return gsmVoice;
235 else if(!stricmp(name, ".mp1"))
236 return mp1Audio;
237 else if(!stricmp(name, ".mp2"))
238 return mp2Audio;
239 else if(!stricmp(name, ".mp3"))
240 return mp3Audio;
241 else
242 return unknownEncoding;
243 }
244
245 const char *Audio::getMIME(Info &info)
246 {
247 if(info.format == wave)
248 return "audio/x-wav";
249
250 if(info.format == snd) {
251 switch(info.encoding) {
252 case g721ADPCM:
253 return "audio/x-adpcm";
254 default:
255 return "audio/basic";
256 }
257 }
258
259 if(info.format == riff)
260 return "audio/x-riff";
261
262 switch(info.encoding) {
263 case speexVoice:
264 case speexAudio:
265 return "application/x-spx";
266 case mp1Audio:
267 case mp2Audio:
268 case mp3Audio:
269 return "audio/x-mpeg";
270 case pcm16Mono:
271 return "audio/l16";
272 case voxADPCM:
273 return "audio/x-vox";
274 case gsmVoice:
275 return "audio/x-gsm";
276 case g729Audio:
277 return "audio/g729";
278 case ilbcAudio:
279 return "audio/iLBC";
280 default:
281 return NULL;
282 }
283 }
284
285 const char *Audio::getName(encoding_t encoding)
286 {
287 switch(encoding) {
288 case pcm8Stereo:
289 case pcm8Mono:
290 return "pcm8";
291 case cdaStereo:
292 case cdaMono:
293 case pcm16Stereo:
294 case pcm16Mono:
295 return "pcm16";
296 case pcm32Stereo:
297 case pcm32Mono:
298 return "pcm32";
299 case mulawAudio:
300 return "pcmu";
301 case alawAudio:
302 return "pcma";
303 case g721ADPCM:
304 return "adpcm";
305 case ilbcAudio:
306 return "ilbc";
307 case g729Audio:
308 return "g.729";
309 case g722Audio:
310 case g722_7bit:
311 case g722_6bit:
312 return "g.722";
313 case g723_2bit:
314 case g723_3bit:
315 case g723_5bit:
316 return "g.723";
317 case gsmVoice:
318 return "gsm";
319 case msgsmVoice:
320 return "msgsm";
321 case mp1Audio:
322 return "mp1";
323 case mp2Audio:
324 return "mp2";
325 case mp3Audio:
326 return "mp3";
327 case okiADPCM:
328 return "oki";
329 case voxADPCM:
330 return "vox";
331 case sx73Voice:
332 return "sx73";
333 case sx96Voice:
334 return "sx96";
335 case speexVoice:
336 case speexAudio:
337 return "speex";
338 default:
339 return "unknown";
340 }
341 }
342
343 bool Audio::is_buffered(encoding_t encoding)
344 {
345 switch(encoding) {
346 case mp1Audio:
347 case mp2Audio:
348 case mp3Audio:
349 return true;
350 default:
351 return false;
352 }
353 }
354
355 bool Audio::is_linear(encoding_t encoding)
356 {
357 switch(encoding) {
358 case cdaStereo:
359 case cdaMono:
360 case pcm16Stereo:
361 case pcm16Mono:
362 return true;
363 default:
364 return false;
365 }
366 }
367
368 Audio::level_t Audio::impulse(encoding_t encoding, void *buffer, unsigned samples)
369 {
370 unsigned long sum = 0;
371 unsigned long count;
372 linear_t sp;
373 int mb;
374 unsigned char *sv = (unsigned char *)&mb, *s1, *s2;
375
376 if(!samples)
377 samples = getCount(encoding);
378
379 switch(encoding) {
380 case cdaStereo:
381 case pcm16Stereo:
382 samples *= 2;
383 case pcm16Mono:
384 case cdaMono:
385 count = samples;
387 sp = (linear_t)buffer;
388 while(samples--) {
389 if(*sp < 0)
390 sum -= *(sp++);
391 else
392 sum += *(sp++);
393 }
394 return (level_t)(sum/count);
395 }
396
397 s1 = (unsigned char *)buffer;
398 s2 = s1 + 1;
399 while(samples--) {
400 sv[0] = *s2;
401 sv[1] = *s1;
402 s1 += 2;
403 s2 += 2;
404 if(mb < 0)
405 sum -= mb;
406 else
407 sum += mb;
408 }
409 return (level_t)(sum / count);
410 default:
411 return -1;
412 }
413 }
414
415 Audio::level_t Audio::impulse(Info &info, void *buffer, unsigned samples)
416 {
417 unsigned long sum = 0;
418 unsigned long count;
419 sample_t *sp, mb;
420 snd16_t *up, ub;
421 unsigned char *sv = (unsigned char *)&mb, *s1, *s2;
422 unsigned char *uv = (unsigned char *)&ub;
423
424 if(!samples)
425 samples = info.framecount;
426
427 if(!samples)
428 samples = getCount(info.encoding);
429
430 switch(info.encoding) {
431 case cdaStereo:
432 case pcm16Stereo:
433 samples *= 2;
434 case pcm16Mono:
435 case cdaMono:
436 count = samples;
437 if(info.format == snd && (info.order ==
__BYTE_ORDER || !info.order)) {
438 count *= 2;
439 up = (snd16_t *)buffer;
440 while(samples--)
441 sum += *(up++);
442 return (level_t)(sum / count);
443 }
444 if(info.format == snd) {
445 count *= 2;
446 s1 = (unsigned char *)buffer;
447 s2 = s1 + 1;
448 while(samples--) {
449 uv[0] = *s2;
450 uv[1] = *s1;
451 s2 += 2;
452 s1 += 2;
453 sum += ub;
454 }
455 return (level_t)(sum / count);
456 }
458 sp = (linear_t)buffer;
459 while(samples--) {
460 if(*sp < 0)
461 sum -= *(sp++);
462 else
463 sum += *(sp++);
464 }
465 return (level_t)(sum/count);
466 }
467
468 s1 = (unsigned char *)buffer;
469 s2 = s1 + 1;
470 while(samples--) {
471 sv[0] = *s2;
472 sv[1] = *s1;
473 s1 += 2;
474 s2 += 2;
475 if(mb < 0)
476 sum -= mb;
477 else
478 sum += mb;
479 }
480 return (level_t)(sum / count);
481 default:
482 return -1;
483 }
484 }
485
486 Audio::level_t Audio::peak(encoding_t encoding, void *buffer, unsigned samples)
487 {
488 level_t max = 0, value;
489 sample_t *sp, mb;
490 unsigned char *sv = (unsigned char *)&mb, *s1, *s2;
491
492 if(!samples)
493 samples = getCount(encoding);
494
495 switch(encoding) {
496 case cdaStereo:
497 case pcm16Stereo:
498 samples *= 2;
499 case pcm16Mono:
500 case cdaMono:
502 sp = (linear_t)buffer;
503 while(samples--) {
504 value = *(sp++);
505 if(value < 0)
506 value = -value;
507 if(value > max)
508 max = value;
509 }
510 return max;
511 }
512
513 s1 = (unsigned char *)buffer;
514 s2 = s1 + 1;
515 while(samples--) {
516 sv[0] = *s2;
517 sv[1] = *s1;
518 s1 += 2;
519 s2 += 2;
520 if(mb < 0)
521 mb = -mb;
522 if(mb > max)
523 max = mb;
524 }
525 return max;
526 default:
527 return -1;
528 }
529 }
530
531 Audio::level_t Audio::peak(Info &info, void *buffer, unsigned samples)
532 {
533 level_t max = 0, value;
534 unsigned long count;
535 sample_t *sp, mb;
536 snd16_t *up, ub;
537 unsigned char *sv = (unsigned char *)&mb, *s1, *s2;
538 unsigned char *uv = (unsigned char *)&ub;
539
540 if(!samples)
541 samples = info.framecount;
542
543 if(!samples)
544 samples = getCount(info.encoding);
545
546 switch(info.encoding) {
547 case cdaStereo:
548 case pcm16Stereo:
549 samples *= 2;
550 case pcm16Mono:
551 case cdaMono:
552 count = samples;
553 if(info.format == snd && (info.order ==
__BYTE_ORDER || !info.order)) {
554 count *= 2;
555 up = (snd16_t *)buffer;
556 while(samples--) {
557 value = (level_t)(*(up++) / 2);
558 if(value > max)
559 max = value;
560 }
561 return max;
562 }
563 if(info.format == snd) {
564 count *= 2;
565 s1 = (unsigned char *)buffer;
566 s2 = s1 + 1;
567 while(samples--) {
568 uv[0] = *s2;
569 uv[1] = *s1;
570 s2 += 2;
571 s1 += 2;
572 ub /= 2;
573 if((level_t)ub > max)
574 max = ub;
575 }
576 return max;
577 }
579 sp = (linear_t)buffer;
580 while(samples--) {
581 value = *(sp++);
582 if(value < 0)
583 value = -value;
584 if(value > max)
585 max = value;
586 }
587 return max;
588 }
589
590 s1 = (unsigned char *)buffer;
591 s2 = s1 + 1;
592 while(samples--) {
593 sv[0] = *s2;
594 sv[1] = *s1;
595 s1 += 2;
596 s2 += 2;
597 if(mb < 0)
598 mb = -mb;
599 if(mb > max)
600 max = mb;
601 }
602 return max;
603 default:
604 return -1;
605 }
606 }
607
608 void Audio::swapEncoded(Info &info, encoded_t buffer, size_t bytes)
609 {
610 char buf;
611
612 if(!is_linear(info.encoding))
613 return;
614
616 return;
617
618 // options for machine optimized should be inserted here
619
620 bytes /= 2;
621 while(bytes--) {
622 buf = buffer[1];
623 buffer[1] = *buffer;
624 *buffer = buf;
625 buffer += 2;
626 }
627 }
628
629 bool Audio::swapEndian(encoding_t encoding, void *buffer, unsigned samples)
630 {
631 unsigned char buf;
632 unsigned char *s1, *s2, *s3, *s4;
633 if(is_stereo(encoding))
634 samples *= 2;
635
636 switch(encoding) {
637 case pcm16Mono:
638 case pcm16Stereo:
639 case cdaMono:
640 case cdaStereo:
642 return true;
643
644 s1 = (unsigned char *)buffer;
645 s2 = s1 + 1;
646 while(samples--) {
647 buf = *s1;
648 *s1 = *s2;
649 *s2 = buf;
650 s1 += 2;
651 s2 += 2;
652 }
653 return false;
654 case pcm32Mono:
655 case pcm32Stereo:
657 return true;
658
659 s1 = (unsigned char *)buffer;
660 s2 = s1 + 1;
661 s3 = s2 + 1;
662 s4 = s3 + 1;
663 while(samples--) {
664 buf = *s1;
665 *s1 = *s4;
666 *s4 = buf;
667 buf = *s2;
668 *s2 = *s3;
669 *s3 = buf;
670 s1 += 4;
671 s2 += 4;
672 s3 += 4;
673 s4 += 4;
674 }
675 return false;
676 default:
677 return true;
678 }
679 }
680
681 bool Audio::swapEndian(Info &info, void *buffer, unsigned samples)
682 {
683 unsigned char buf;
684 unsigned char *s1, *s2, *s3, *s4;
685 if(is_stereo(info.encoding))
686 samples *= 2;
687
688 switch(info.encoding) {
689 case pcm16Mono:
690 case pcm16Stereo:
691 case cdaMono:
692 case cdaStereo:
694 return true;
695
696 s1 = (unsigned char *)buffer;
697 s2 = s1 + 1;
698 while(samples--) {
699 buf = *s1;
700 *s1 = *s2;
701 *s2 = buf;
702 s1 += 2;
703 s2 += 2;
704 }
705 return false;
706 case pcm32Mono:
707 case pcm32Stereo:
709 return true;
710
711 s1 = (unsigned char *)buffer;
712 s2 = s1 + 1;
713 s3 = s2 + 1;
714 s4 = s3 + 1;
715 while(samples--) {
716 buf = *s1;
717 *s1 = *s4;
718 *s4 = buf;
719 buf = *s2;
720 *s2 = *s3;
721 *s3 = buf;
722 s1 += 4;
723 s2 += 4;
724 s3 += 4;
725 s4 += 4;
726 }
727 return false;
728 default:
729 return true;
730 }
731 }
732
733
734 bool Audio::is_endian(encoding_t encoding)
735 {
736 switch(encoding) {
737 case cdaMono:
738 case cdaStereo:
739 case pcm32Mono:
740 case pcm32Stereo:
741 case pcm16Stereo:
742 case pcm16Mono:
744 return false;
745 default:
746 return true;
747 }
748 }
749
750 bool Audio::is_endian(Info &info)
751 {
752 switch(info.encoding) {
753 case cdaStereo:
754 case cdaMono:
755 case pcm16Stereo:
756 case pcm16Mono:
757 case pcm32Stereo:
758 case pcm32Mono:
760 return false;
761 default:
762 return true;
763 }
764 }
765
766 timeout_t Audio::getFraming(Info &info, timeout_t timeout)
767 {
768 timeout_t fa = info.framing;
769 unsigned long frames;
770
771 if(!timeout)
772 return fa;
773
774 if(!fa)
775 return timeout;
776
777 frames = timeout / fa;
778 return frames * fa;
779 }
780
781 timeout_t Audio::getFraming(encoding_t encoding, timeout_t timeout)
782 {
783 timeout_t fa = 0;
784 unsigned long frames;
785
786 switch(encoding) {
787 case mp1Audio:
788 fa = 8;
789 break;
790 case mp2Audio:
791 case mp3Audio:
792 fa = 26;
793 break;
794 case msgsmVoice:
795 fa = 40;
796 break;
797 case g729Audio:
798 fa = 10;
799 break;
800 case gsmVoice:
801 case speexVoice:
802 case speexAudio:
803 case speexUltra:
804 fa = 20;
805 break;
806 case ilbcAudio:
807 fa = 30;
808 break;
809 case sx96Voice:
810 case sx73Voice:
811 fa = 15;
812 default:
813 break;
814 }
815 if(!timeout)
816 return fa;
817
818 if(!fa)
819 return timeout;
820
821 frames = timeout / fa;
822 return frames * fa;
823 }
824
825 int Audio::getCount(encoding_t encoding)
826 {
827 switch(encoding) {
828 case mp1Audio:
829 return 384;
830 case mp2Audio:
831 case mp3Audio:
832 return 1152;
833 case msgsmVoice:
834 return 320;
835 case gsmVoice:
836 return 160;
837 case ilbcAudio:
838 return 240;
839 case g729Audio:
840 return 80;
841 case sx73Voice:
842 case sx96Voice:
843 return 120;
844 case speexVoice:
845 return 160;
846 case speexAudio:
847 return 320;
848 case speexUltra:
849 return 640;
850 case unknownEncoding:
851 return 0;
852 case g723_2bit:
853 return 4;
854 case g723_3bit:
855 case g723_5bit:
856 return 8;
857 case g721ADPCM:
858 case okiADPCM:
859 case voxADPCM:
860 return 2;
861 default:
862 return 1;
863 }
864 }
865
866 int Audio::getFrame(encoding_t encoding, int samples)
867 {
868 int framing = 0;
869 switch(encoding) {
870 case sx73Voice:
871 framing = 14;
872 break;
873 case sx96Voice:
874 framing = 18;
875 break;
876 case msgsmVoice:
877 framing = 65;
878 break;
879 case speexVoice:
880 framing = 20;
881 break;
882 case speexAudio:
883 framing = 40;
884 break;
885 case gsmVoice:
886 framing = 33;
887 break;
888 case ilbcAudio:
889 framing = 50;
890 break;
891 case g729Audio:
892 framing = 10;
893 break;
894 case g723_2bit:
895 framing = 1;
896 break;
897 case g723_3bit:
898 framing = 3;
899 break;
900 case g723_5bit:
901 framing = 5;
902 break;
903 case unknownEncoding:
904 return 0;
905 case pcm32Stereo:
906 return 8;
907 case pcm32Mono:
908 case pcm16Stereo:
909 case cdaStereo:
910 framing = 4;
911 break;
912 case pcm8Stereo:
913 case pcm16Mono:
914 case cdaMono:
915 framing = 2;
916 break;
917 default:
918 framing = 1;
919 }
920 if(!samples)
921 return framing;
922
923 return (samples / framing) * framing;
924 }
925
926 void Audio::fill(unsigned char *addr, int samples, encoding_t encoding)
927 {
928 int frame = getFrame(encoding);
929 int count = getCount(encoding);
930
931 if(!frame || !count)
932 return;
933
934 while(samples >= count) {
935 switch(encoding) {
936 case mulawAudio:
937 *addr = 0xff;
938 break;
939 case alawAudio:
940 *addr = 0x55;
941 break;
942 default:
943 memset(addr, 0, frame);
944 break;
945 }
946 addr += frame;
947 samples -= count;
948 }
949 }
950
951 Audio::rate_t Audio::getRate(encoding_t encoding, rate_t request)
952 {
953 if((long)request == (long)0)
954 request = getRate(encoding);
955
956 switch(encoding) {
957 case pcm8Stereo:
958 case pcm8Mono:
959 case pcm16Stereo:
960 case pcm16Mono:
961 case pcm32Stereo:
962 case pcm32Mono:
963 case mulawAudio:
964 case alawAudio:
965 return request;
966 case voxADPCM:
967 if(request == rate8khz)
968 return rate8khz;
969 return rate6khz;
970 default:
971 break;
972 };
973 return getRate(encoding);
974 }
975
976 Audio::rate_t Audio::getRate(encoding_t encoding)
977 {
978 switch(encoding) {
979 case pcm8Stereo:
980 case pcm8Mono:
981 case pcm16Stereo:
982 case pcm16Mono:
983 case pcm32Stereo:
984 case pcm32Mono:
985 case unknownEncoding:
986 return rateUnknown;
987 case voxADPCM:
988 return rate6khz;
989 case cdaStereo:
990 case cdaMono:
991 return rate44khz;
992 case speexAudio:
993 return rate16khz;
994 case speexUltra:
995 return rate32khz;
996 default:
997 return rate8khz;
998 }
999 }
1000
1001 unsigned long Audio::toSamples(encoding_t encoding, size_t bytes)
1002 {
1003 unsigned long sf = getFrame(encoding);
1004 if(!bytes || !sf)
1005 return 0;
1006 unsigned long frames = (unsigned long)(bytes / sf);
1007 return frames * getCount(encoding);
1008 }
1009
1010 unsigned long Audio::toSamples(Info &info, size_t bytes)
1011 {
1012 if(!bytes)
1013 return 0;
1014
1015 unsigned long frames = (unsigned long)(bytes / info.framesize);
1016 return frames * info.framecount;
1017 }
1018
1019 size_t Audio::toBytes(encoding_t encoding, unsigned long samples)
1020 {
1021 unsigned long sc = getCount(encoding);
1022 if(!samples || !sc)
1023 return 0;
1024 unsigned long frames = samples / sc;
1025 return frames * getFrame(encoding);
1026 }
1027
1028 size_t Audio::maxFramesize(Info &info)
1029 {
1030 switch(info.encoding) {
1031 case mp1Audio:
1032 return 682;
1033 case mp2Audio:
1034 case mp3Audio:
1035 return 1735;
1036 default:
1037 return info.framesize;
1038 }
1039 }
1040
1041 size_t Audio::toBytes(Info &info, unsigned long samples)
1042 {
1043 if(!samples)
1044 return 0;
1045 unsigned long frames = samples / info.framecount;
1046 return frames * info.framesize;
1047 }
1048
1049 bool Audio::is_mono(encoding_t encoding)
1050 {
1051 switch(encoding) {
1052 case pcm8Stereo:
1053 case pcm16Stereo:
1054 case pcm32Stereo:
1055 case cdaStereo:
1056 return false;
1057 default:
1058 return true;
1059 }
1060 }
1061
1062 bool Audio::is_stereo(encoding_t encoding)
1063 {
1064 return !is_mono(encoding);
1065 }
1066
1067 #ifdef _MSWINDOWS_
1068 #define snprintf _snprintf
1069 #endif
1070
1071 void Audio::toTimestamp(timeout_t duration, char *buf, size_t len)
1072 {
1073 timeout_t msec = duration % 1000;
1074 timeout_t secs = (duration / 1000) % 60;
1075 timeout_t mins = (duration / 60000) % 60;
1076 timeout_t hours = (duration /3600000);
1077
1078 snprintf(buf, len, "%ld:%02ld:%02ld.%03ld", hours, mins, secs, msec);
1079 }
1080
1081 timeout_t Audio::toTimeout(const char *buf)
1082 {
1083 const char *cp, *sp;
1084 timeout_t msec = 0;
1085 timeout_t sec = 0;
1086
1087 cp = strchr(buf, '.');
1088 if(cp) {
1089 msec = atol(cp + 1);
1090 sp = --cp;
1091 }
1092 else
1093 sp = strrchr(buf, ':');
1094
1095 if(!sp) {
1096 sp = buf;
1097 while(*sp && isdigit(*sp))
1098 ++sp;
1099 if(*sp && tolower(*sp) == 'm' && tolower(sp[1] == 's'))
1100 return atol(buf);
1101 if(tolower(*sp) == 'h')
1102 return atol(buf) * 3600000;
1103 if(tolower(*sp) == 'm')
1104 return atol(buf) * 60000;
1105 return atol(buf) * 1000l;
1106 }
1107 while(*sp != ':' && sp > buf)
1108 --sp;
1109
1110 if(sp == buf)
1111 return atol(buf) * 1000 + msec;
1112
1113 sec = atol(sp + 1) * 1000;
1114 --sp;
1115 while(*sp != ':' && sp > buf)
1116 --sp;
1117
1118 if(sp == buf)
1119 return atol(buf) * 60000 + sec + msec;
1120
1121 return atol(buf) * 3600000 + atol(++sp) * 60000 + sec + msec;
1122 }
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
#define BAYONNE_NAMESPACE
GNU Bayonne library namespace.