00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
#include "wvspeex.h"
00011
#include <speex.h>
00012
#include <speex_header.h>
00013
00014
00015
00016
00017
00018
00019 static SpeexMode *
get_speex_mode(WvSpeex::CodecMode modeid,
00020
int samplingrate)
00021 {
00022
00023
if (modeid >= 0 && modeid < SPEEX_NB_MODES)
00024
return speex_mode_list[modeid];
00025
00026
00027 SpeexMode *mode;
00028 assert(samplingrate <= 48000 || !
"sampling rate too high");
00029 assert(samplingrate >= 6000 || !
"sampling rate too low");
00030
if (samplingrate > 25000)
00031 mode = & speex_uwb_mode;
00032
else if (samplingrate > 12500)
00033 mode = & speex_wb_mode;
00034
else
00035 mode = & speex_nb_mode;
00036
return mode;
00037 }
00038
00039
00040
00041
00042
00043 WvSpeexEncoder::WvSpeexEncoder(
00044
const WvSpeex::BitrateSpec &bitratespec,
00045
int samplingrate,
unsigned int channels, WvSpeex::CodecMode modeid,
00046
int complexity) :
00047 spxstate(NULL), spxbits(NULL), spxmode(NULL),
00048 _channels(channels), _samplesperframe(0)
00049 {
00050
00051 spxmode =
get_speex_mode(modeid, samplingrate);
00052 spxstate = speex_encoder_init(spxmode);
00053
if (! spxstate)
00054 {
00055 seterror(
"error during speex_encoder_init");
00056
return;
00057 }
00058 spxbits =
new SpeexBits;
00059 speex_bits_init(spxbits);
00060
00061
00062 speex_encoder_ctl(spxstate, SPEEX_SET_SAMPLING_RATE, &samplingrate);
00063
00064
00065
if (complexity != WvSpeex::DEFAULT_COMPLEXITY)
00066 speex_encoder_ctl(spxstate, SPEEX_SET_COMPLEXITY, &complexity);
00067
00068
00069
switch (bitratespec.
mode)
00070 {
00071
case WvSpeex::BitrateSpec::VBR_QUALITY:
00072 {
00073
int enable = 1;
00074 speex_encoder_ctl(spxstate, SPEEX_SET_VBR, &enable);
00075
float quality = bitratespec.
quality_index * 10;
00076 speex_encoder_ctl(spxstate, SPEEX_SET_VBR_QUALITY,
00077 &quality);
00078
break;
00079 }
00080
00081
case WvSpeex::BitrateSpec::CBR_QUALITY:
00082 {
00083
int quality = int(bitratespec.
quality_index * 10);
00084 speex_encoder_ctl(spxstate, SPEEX_SET_QUALITY,
00085 &quality);
00086
break;
00087 }
00088
00089
case WvSpeex::BitrateSpec::CBR_BITRATE:
00090 {
00091
int bitrate = bitratespec.
nominal_bitrate;
00092 speex_encoder_ctl(spxstate, SPEEX_SET_BITRATE,
00093 &bitrate);
00094
break;
00095 }
00096 }
00097
00098
00099 speex_encoder_ctl(spxstate, SPEEX_GET_FRAME_SIZE,
00100 &_samplesperframe);
00101 }
00102
00103
00104 WvSpeexEncoder::~WvSpeexEncoder()
00105 {
00106 speex_encoder_destroy(spxstate);
00107 speex_bits_destroy(spxbits);
00108
delete spxbits;
00109 }
00110
00111
00112 bool WvSpeexEncoder::_typedencode(IBuffer &inbuf, OBuffer &outbuf,
00113
bool flush)
00114 {
00115
if (! flushspxbits(outbuf))
00116
return false;
00117
for (;;)
00118 {
00119 size_t avail = inbuf.used();
00120
if (avail == 0)
00121
return true;
00122
if (avail < size_t(_samplesperframe))
00123
return ! flush;
00124 speex_encode(spxstate, const_cast<float*>(
00125 inbuf.get(_samplesperframe)), spxbits);
00126
if (! flushspxbits(outbuf))
00127
return false;
00128
if (! flush)
00129
return true;
00130 }
00131 }
00132
00133
00134 bool WvSpeexEncoder::_typedfinish(OBuffer &outbuf)
00135 {
00136
return flushspxbits(outbuf);
00137 }
00138
00139
00140
bool WvSpeexEncoder::flushspxbits(OBuffer &outbuf)
00141 {
00142 size_t needed = speex_bits_nbytes(spxbits);
00143
if (needed == 0)
00144
return true;
00145
00146
while (needed != 0)
00147 {
00148 size_t avail = outbuf.optallocable();
00149
if (avail == 0)
00150
return false;
00151
if (avail > needed)
00152 avail = needed;
00153 speex_bits_write(spxbits, reinterpret_cast<char*>(
00154 outbuf.alloc(avail)), avail);
00155 needed -= avail;
00156 }
00157
00158 speex_bits_reset(spxbits);
00159
return true;
00160 }
00161
00162
00163 int WvSpeexEncoder::samplingrate()
const
00164
{
00165
int rate;
00166 speex_encoder_ctl(const_cast<void*>(spxstate),
00167 SPEEX_GET_SAMPLING_RATE, &rate);
00168
return rate;
00169 }
00170
00171
00172 WvSpeex::CodecMode
WvSpeexEncoder::mode()
const
00173
{
00174
return WvSpeex::CodecMode(spxmode->modeID);
00175 }
00176
00177
00178 bool WvSpeexEncoder::vbr()
const
00179
{
00180
int enabled;
00181 speex_encoder_ctl(const_cast<void*>(spxstate),
00182 SPEEX_GET_VBR, &enabled);
00183
return enabled;
00184 }
00185
00186
00187 int WvSpeexEncoder::nominalbitrate()
const
00188
{
00189
int bitrate;
00190 speex_encoder_ctl(const_cast<void*>(spxstate),
00191 SPEEX_GET_BITRATE, &bitrate);
00192
return bitrate;
00193 }
00194
00195
00196
00197
00198
00199 WvSpeexDecoder::WvSpeexDecoder(
int samplingrate,
unsigned int channels,
00200 WvSpeex::CodecMode modeid) :
00201 _samplingrate(samplingrate), _channels(channels),
00202 spxstate(NULL), spxbits(NULL), spxmode(NULL),
00203 _samplesperframe(0)
00204 {
00205
00206 spxmode =
get_speex_mode(modeid, samplingrate);
00207 spxstate = speex_decoder_init(spxmode);
00208
if (! spxstate)
00209 {
00210 seterror(
"error during speex_decoder_init");
00211
return;
00212 }
00213 spxbits =
new SpeexBits;
00214 speex_bits_init(spxbits);
00215
00216
00217 speex_decoder_ctl(spxstate, SPEEX_SET_SAMPLING_RATE,
00218 & samplingrate);
00219
00220
00221 speex_decoder_ctl(spxstate, SPEEX_GET_FRAME_SIZE,
00222 &_samplesperframe);
00223 }
00224
00225
00226 WvSpeexDecoder::~WvSpeexDecoder()
00227 {
00228 speex_decoder_destroy(spxstate);
00229 speex_bits_destroy(spxbits);
00230
delete spxbits;
00231 }
00232
00233
00234 WvSpeex::CodecMode
WvSpeexDecoder::mode()
const
00235
{
00236
return WvSpeex::CodecMode(spxmode->modeID);
00237 }
00238
00239
00240 bool WvSpeexDecoder::postfilter()
const
00241
{
00242
int enabled;
00243 speex_decoder_ctl(spxstate, SPEEX_GET_ENH, &enabled);
00244
return enabled;
00245 }
00246
00247
00248 void WvSpeexDecoder::setpostfilter(
bool enable)
00249 {
00250
int enabled = enable ? 1 : 0;
00251 speex_decoder_ctl(spxstate, SPEEX_SET_ENH, &enabled);
00252 }
00253
00254
00255 bool WvSpeexDecoder::_typedencode(IBuffer &inbuf, OBuffer &outbuf,
00256
bool flush)
00257 {
00258
for (;;)
00259 {
00260 size_t avail = inbuf.used();
00261
if (avail == 0)
00262
return true;
00263
if (outbuf.free() < size_t(_samplesperframe))
00264
return false;
00265
00266 size_t skip = 0;
00267
if (avail > MAX_BYTES_PER_FRAME)
00268 {
00269
00270 skip = avail - MAX_BYTES_PER_FRAME;
00271 avail -= skip;
00272 }
00273 speex_bits_read_from(spxbits, const_cast<char*>(
00274 reinterpret_cast<const char*>(inbuf.get(avail))), avail);
00275
float *outsamples = outbuf.alloc(_samplesperframe);
00276
int retval = speex_decode(spxstate, spxbits, outsamples);
00277 inbuf.skip(skip);
00278
if (retval != 0)
00279
return false;
00280
if (! flush)
00281
return true;
00282 }
00283 }
00284
00285
00286 bool WvSpeexDecoder::_typedfinish(OBuffer &outbuf)
00287 {
00288
return true;
00289 }
00290
00291
00292 bool WvSpeexDecoder::missing(OBuffer &outbuf)
00293 {
00294
if (!
isok() ||
isfinished())
00295
return false;
00296
if (outbuf.free() < size_t(_samplesperframe))
00297
return false;
00298 speex_decode(spxstate, NULL, outbuf.alloc(_samplesperframe));
00299
return true;
00300 }