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 }