📄 friends.cpp
字号:
// Copyright (C) 1999-2005 Open Source Telecom Corporation.// // This program is free software; you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation; either version 2 of the License, or// (at your option) any later version.// // This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the// GNU General Public License for more details.//// You should have received a copy of the GNU General Public License// along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.// // As a special exception, you may use this file as part of a free software// library without restriction. Specifically, if other files instantiate// templates or use macros or inline functions from this file, or you compile// this file and link it with other files to produce an executable, this// file does not by itself cause the resulting executable to be covered by// the GNU General Public License. This exception does not however// invalidate any other reasons why the executable file might be covered by// the GNU General Public License.//// This exception applies only to the code released under the name GNU// ccAudio. If you copy code from other releases into a copy of GNU// ccAudio, as the General Public License permits, the exception does// not apply to the code that you add in this way. To avoid misleading// anyone as to the status of such modified files, you must delete// this exception notice from them.//// If you write modifications of your own for GNU ccAudio, it is your choice// whether to permit this exception to apply to your modifications.// If you do not wish that, delete this exception notice.//#include "private.h"#include "audio2.h"#include <cmath>#include <cctype>#include <cstdio>#ifndef W32#include <cstdlib>#include <unistd.h>#include <sys/stat.h>#endif#ifdef HAVE_SHL_LOAD#include <dl.h> #endif#ifdef HAVE_MACH_DYLD#include <mach-o/dyld.h>#endif#if defined(HAVE_DLFCN_H)extern "C" {#include <dlfcn.h> }#ifndef RTLD_GLOBAL #define RTLD_GLOBAL 0#endif#endif // HAVE_DLFN_H#ifndef M_PI#define M_PI 3.14159265358979323846#endifusing namespace ost;class AudioRegistry {public: AudioRegistry(); const char *codecdir;};#ifdef W32extern LONG buffer_framing = 120; // millisecextern LONG buffer_count = 8;#endifstatic class AudioRegistry registry;#if defined(CAPE_REGISTRY_PREFIX)#define REGISTRY_AUDIO_SETTINGS CAPE_REGISTRY_PREFIX "\\Audio Settings"#else#define REGISTRY_AUDIO_SETTINGS "SOFTWARE\\CAPE Framework\\Audio Settings"#endifAudioRegistry::AudioRegistry(){#ifdef W32 static TCHAR regpath[256]; LONG value; HKEY key; char *env; codecdir = "C:/Program Files/Common Files/GNU Telephony/Audio Codecs";#ifdef DEBUG#define PLUGINS "Debug"#else#define PLUGINS "Codecs"#endif if(RegOpenKey(HKEY_LOCAL_MACHINE, REGISTRY_AUDIO_SETTINGS, &key) == ERROR_SUCCESS) { if(RegQueryValue(key, PLUGINS, regpath, &value) == ERROR_SUCCESS) { codecdir = regpath; env = regpath; while(NULL != (env = strchr(env, '\\'))) *env = '/'; } RegQueryValue(key, "Framing", NULL, &buffer_framing); RegQueryValue(key, "Buffers", NULL, &buffer_count); RegCloseKey(key); }#else codecdir = CODEC_LIBPATH;#endif }const char *Audio::getCodecPath(void){ return registry.codecdir;}Audio::Level Audio::tolevel(float dbm){ double l = pow(10.0, (dbm - M_PI)/20.0)*(32768.0*0.70711); return (Level)(l*l);}float Audio::todbm(Level l){ return (float)(log10(sqrt((float)l)/(32768.0*0.70711))*20.0 + M_PI);}const char *Audio::getExtension(Encoding encoding){ switch(encoding) { case cdaStereo: case pcm16Stereo: case pcm32Stereo: case cdaMono: case pcm16Mono: case pcm32Mono: return ".wav"; case alawAudio: return ".al"; case gsmVoice: return ".gsm"; case msgsmVoice: return ".wav"; case mp1Audio: return ".mp1"; case mp2Audio: return ".mp2"; case mp3Audio: return ".mp3"; case voxADPCM: return ".vox"; case speexVoice: case speexAudio: return ".spx"; case sx73Voice: case sx96Voice: return ".sx"; case g721ADPCM: return ".adpcm"; default: return ".au"; }} Audio::Encoding Audio::getMono(Encoding encoding){ switch(encoding) { case cdaStereo: return cdaMono; case pcm8Stereo: return pcm8Mono; case pcm16Stereo: return pcm16Mono; case pcm32Stereo: return pcm32Mono; default: return encoding; }}Audio::Encoding Audio::getStereo(Encoding encoding){ switch(encoding) { case cdaStereo: case pcm8Stereo: case pcm16Stereo: case pcm32Stereo: return encoding; case cdaMono: return cdaStereo; case pcm8Mono: return pcm8Stereo; case pcm16Mono: return pcm16Stereo; case pcm32Mono: return pcm32Stereo; default: return unknownEncoding; }}Audio::Encoding Audio::getEncoding(const char *name){ if(!stricmp(name, "ulaw") || !stricmp(name, "mulaw") || !stricmp(name, "pcmu")) return mulawAudio; else if(!stricmp(name, "alaw") || !stricmp(name, "pcma")) return alawAudio; else if(!stricmp(name, "linear") || !stricmp(name, "pcm16") || !stricmp(name, "pcm") || !stricmp(name, "l16")) return pcm16Mono; else if(!stricmp(name, "cda")) return cdaStereo; else if(!stricmp(name, "gsm")) return gsmVoice; else if(!stricmp(name, "msgsm")) return msgsmVoice; else if(!stricmp(name, "pcm8") || !stricmp(name, "l8")) return pcm8Mono; else if(!stricmp(name, "pcm32")) return pcm32Mono; else if(!stricmp(name, "adpcm")) return g721ADPCM; else if(!stricmp(name, "mp1")) return mp1Audio; else if(!stricmp(name, "mp2")) return mp2Audio; else if(!stricmp(name, "mp3")) return mp3Audio; else if(!stricmp(name, "oki")) return okiADPCM; else if(!stricmp(name, "vox")) return voxADPCM; else if(!stricmp(name, "sx73")) return sx73Voice; else if(!stricmp(name, "sx96")) return sx96Voice; else if(!stricmp(name, "spx") || !stricmp(name, "speex")) return speexVoice; else if(!stricmp(name, "g723_16") || !stricmp(name, "g.723_16")) return g723_2bit; else if(!stricmp(name, "g723_24") || !stricmp(name, "g.723_24")) return g723_3bit; else if(!stricmp(name, "g723_40") || !stricmp(name, "g.723_40")) return g723_5bit; else if(!stricmp(name, ".al")) return alawAudio; else if(!stricmp(name, ".ul")) return mulawAudio; else if(!stricmp(name, ".adpcm")) return g721ADPCM; else if(!stricmp(name, ".cda")) return cdaStereo; else if(!stricmp(name, ".sx")) return sx96Voice; else if(!stricmp(name, ".gsm")) return gsmVoice; else if(!stricmp(name, ".mp1")) return mp1Audio; else if(!stricmp(name, ".mp2")) return mp2Audio; else if(!stricmp(name, ".mp3")) return mp3Audio; else return unknownEncoding;}const char *Audio::getMIME(Info &info){ if(info.format == wave) return "audio/x-wav"; if(info.format == snd) { switch(info.encoding) { case g721ADPCM: return "audio/x-adpcm"; default: return "audio/basic"; } } if(info.format == riff) return "audio/x-riff"; switch(info.encoding) { case speexVoice: case speexAudio: return "application/x-spx"; case mp1Audio: case mp2Audio: case mp3Audio: return "audio/x-mpeg"; case pcm16Mono: return "audio/l16"; case voxADPCM: return "audio/x-vox"; default: return NULL; }}const char *Audio::getName(Encoding encoding){ switch(encoding) { case pcm8Stereo: case pcm8Mono: return "pcm8"; case cdaStereo: case cdaMono: case pcm16Stereo: case pcm16Mono: return "pcm16"; case pcm32Stereo: case pcm32Mono: return "pcm32"; case mulawAudio: return "pcmu"; case alawAudio: return "pcma"; case g721ADPCM: return "adpcm"; case g722Audio: case g722_7bit: case g722_6bit: return "g.722"; case g723_2bit: case g723_3bit: case g723_5bit: return "g.723"; case gsmVoice: return "gsm"; case msgsmVoice: return "msgsm"; case mp1Audio: return "mp1"; case mp2Audio: return "mp2"; case mp3Audio: return "mp3"; case okiADPCM: return "oki"; case voxADPCM: return "vox"; case sx73Voice: return "sx73"; case sx96Voice: return "sx96"; case speexVoice: case speexAudio: return "speex"; default: return "unknown"; }}bool Audio::isBuffered(Encoding encoding){ switch(encoding) { case mp1Audio: case mp2Audio: case mp3Audio: return true; default: return false; }} bool Audio::isLinear(Encoding encoding){ switch(encoding) { case cdaStereo: case cdaMono: case pcm16Stereo: case pcm16Mono: return true; default: return false; }}Audio::Level Audio::getImpulse(Encoding encoding, void *buffer, unsigned samples){ unsigned long sum = 0; unsigned long count; Linear sp; int mb; unsigned char *sv = (unsigned char *)&mb, *s1, *s2; if(!samples) samples = getCount(encoding); switch(encoding) { case cdaStereo: case pcm16Stereo: samples *= 2; case pcm16Mono: case cdaMono: count = samples; if(__BYTE_ORDER == __LITTLE_ENDIAN) { sp = (Linear)buffer; while(samples--) { if(*sp < 0) sum -= *(sp++); else sum += *(sp++); } return (Level)(sum/count); } s1 = (unsigned char *)buffer; s2 = s1 + 1; while(samples--) { sv[0] = *s2; sv[1] = *s1; s1 += 2; s2 += 2; if(mb < 0) sum -= mb; else sum += mb; } return (Level)(sum / count); default: return -1; }}Audio::Level Audio::getImpulse(Info &info, void *buffer, unsigned samples){ unsigned long sum = 0; unsigned long count; Sample *sp, mb; snd16_t *up, ub; unsigned char *sv = (unsigned char *)&mb, *s1, *s2; unsigned char *uv = (unsigned char *)&ub; if(!samples) samples = info.framecount; if(!samples) samples = getCount(info.encoding); switch(info.encoding) { case cdaStereo: case pcm16Stereo: samples *= 2; case pcm16Mono: case cdaMono: count = samples; if(info.format == snd && (info.order == __BYTE_ORDER || !info.order)) { count *= 2; up = (snd16_t *)buffer; while(samples--) sum += *(up++); return (Level)(sum / count); } if(info.format == snd) { count *= 2; s1 = (unsigned char *)buffer; s2 = s1 + 1; while(samples--) { uv[0] = *s2; uv[1] = *s1; s2 += 2; s1 += 2; sum += ub; } return (Level)(sum / count); } if(__BYTE_ORDER == info.order || !info.order) { sp = (Linear)buffer; while(samples--) { if(*sp < 0) sum -= *(sp++); else sum += *(sp++); } return (Level)(sum/count); } s1 = (unsigned char *)buffer; s2 = s1 + 1; while(samples--) { sv[0] = *s2; sv[1] = *s1; s1 += 2; s2 += 2; if(mb < 0) sum -= mb; else sum += mb; } return (Level)(sum / count); default: return -1; }}Audio::Level Audio::getPeak(Encoding encoding, void *buffer, unsigned samples){ Level max = 0, value; unsigned long count; Sample *sp, mb; unsigned char *sv = (unsigned char *)&mb, *s1, *s2; if(!samples) samples = getCount(encoding); switch(encoding) { case cdaStereo: case pcm16Stereo: samples *= 2; case pcm16Mono: case cdaMono: count = samples; if(__BYTE_ORDER == __LITTLE_ENDIAN) { sp = (Linear)buffer; while(samples--) { value = *(sp++); if(value < 0) value = -value; if(value > max) max = value; } return max; } s1 = (unsigned char *)buffer; s2 = s1 + 1; while(samples--) { sv[0] = *s2; sv[1] = *s1; s1 += 2; s2 += 2; if(mb < 0) mb = -mb; if(mb > max) max = mb; } return max; default: return -1; }}Audio::Level Audio::getPeak(Info &info, void *buffer, unsigned samples){ Level max = 0, value; unsigned long count; Sample *sp, mb; snd16_t *up, ub; unsigned char *sv = (unsigned char *)&mb, *s1, *s2; unsigned char *uv = (unsigned char *)&ub; if(!samples) samples = info.framecount; if(!samples) samples = getCount(info.encoding); switch(info.encoding) { case cdaStereo: case pcm16Stereo: samples *= 2; case pcm16Mono: case cdaMono: count = samples; if(info.format == snd && (info.order == __BYTE_ORDER || !info.order)) { count *= 2; up = (snd16_t *)buffer; while(samples--) { value = (Level)(*(up++) / 2); if(value > max) max = value; } return max; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -