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