Checkin of validated codec used during development
[opal.git] / plugins / audio / Speex / speexcodec.cxx
blob07f0306809e544b5f5d03e857452c1ef752b846a
1 /*
2 * Speex Plugin codec for OpenH323/OPAL
4 * Copyright (C) 2004 Post Increment, All Rights Reserved
6 * The contents of this file are subject to the Mozilla Public License
7 * Version 1.0 (the "License"); you may not use this file except in
8 * compliance with the License. You may obtain a copy of the License at
9 * http://www.mozilla.org/MPL/
11 * Software distributed under the License is distributed on an "AS IS"
12 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
13 * the License for the specific language governing rights and limitations
14 * under the License.
16 * The Original Code is Open H323 Library.
18 * The Initial Developer of the Original Code is Post Increment
20 * Contributor(s): ______________________________________.
22 * $Log$
23 * Revision 1.2 2006/07/31 09:09:17 csoutheren
24 * Checkin of validated codec used during development
26 * Revision 1.1.2.2 2006/04/08 06:09:09 rjongbloed
27 * Fix correct directory for OPAL headers
29 * Revision 1.1.2.1 2006/04/06 01:20:05 csoutheren
30 * Ported audio codec plugins from OpenH323 to OPAL
32 * Revision 1.18 2005/08/15 01:57:13 csoutheren
33 * Removed error/warning on 64 bit platforms
35 * Revision 1.17 2005/07/15 10:09:00 rogerhardiman
36 * Fix SF bug 1237507. Windows uses malloc.h. Linux and FreeBSD uses stdlib.h
37 * Wrap #include with _WIN32 to be consistent with malloc.h in pwlib.
39 * Revision 1.16 2004/12/20 23:37:43 csoutheren
40 * Added packet loss concealment as per Jean-Marc Valin suggestions
42 * Revision 1.15 2004/12/20 23:18:01 csoutheren
43 * Added stdlib.h to all plugins to keep FreeBSD happy
44 * Thanks to Kevin Oberman
46 * Revision 1.14 2004/12/06 13:57:16 csoutheren
47 * Fixed cut and paste error with wideband speex codec
49 * Revision 1.13 2004/11/29 06:29:02 csoutheren
50 * Added support for wideband codec modes
52 * Revision 1.12 2004/06/16 05:32:52 csoutheren
53 * Removed non-working codecs
55 * Revision 1.11 2004/06/16 04:35:50 csoutheren
56 * Cleanup and add extra tables
58 * Revision 1.10 2004/06/16 04:21:05 csoutheren
59 * Added rest of supported Speex codecs
61 * Revision 1.9 2004/06/16 03:57:58 csoutheren
62 * Fixed strings
64 * Revision 1.8 2004/06/16 03:33:03 csoutheren
65 * Initial support for ACM Speex
67 * Revision 1.7 2004/05/13 10:35:09 csoutheren
68 * Fixed bit rates and bytes per frame for each codec
70 * Revision 1.6 2004/05/12 12:32:44 csoutheren
71 * More name fixes
73 * Revision 1.5 2004/05/12 11:27:04 csoutheren
74 * Changed codec name to match embedded codec
76 * Revision 1.4 2004/04/09 12:24:18 csoutheren
77 * Renamed h323plugin.h to opalplugin.h, and modified everything else
78 * as required
80 * Revision 1.3 2004/04/04 12:57:49 csoutheren
81 * Updated Makefiles and fixed Linux problems
83 * Revision 1.2 2004/04/04 12:44:18 csoutheren
84 * Added file headers
88 #include <codec/opalplugin.h>
90 extern "C" {
91 PLUGIN_CODEC_IMPLEMENT("Speex")
94 #include <stdlib.h>
95 #ifdef _WIN32
96 #include <malloc.h>
97 #endif
98 #include <string.h>
100 #include "libspeex/speex.h"
102 #define NARROW_SAMPLES_PER_FRAME 160
103 #define WIDE_SAMPLES_PER_FRAME 320
105 #define NARROW_NS_PER_FRAME 20000
106 #define WIDE_NS_PER_FRAME 20000
108 const float MaxSampleValue = 32767.0;
109 const float MinSampleValue = -32767.0;
111 struct PluginSpeexContext {
112 struct SpeexBits * bits;
113 void * coderState;
114 unsigned encoderFrameSize;
117 /////////////////////////////////////////////////////////////////////////////
119 static void * create_encoder(const struct PluginCodec_Definition * codec)
121 int mode = (int)(long)(codec->userData);
123 struct PluginSpeexContext * context = new PluginSpeexContext;
124 context->bits = new SpeexBits;
125 speex_bits_init(context->bits);
127 if (codec->sampleRate == 16000)
128 context->coderState = speex_encoder_init(&speex_wb_mode);
129 else
130 context->coderState = speex_encoder_init(&speex_nb_mode);
132 speex_encoder_ctl(context->coderState, SPEEX_GET_FRAME_SIZE, &context->encoderFrameSize);
133 speex_encoder_ctl(context->coderState, SPEEX_SET_QUALITY, &mode);
135 return context;
138 static int codec_encoder(const struct PluginCodec_Definition * codec,
139 void * _context,
140 const void * from,
141 unsigned * fromLen,
142 void * to,
143 unsigned * toLen,
144 unsigned int * flag)
146 PluginSpeexContext * context = (PluginSpeexContext *)_context;
148 if (*fromLen != codec->samplesPerFrame*2)
149 return 0;
151 short * sampleBuffer = (short *)from;
153 // convert PCM to float
154 float floatData[WIDE_SAMPLES_PER_FRAME];
155 int i;
156 for (i = 0; i < codec->samplesPerFrame; i++)
157 floatData[i] = sampleBuffer[i];
159 // encode PCM data in sampleBuffer to buffer
160 speex_bits_reset(context->bits);
161 speex_encode(context->coderState, floatData, context->bits);
163 *toLen = speex_bits_write(context->bits, (char *)to, context->encoderFrameSize);
165 return 1;
168 static void destroy_encoder(const struct PluginCodec_Definition * codec, void * _context)
170 PluginSpeexContext * context = (PluginSpeexContext *)_context;
172 speex_bits_destroy(context->bits);
173 free(context->bits);
175 speex_encoder_destroy(context->coderState);
176 free(context);
179 static void * create_decoder(const struct PluginCodec_Definition * codec)
181 int tmp = 1;
183 PluginSpeexContext * context = new PluginSpeexContext;
184 context->bits = new SpeexBits;
185 speex_bits_init(context->bits);
187 if (codec->sampleRate == 16000)
188 context->coderState = speex_decoder_init(&speex_wb_mode);
189 else
190 context->coderState = speex_decoder_init(&speex_nb_mode);
192 speex_decoder_ctl(context->coderState, SPEEX_SET_ENH, &tmp);
194 return context;
197 static int codec_decoder(const struct PluginCodec_Definition * codec,
198 void * _context,
199 const void * from,
200 unsigned * fromLen,
201 void * to,
202 unsigned * toLen,
203 unsigned int * flag)
205 struct PluginSpeexContext * context = (struct PluginSpeexContext *)_context;
207 float floatData[WIDE_SAMPLES_PER_FRAME];
208 short * sampleBuffer = (short *)to;
210 // if this is a packet loss concealment frame, generate interpolated data
211 // else decode the real data
212 if (*flag & PluginCodec_CoderSilenceFrame)
213 speex_decode(context->coderState, NULL, floatData);
214 else {
215 speex_bits_read_from(context->bits, (char *)from, *fromLen);
216 speex_decode(context->coderState, context->bits, floatData);
219 // convert float to PCM
220 int i;
221 for (i = 0; i < codec->samplesPerFrame; i++) {
222 float sample = floatData[i];
223 if (sample < MinSampleValue)
224 sample = MinSampleValue;
225 else if (sample > MaxSampleValue)
226 sample = MaxSampleValue;
227 sampleBuffer[i] = (short)sample;
231 return 1;
234 static void destroy_decoder(const struct PluginCodec_Definition * codec, void * _context)
236 struct PluginSpeexContext * context = (struct PluginSpeexContext *)_context;
238 speex_bits_destroy(context->bits);
239 free(context->bits);
241 speex_decoder_destroy(context->coderState);
242 free(context);
245 /////////////////////////////////////////////////////////////////////////////
247 static struct PluginCodec_information licenseInfo = {
248 //1081075346, // Sun 04 Apr 2004 10:42:26 AM UTC
249 //1087351735, // Wed 16 Jun 2004 02:08:55 AM UTC
250 1101695533, // Mon 29 Nov 2004 12:32:13 PM EST
252 "Craig Southeren, Post Increment", // source code author
253 "3.1", // source code version
254 "craigs@postincrement.com", // source code email
255 "http://www.postincrement.com", // source code URL
256 "Copyright (C) 2004 by Post Increment, All Rights Reserved", // source code copyright
257 "MPL 1.0", // source code license
258 PluginCodec_License_MPL, // source code license
260 "Speex", // codec description
261 "Jean-Marc Valin, Xiph Foundation.", // codec author
262 "1.0.3", // codec version
263 "jean-marc.valin@hermes.usherb.ca", // codec email
264 "http://www.speex.org", // codec URL
265 "(C) 2003 Xiph.Org Foundation, All Rights Reserved", // codec copyright information
266 "Xiph BSD license", // codec license
267 PluginCodec_License_BSD // codec license code
270 static const char L16Desc[] = { "L16" };
272 static const char sdpSpeex[] = { "speex" };
274 #define EQUIVALENCE_COUNTRY_CODE 9
275 #define EQUIVALENCE_EXTENSION_CODE 0
276 #define EQUIVALENCE_MANUFACTURER_CODE 61
278 #define MICROSOFT_COUNTRY_CODE 181
279 #define MICROSOFT_T35EXTENSION 0
280 #define MICROSOFT_MANUFACTURER 21324
282 #define XIPH_COUNTRY_CODE 0xB5
283 #define XIPH_EXTENSION_CODE 0x00
284 #define XIPH_MANUFACTURER_CODE 0x0026
286 static const unsigned char speexWNarrow8kHdr[] =
288 0x02, 0x00, 0x00, 0x00,
289 0x00, 0x00, 0xa0, 0x00,
290 0x00, 0x00, 0xa0, 0x00,
291 0x04, 0x00, 0x10, 0x00,
293 0x00, 0x00, 0x00, 0x00,
295 // WAVEFORMATEX
296 0x09, 0xa1, // WORD wFormatTag; format type
297 0x01, 0x00, // WORD nChannels; number of channels (i.e. mono, stereo...)
298 0x40, 0x1f, 0x00, 0x00, // DWORD nSamplesPerSec; sample rate
299 0xe8, 0x03, 0x00, 0x00, // DWORD nAvgBytesPerSec; for buffer estimation
301 0x14, 0x00, // WORD nBlockAlign; block size of data
302 0x10, 0x00, // WORD wBitsPerSample; Number of bits per sample of mono data
303 0x0e, 0x00, // WORD cbSize; The count in bytes of the size of extra information
305 // Speex additional information
306 0x00, 0x01, // SPEEXWAVEFORMAT_VERSION
307 0x01, 0x00, // nFramesPerBlock
308 0x03, 0x00, // nQuality
309 0x00, 0x00, // nMode
310 0xf4, 0x01, // nVbrQuality
312 0x03, 0x00, // nComplexity
313 0x00, 0x00, // nFlags
315 // unknown
316 0x00, 0x00
319 ////////////////////////////////////////////////////////////////////////////////////////////////
321 #define CREATE_IETFSPEEX_CAP_DATA(desc, suffix, ordinal, rate) \
322 static const char ietfSpeex##suffix[] = "SpeexIETF" #desc; \
323 static const char ietfSpeex##suffix##Str[] = "speex sr=" #rate ";mode=" #ordinal ";vbr=off;cng=off"; \
324 static struct PluginCodec_H323NonStandardCodecData ietfSpeex##suffix##Cap = \
326 NULL, \
327 XIPH_COUNTRY_CODE, XIPH_EXTENSION_CODE, XIPH_MANUFACTURER_CODE, \
328 (const unsigned char *)ietfSpeex##suffix##Str, sizeof(ietfSpeex##suffix##Str)-1, \
329 NULL \
330 }; \
332 ////////////////////////////////////////////////////////////////////////////////////////////////
334 #define CREATE_NARROW_SPEEX_CAP_DATA(desc, suffix, ordinal) \
335 static const char speex##suffix[] = "Speex" #desc; \
336 static const char speex##suffix##Str[] = "Speex bs4 Narrow" #ordinal; \
337 static struct PluginCodec_H323NonStandardCodecData speex##suffix##Cap = \
339 NULL, \
340 EQUIVALENCE_COUNTRY_CODE, EQUIVALENCE_EXTENSION_CODE, EQUIVALENCE_MANUFACTURER_CODE, \
341 (const unsigned char *)speex##suffix##Str, sizeof(speex##suffix##Str)-1, \
342 NULL \
343 }; \
344 CREATE_IETFSPEEX_CAP_DATA(desc, suffix, ordinal, 8000) \
347 #define DECLARE_NARROW_SPEEX_CODEC(prefix, suffix, ordinal, bitsPerFrame) \
348 /* Original OpenH323 capability */ \
350 /* encoder */ \
351 PLUGIN_CODEC_VERSION, /* codec API version */ \
352 &licenseInfo, /* license information */ \
353 PluginCodec_MediaTypeAudio | /* audio codec */ \
354 PluginCodec_InputTypeRaw | /* raw input data */ \
355 PluginCodec_OutputTypeRaw | /* raw output data */ \
356 PluginCodec_RTPTypeShared | /* share RTP code */ \
357 PluginCodec_RTPTypeDynamic | /* dynamic RTP type */ \
358 PluginCodec_DecodeSilence, /* can encode silence frames */ \
359 prefix##suffix, /* text decription */ \
360 L16Desc, /* source format */ \
361 prefix##suffix, /* destination format */ \
362 (void *)ordinal, /* user data */ \
363 8000, /* samples per second */ \
364 bitsPerFrame*50, /* raw bits per second */ \
365 NARROW_NS_PER_FRAME, /* nanoseconds per frame */ \
366 NARROW_SAMPLES_PER_FRAME, /* samples per frame */ \
367 (bitsPerFrame + 7) / 8, /* bytes per frame */ \
368 1, /* recommended number of frames per packet */ \
369 1, /* maximum number of frames per packet */ \
370 0, /* IANA RTP payload code */ \
371 sdpSpeex, /* RTP payload name */ \
372 create_encoder, /* create codec function */ \
373 destroy_encoder, /* destroy codec */ \
374 codec_encoder, /* encode/decode */ \
375 NULL, /* codec controls */ \
376 PluginCodec_H323Codec_nonStandard, /* h323CapabilityType */ \
377 &prefix##suffix##Cap /* h323CapabilityData */ \
378 }, \
380 /* decoder */ \
381 PLUGIN_CODEC_VERSION, /* codec API version */ \
382 &licenseInfo, /* license information */ \
383 PluginCodec_MediaTypeAudio | /* audio codec */ \
384 PluginCodec_InputTypeRaw | /* raw input data */ \
385 PluginCodec_OutputTypeRaw | /* raw output data */ \
386 PluginCodec_RTPTypeShared | /* share RTP code */ \
387 PluginCodec_RTPTypeDynamic | /* dynamic RTP type */ \
388 PluginCodec_DecodeSilence, /* can encode silence frames */ \
389 prefix##suffix, /* text decription */ \
390 prefix##suffix, /* source format */ \
391 L16Desc, /* destination format */ \
392 (void *)ordinal, /* user data */ \
393 8000, /* samples per second */ \
394 bitsPerFrame*50, /* raw bits per second */ \
395 NARROW_NS_PER_FRAME, /* nanoseconds per frame */ \
396 NARROW_SAMPLES_PER_FRAME, /* samples per frame */ \
397 (bitsPerFrame+7)/8, /* bytes per frame */ \
398 1, /* recommended number of frames per packet */ \
399 1, /* maximum number of frames per packet */ \
400 0, /* IANA RTP payload code */ \
401 sdpSpeex, /* RTP payload name */ \
402 create_decoder, /* create codec function */ \
403 destroy_decoder, /* destroy codec */ \
404 codec_decoder, /* encode/decode */ \
405 NULL, /* codec controls */ \
406 PluginCodec_H323Codec_nonStandard, /* h323CapabilityType */ \
407 &prefix##suffix##Cap /* h323CapabilityData */ \
410 CREATE_NARROW_SPEEX_CAP_DATA(Narrow-5.95k, Narrow5k95, 2)
411 CREATE_NARROW_SPEEX_CAP_DATA(Narrow-8k, Narrow8k, 3)
412 CREATE_NARROW_SPEEX_CAP_DATA(Narrow-11k, Narrow11k, 4)
413 CREATE_NARROW_SPEEX_CAP_DATA(Narrow-15k, Narrow15k, 5)
414 CREATE_NARROW_SPEEX_CAP_DATA(Narrow-18.2k, Narrow18k2, 6)
415 CREATE_NARROW_SPEEX_CAP_DATA(Narrow-24.6k, Narrow24k6, 7)
417 ////////////////////////////////////////////////////////////////////////////////////////////////
419 #define CREATE_WIDE_SPEEX_CAP_DATA(desc, suffix, ordinal) \
420 static const char speex##suffix[] = "Speex" #desc; \
421 static const char speex##suffix##Str[] = "Speex bs4 Wide" #ordinal; \
422 static struct PluginCodec_H323NonStandardCodecData speex##suffix##Cap = \
424 NULL, \
425 EQUIVALENCE_COUNTRY_CODE, EQUIVALENCE_EXTENSION_CODE, EQUIVALENCE_MANUFACTURER_CODE, \
426 (const unsigned char *)speex##suffix##Str, sizeof(speex##suffix##Str)-1, \
427 NULL \
428 }; \
429 CREATE_IETFSPEEX_CAP_DATA(desc, suffix, ordinal, 16000)
431 #define DECLARE_WIDE_SPEEX_CODEC(prefix, suffix, ordinal, bitsPerFrame) \
432 /* Original OpenH323 capability */ \
434 /* encoder */ \
435 PLUGIN_CODEC_VERSION, /* codec API version */ \
436 &licenseInfo, /* license information */ \
437 PluginCodec_MediaTypeAudio | /* audio codec */ \
438 PluginCodec_InputTypeRaw | /* raw input data */ \
439 PluginCodec_OutputTypeRaw | /* raw output data */ \
440 PluginCodec_RTPTypeShared | /* share RTP code */ \
441 PluginCodec_RTPTypeDynamic | /* dynamic RTP type */ \
442 PluginCodec_DecodeSilence, /* can encode silence frames */ \
443 prefix##suffix, /* text decription */ \
444 L16Desc, /* source format */ \
445 prefix##suffix, /* destination format */ \
446 (void *)ordinal, /* user data */ \
447 16000, /* samples per second */ \
448 bitsPerFrame*50, /* raw bits per second */ \
449 WIDE_NS_PER_FRAME, /* nanoseconds per frame */ \
450 WIDE_SAMPLES_PER_FRAME, /* samples per frame */ \
451 (bitsPerFrame+7)/8, /* bytes per frame */ \
452 1, /* recommended number of frames per packet */ \
453 1, /* maximum number of frames per packet */ \
454 0, /* IANA RTP payload code */ \
455 sdpSpeex, /* RTP payload name */ \
456 create_encoder, /* create codec function */ \
457 destroy_encoder, /* destroy codec */ \
458 codec_encoder, /* encode/decode */ \
459 NULL, /* codec controls */ \
460 PluginCodec_H323Codec_nonStandard, /* h323CapabilityType */ \
461 &prefix##suffix##Cap /* h323CapabilityData */ \
462 }, \
464 /* decoder */ \
465 PLUGIN_CODEC_VERSION, /* codec API version */ \
466 &licenseInfo, /* license information */ \
467 PluginCodec_MediaTypeAudio | /* audio codec */ \
468 PluginCodec_InputTypeRaw | /* raw input data */ \
469 PluginCodec_OutputTypeRaw | /* raw output data */ \
470 PluginCodec_RTPTypeShared | /* share RTP code */ \
471 PluginCodec_RTPTypeDynamic | /* dynamic RTP type */ \
472 PluginCodec_DecodeSilence, /* can encode silence frames */ \
473 prefix##suffix, /* text decription */ \
474 prefix##suffix, /* source format */ \
475 L16Desc, /* destination format */ \
476 (void *)ordinal, /* user data */ \
477 16000, /* samples per second */ \
478 bitsPerFrame*50, /* raw bits per second */ \
479 WIDE_NS_PER_FRAME, /* nanoseconds per frame */ \
480 WIDE_SAMPLES_PER_FRAME, /* samples per frame */ \
481 (bitsPerFrame+7)/8, /* bytes per frame */ \
482 1, /* recommended number of frames per packet */ \
483 1, /* maximum number of frames per packet */ \
484 0, /* IANA RTP payload code */ \
485 sdpSpeex, /* RTP payload name */ \
486 create_decoder, /* create codec function */ \
487 destroy_decoder, /* destroy codec */ \
488 codec_decoder, /* encode/decode */ \
489 NULL, /* codec controls */ \
490 PluginCodec_H323Codec_nonStandard, /* h323CapabilityType */ \
491 &prefix##suffix##Cap /* h323CapabilityData */ \
494 CREATE_WIDE_SPEEX_CAP_DATA(Wide-11.55k, Wide11k5, 2)
495 CREATE_WIDE_SPEEX_CAP_DATA(Wide-17.6k, Wide17k6, 3)
496 CREATE_WIDE_SPEEX_CAP_DATA(Wide-28.6k, Wide28k6, 4)
498 ////////////////////////////////////////////////////////////////////////////////////////////////
500 #define CREATE_NARROW_SPEEXW_CAP_DATA(desc, suffix, ordinal) \
501 static const char speexW##suffix[] = "SpeexW" #desc; \
502 static struct PluginCodec_H323NonStandardCodecData speexW##suffix##Cap = \
504 NULL, \
505 MICROSOFT_COUNTRY_CODE, MICROSOFT_T35EXTENSION, MICROSOFT_MANUFACTURER, \
506 speexW##suffix##Hdr, sizeof(speexW##suffix##Hdr), \
507 NULL \
508 }; \
510 #define DECLARE_NARROW_SPEEXW_CODEC(suffix, ordinal, bitsPerFrame) \
511 /* SpeexW OpenH323 capability */ \
513 /* encoder */ \
514 PLUGIN_CODEC_VERSION, /* codec API version */ \
515 &licenseInfo, /* license information */ \
516 PluginCodec_MediaTypeAudio | /* audio codec */ \
517 PluginCodec_InputTypeRaw | /* raw input data */ \
518 PluginCodec_OutputTypeRaw | /* raw output data */ \
519 PluginCodec_RTPTypeShared | /* share RTP code */ \
520 PluginCodec_RTPTypeDynamic | /* dynamic RTP type */ \
521 PluginCodec_DecodeSilence, /* can encode silence frames */ \
522 speexW##suffix, /* text decription */ \
523 L16Desc, /* source format */ \
524 speexW##suffix, /* destination format */ \
525 (void *)ordinal, /* user data */ \
526 8000, /* samples per second */ \
527 bitsPerFrame*50, /* raw bits per second */ \
528 NARROW_NS_PER_FRAME, /* nanoseconds per frame */ \
529 NARROW_SAMPLES_PER_FRAME, /* samples per frame */ \
530 (bitsPerFrame+7)/8, /* bytes per frame */ \
531 1, /* recommended number of frames per packet */ \
532 1, /* maximum number of frames per packet */ \
533 0, /* IANA RTP payload code */ \
534 NULL, /* RTP payload name */ \
535 create_encoder, /* create codec function */ \
536 destroy_encoder, /* destroy codec */ \
537 codec_encoder, /* encode/decode */ \
538 NULL, /* codec controls */ \
539 PluginCodec_H323Codec_nonStandard, /* h323CapabilityType */ \
540 &speexW##suffix##Cap /* h323CapabilityData */ \
541 }, \
543 /* decoder */ \
544 PLUGIN_CODEC_VERSION, /* codec API version */ \
545 &licenseInfo, /* license information */ \
546 PluginCodec_MediaTypeAudio | /* audio codec */ \
547 PluginCodec_InputTypeRaw | /* raw input data */ \
548 PluginCodec_OutputTypeRaw | /* raw output data */ \
549 PluginCodec_RTPTypeShared | /* share RTP code */ \
550 PluginCodec_RTPTypeDynamic, /* dynamic RTP type */ \
551 speexW##suffix, /* text decription */ \
552 speexW##suffix, /* source format */ \
553 L16Desc, /* destination format */ \
554 (void *)ordinal, /* user data */ \
555 8000, /* samples per second */ \
556 bitsPerFrame*50, /* raw bits per second */ \
557 NARROW_NS_PER_FRAME, /* nanoseconds per frame */ \
558 NARROW_SAMPLES_PER_FRAME, /* samples per frame */ \
559 (bitsPerFrame+7)/8, /* bytes per frame */ \
560 1, /* recommended number of frames per packet */ \
561 1, /* maximum number of frames per packet */ \
562 0, /* IANA RTP payload code */ \
563 NULL, /* RTP payload name */ \
564 create_decoder, /* create codec function */ \
565 destroy_decoder, /* destroy codec */ \
566 codec_decoder, /* encode/decode */ \
567 NULL, /* codec controls */ \
568 PluginCodec_H323Codec_nonStandard, /* h323CapabilityType */ \
569 &speexW##suffix##Cap /* h323CapabilityData */ \
572 CREATE_NARROW_SPEEXW_CAP_DATA(Narrow-8k, Narrow8k, 3)
574 ////////////////////////////////////////////////////////////////////////////////////////////////
576 #define NARROW_BITSPERFRAME_MODE2 119 // 5950
577 #define NARROW_BITSPERFRAME_MODE3 160 // 8000
578 #define NARROW_BITSPERFRAME_MODE4 220 // 11000
579 #define NARROW_BITSPERFRAME_MODE5 300 // 15000
580 #define NARROW_BITSPERFRAME_MODE6 364 // 18200
581 #define NARROW_BITSPERFRAME_MODE7 492 // 26400
583 #define WIDE_BITSPERFRAME_MODE2 (NARROW_BITSPERFRAME_MODE2 + 112) // 11550
584 #define WIDE_BITSPERFRAME_MODE3 (NARROW_BITSPERFRAME_MODE3 + 192) // 17600
585 #define WIDE_BITSPERFRAME_MODE4 (NARROW_BITSPERFRAME_MODE4 + 352) // 28600
587 static struct PluginCodec_Definition ver1SpeexCodecDefn[] = {
588 DECLARE_NARROW_SPEEX_CODEC(speex, Narrow5k95, 2, NARROW_BITSPERFRAME_MODE2),
589 DECLARE_NARROW_SPEEX_CODEC(speex, Narrow8k, 3, NARROW_BITSPERFRAME_MODE3),
590 DECLARE_NARROW_SPEEX_CODEC(speex, Narrow11k, 4, NARROW_BITSPERFRAME_MODE4),
591 DECLARE_NARROW_SPEEX_CODEC(speex, Narrow15k, 5, NARROW_BITSPERFRAME_MODE5),
592 DECLARE_NARROW_SPEEX_CODEC(speex, Narrow18k2, 6, NARROW_BITSPERFRAME_MODE6),
593 DECLARE_NARROW_SPEEX_CODEC(speex, Narrow24k6, 7, NARROW_BITSPERFRAME_MODE7),
595 DECLARE_NARROW_SPEEX_CODEC(ietfSpeex, Narrow5k95, 2, NARROW_BITSPERFRAME_MODE2),
596 DECLARE_NARROW_SPEEX_CODEC(ietfSpeex, Narrow8k, 3, NARROW_BITSPERFRAME_MODE3),
597 DECLARE_NARROW_SPEEX_CODEC(ietfSpeex, Narrow11k, 4, NARROW_BITSPERFRAME_MODE4),
598 DECLARE_NARROW_SPEEX_CODEC(ietfSpeex, Narrow15k, 5, NARROW_BITSPERFRAME_MODE5),
599 DECLARE_NARROW_SPEEX_CODEC(ietfSpeex, Narrow18k2, 6, NARROW_BITSPERFRAME_MODE6),
600 DECLARE_NARROW_SPEEX_CODEC(ietfSpeex, Narrow24k6, 7, NARROW_BITSPERFRAME_MODE7),
602 //DECLARE_SPEEXW_CODEC(Narrow5k95, 2), // does not work
603 DECLARE_NARROW_SPEEXW_CODEC(Narrow8k, 3, NARROW_BITSPERFRAME_MODE3),
604 //DECLARE_SPEEX_CODEC(Narrow11k, 4), // does not work
605 //DECLARE_SPEEX_CODEC(Narrow15k, 5), // does not work
606 //DECLARE_SPEEX_CODEC(Narrow18k2, 6), // does not work
607 //DECLARE_SPEEX_CODEC(Narrow24k6, 7) // does not work
610 #define NUM_VER1_DEFNS (sizeof(ver1SpeexCodecDefn) / sizeof(struct PluginCodec_Definition))
612 static struct PluginCodec_Definition ver2SpeexCodecDefn[] = {
613 DECLARE_NARROW_SPEEX_CODEC(speex, Narrow5k95, 2, NARROW_BITSPERFRAME_MODE2),
614 DECLARE_NARROW_SPEEX_CODEC(speex, Narrow8k, 3, NARROW_BITSPERFRAME_MODE3),
615 DECLARE_NARROW_SPEEX_CODEC(speex, Narrow11k, 4, NARROW_BITSPERFRAME_MODE4),
616 DECLARE_NARROW_SPEEX_CODEC(speex, Narrow15k, 5, NARROW_BITSPERFRAME_MODE5),
617 DECLARE_NARROW_SPEEX_CODEC(speex, Narrow18k2, 6, NARROW_BITSPERFRAME_MODE6),
618 DECLARE_NARROW_SPEEX_CODEC(speex, Narrow24k6, 7, NARROW_BITSPERFRAME_MODE7),
620 DECLARE_NARROW_SPEEX_CODEC(ietfSpeex, Narrow5k95, 2, NARROW_BITSPERFRAME_MODE2),
621 DECLARE_NARROW_SPEEX_CODEC(ietfSpeex, Narrow8k, 3, NARROW_BITSPERFRAME_MODE3),
622 DECLARE_NARROW_SPEEX_CODEC(ietfSpeex, Narrow11k, 4, NARROW_BITSPERFRAME_MODE4),
623 DECLARE_NARROW_SPEEX_CODEC(ietfSpeex, Narrow15k, 5, NARROW_BITSPERFRAME_MODE5),
624 DECLARE_NARROW_SPEEX_CODEC(ietfSpeex, Narrow18k2, 6, NARROW_BITSPERFRAME_MODE6),
625 DECLARE_NARROW_SPEEX_CODEC(ietfSpeex, Narrow24k6, 7, NARROW_BITSPERFRAME_MODE7),
627 //DECLARE_SPEEXW_CODEC(Narrow5k95, 2), // does not work
628 DECLARE_NARROW_SPEEXW_CODEC(Narrow8k, 3, NARROW_BITSPERFRAME_MODE3),
629 //DECLARE_SPEEX_CODEC(Narrow11k, 4), // does not work
630 //DECLARE_SPEEX_CODEC(Narrow15k, 5), // does not work
631 //DECLARE_SPEEX_CODEC(Narrow18k2, 6), // does not work
632 //DECLARE_SPEEX_CODEC(Narrow24k6, 7) // does not work
634 DECLARE_WIDE_SPEEX_CODEC(speex, Wide11k5, 2, WIDE_BITSPERFRAME_MODE2),
635 DECLARE_WIDE_SPEEX_CODEC(speex, Wide17k6, 3, WIDE_BITSPERFRAME_MODE3),
636 DECLARE_WIDE_SPEEX_CODEC(speex, Wide28k6, 4, WIDE_BITSPERFRAME_MODE4),
638 DECLARE_WIDE_SPEEX_CODEC(ietfSpeex, Wide11k5, 2, WIDE_BITSPERFRAME_MODE2),
639 DECLARE_WIDE_SPEEX_CODEC(ietfSpeex, Wide17k6, 3, WIDE_BITSPERFRAME_MODE3),
640 DECLARE_WIDE_SPEEX_CODEC(ietfSpeex, Wide28k6, 4, WIDE_BITSPERFRAME_MODE4),
643 #define NUM_VER2_DEFNS (sizeof(ver2SpeexCodecDefn) / sizeof(struct PluginCodec_Definition))
645 /////////////////////////////////////////////////////////////////////////////
647 extern "C" {
649 PLUGIN_CODEC_DLL_API struct PluginCodec_Definition * PLUGIN_CODEC_GET_CODEC_FN(unsigned * count, unsigned version)
651 if (version == 1) {
652 *count = NUM_VER1_DEFNS;
653 return ver1SpeexCodecDefn;
655 else
657 *count = NUM_VER2_DEFNS;
658 return ver2SpeexCodecDefn;