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