📄 speexcodec.cxx
字号:
/*
* Speex Plugin codec for OpenH323/OPAL
*
* Copyright (C) 2004 Post Increment, All Rights Reserved
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
*
* The Original Code is Open H323 Library.
*
* The Initial Developer of the Original Code is Post Increment
*
* Contributor(s): ______________________________________.
*
* $Log: speexcodec.cxx,v $
* Revision 1.18 2005/08/15 01:57:13 csoutheren
* Removed error/warning on 64 bit platforms
*
* Revision 1.17 2005/07/15 10:09:00 rogerhardiman
* Fix SF bug 1237507. Windows uses malloc.h. Linux and FreeBSD uses stdlib.h
* Wrap #include with _WIN32 to be consistent with malloc.h in pwlib.
*
* Revision 1.16 2004/12/20 23:37:43 csoutheren
* Added packet loss concealment as per Jean-Marc Valin suggestions
*
* Revision 1.15 2004/12/20 23:18:01 csoutheren
* Added stdlib.h to all plugins to keep FreeBSD happy
* Thanks to Kevin Oberman
*
* Revision 1.14 2004/12/06 13:57:16 csoutheren
* Fixed cut and paste error with wideband speex codec
*
* Revision 1.13 2004/11/29 06:29:02 csoutheren
* Added support for wideband codec modes
*
* Revision 1.12 2004/06/16 05:32:52 csoutheren
* Removed non-working codecs
*
* Revision 1.11 2004/06/16 04:35:50 csoutheren
* Cleanup and add extra tables
*
* Revision 1.10 2004/06/16 04:21:05 csoutheren
* Added rest of supported Speex codecs
*
* Revision 1.9 2004/06/16 03:57:58 csoutheren
* Fixed strings
*
* Revision 1.8 2004/06/16 03:33:03 csoutheren
* Initial support for ACM Speex
*
* Revision 1.7 2004/05/13 10:35:09 csoutheren
* Fixed bit rates and bytes per frame for each codec
*
* Revision 1.6 2004/05/12 12:32:44 csoutheren
* More name fixes
*
* Revision 1.5 2004/05/12 11:27:04 csoutheren
* Changed codec name to match embedded codec
*
* Revision 1.4 2004/04/09 12:24:18 csoutheren
* Renamed h323plugin.h to opalplugin.h, and modified everything else
* as required
*
* Revision 1.3 2004/04/04 12:57:49 csoutheren
* Updated Makefiles and fixed Linux problems
*
* Revision 1.2 2004/04/04 12:44:18 csoutheren
* Added file headers
*
*/
#include <opalplugin.h>
extern "C" {
PLUGIN_CODEC_IMPLEMENT("Speex")
};
#include <stdlib.h>
#ifdef _WIN32
#include <malloc.h>
#endif
#include <string.h>
#include "libspeex/speex.h"
#define NARROW_SAMPLES_PER_FRAME 160
#define WIDE_SAMPLES_PER_FRAME 320
#define NARROW_NS_PER_FRAME 20000
#define WIDE_NS_PER_FRAME 20000
const float MaxSampleValue = 32767.0;
const float MinSampleValue = -32767.0;
struct PluginSpeexContext {
struct SpeexBits * bits;
void * coderState;
unsigned encoderFrameSize;
};
/////////////////////////////////////////////////////////////////////////////
static void * create_encoder(const struct PluginCodec_Definition * codec)
{
int mode = (int)(long)(codec->userData);
struct PluginSpeexContext * context = new PluginSpeexContext;
context->bits = new SpeexBits;
speex_bits_init(context->bits);
if (codec->sampleRate == 16000)
context->coderState = speex_encoder_init(&speex_wb_mode);
else
context->coderState = speex_encoder_init(&speex_nb_mode);
speex_encoder_ctl(context->coderState, SPEEX_GET_FRAME_SIZE, &context->encoderFrameSize);
speex_encoder_ctl(context->coderState, SPEEX_SET_QUALITY, &mode);
return context;
}
static int codec_encoder(const struct PluginCodec_Definition * codec,
void * _context,
const void * from,
unsigned * fromLen,
void * to,
unsigned * toLen,
unsigned int * flag)
{
PluginSpeexContext * context = (PluginSpeexContext *)_context;
if (*fromLen != codec->samplesPerFrame*2)
return 0;
short * sampleBuffer = (short *)from;
// convert PCM to float
float floatData[WIDE_SAMPLES_PER_FRAME];
int i;
for (i = 0; i < codec->samplesPerFrame; i++)
floatData[i] = sampleBuffer[i];
// encode PCM data in sampleBuffer to buffer
speex_bits_reset(context->bits);
speex_encode(context->coderState, floatData, context->bits);
*toLen = speex_bits_write(context->bits, (char *)to, context->encoderFrameSize);
return 1;
}
static void destroy_encoder(const struct PluginCodec_Definition * codec, void * _context)
{
PluginSpeexContext * context = (PluginSpeexContext *)_context;
speex_bits_destroy(context->bits);
free(context->bits);
speex_encoder_destroy(context->coderState);
free(context);
}
static void * create_decoder(const struct PluginCodec_Definition * codec)
{
int tmp = 1;
PluginSpeexContext * context = new PluginSpeexContext;
context->bits = new SpeexBits;
speex_bits_init(context->bits);
if (codec->sampleRate == 16000)
context->coderState = speex_decoder_init(&speex_wb_mode);
else
context->coderState = speex_decoder_init(&speex_nb_mode);
speex_decoder_ctl(context->coderState, SPEEX_SET_ENH, &tmp);
return context;
}
static int codec_decoder(const struct PluginCodec_Definition * codec,
void * _context,
const void * from,
unsigned * fromLen,
void * to,
unsigned * toLen,
unsigned int * flag)
{
struct PluginSpeexContext * context = (struct PluginSpeexContext *)_context;
float floatData[WIDE_SAMPLES_PER_FRAME];
short * sampleBuffer = (short *)to;
// if this is a packet loss concealment frame, generate interpolated data
// else decode the real data
if (*flag & PluginCodec_CoderSilenceFrame)
speex_decode(context->coderState, NULL, floatData);
else {
speex_bits_read_from(context->bits, (char *)from, *fromLen);
speex_decode(context->coderState, context->bits, floatData);
}
// convert float to PCM
int i;
for (i = 0; i < codec->samplesPerFrame; i++) {
float sample = floatData[i];
if (sample < MinSampleValue)
sample = MinSampleValue;
else if (sample > MaxSampleValue)
sample = MaxSampleValue;
sampleBuffer[i] = (short)sample;
}
return 1;
}
static void destroy_decoder(const struct PluginCodec_Definition * codec, void * _context)
{
struct PluginSpeexContext * context = (struct PluginSpeexContext *)_context;
speex_bits_destroy(context->bits);
free(context->bits);
speex_decoder_destroy(context->coderState);
free(context);
}
/////////////////////////////////////////////////////////////////////////////
static struct PluginCodec_information licenseInfo = {
//1081075346, // Sun 04 Apr 2004 10:42:26 AM UTC
//1087351735, // Wed 16 Jun 2004 02:08:55 AM UTC
1101695533, // Mon 29 Nov 2004 12:32:13 PM EST
"Craig Southeren, Post Increment", // source code author
"3.1", // source code version
"craigs@postincrement.com", // source code email
"http://www.postincrement.com", // source code URL
"Copyright (C) 2004 by Post Increment, All Rights Reserved", // source code copyright
"MPL 1.0", // source code license
PluginCodec_License_MPL, // source code license
"Speex", // codec description
"Jean-Marc Valin, Xiph Foundation.", // codec author
"1.0.3", // codec version
"jean-marc.valin@hermes.usherb.ca", // codec email
"http://www.speex.org", // codec URL
"(C) 2003 Xiph.Org Foundation, All Rights Reserved", // codec copyright information
"Xiph BSD license", // codec license
PluginCodec_License_BSD // codec license code
};
static const char L16Desc[] = { "L16" };
static const char sdpSpeex[] = { "speex" };
#define EQUIVALENCE_COUNTRY_CODE 9
#define EQUIVALENCE_EXTENSION_CODE 0
#define EQUIVALENCE_MANUFACTURER_CODE 61
#define MICROSOFT_COUNTRY_CODE 181
#define MICROSOFT_T35EXTENSION 0
#define MICROSOFT_MANUFACTURER 21324
#define XIPH_COUNTRY_CODE 0xB5
#define XIPH_EXTENSION_CODE 0x00
#define XIPH_MANUFACTURER_CODE 0x0026
static const unsigned char speexWNarrow8kHdr[] =
{
0x02, 0x00, 0x00, 0x00,
0x00, 0x00, 0xa0, 0x00,
0x00, 0x00, 0xa0, 0x00,
0x04, 0x00, 0x10, 0x00,
0x00, 0x00, 0x00, 0x00,
// WAVEFORMATEX
0x09, 0xa1, // WORD wFormatTag; format type
0x01, 0x00, // WORD nChannels; number of channels (i.e. mono, stereo...)
0x40, 0x1f, 0x00, 0x00, // DWORD nSamplesPerSec; sample rate
0xe8, 0x03, 0x00, 0x00, // DWORD nAvgBytesPerSec; for buffer estimation
0x14, 0x00, // WORD nBlockAlign; block size of data
0x10, 0x00, // WORD wBitsPerSample; Number of bits per sample of mono data
0x0e, 0x00, // WORD cbSize; The count in bytes of the size of extra information
// Speex additional information
0x00, 0x01, // SPEEXWAVEFORMAT_VERSION
0x01, 0x00, // nFramesPerBlock
0x03, 0x00, // nQuality
0x00, 0x00, // nMode
0xf4, 0x01, // nVbrQuality
0x03, 0x00, // nComplexity
0x00, 0x00, // nFlags
// unknown
0x00, 0x00
};
////////////////////////////////////////////////////////////////////////////////////////////////
#define CREATE_IETFSPEEX_CAP_DATA(desc, suffix, ordinal, rate) \
static const char ietfSpeex##suffix[] = "SpeexIETF" #desc; \
static const char ietfSpeex##suffix##Str[] = "speex sr=" #rate ";mode=" #ordinal ";vbr=off;cng=off"; \
static struct PluginCodec_H323NonStandardCodecData ietfSpeex##suffix##Cap = \
{ \
NULL, \
XIPH_COUNTRY_CODE, XIPH_EXTENSION_CODE, XIPH_MANUFACTURER_CODE, \
(const unsigned char *)ietfSpeex##suffix##Str, sizeof(ietfSpeex##suffix##Str)-1, \
NULL \
}; \
////////////////////////////////////////////////////////////////////////////////////////////////
#define CREATE_NARROW_SPEEX_CAP_DATA(desc, suffix, ordinal) \
static const char speex##suffix[] = "Speex" #desc; \
static const char speex##suffix##Str[] = "Speex bs4 Narrow" #ordinal; \
static struct PluginCodec_H323NonStandardCodecData speex##suffix##Cap = \
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -