1 /*
2  * Copyright (C) 2002-2003 Fhg Fokus
3  *
4  * This file is part of SEMS, a free SIP media server.
5  *
6  * SEMS is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version. This program is released under
10  * the GPL with the additional exemption that compiling, linking,
11  * and/or using OpenSSL is allowed.
12  *
13  * For a license to use the SEMS software under conditions
14  * other than those described here, or to purchase support for this
15  * software, please contact iptel.org by e-mail at the following addresses:
16  *    info@iptel.org
17  *
18  * SEMS is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software
25  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26  */
27 
28 #ifndef _amci_h_
29 #define _amci_h_
30 
31 /** AUDIO_BUFFER_SIZE must be a power of 2 */
32 #define AUDIO_BUFFER_SIZE (1<<13) /* 4 KB samples */
33 
34 #ifdef __cplusplus
35 extern "C" {
36 #endif
37 
38 #ifdef __linux
39 # ifndef _GNU_SOURCE
40 #  define _GNU_SOURCE
41 # endif
42 #endif
43 #include <stdio.h>
44 
45 /**
46  * @file amci.h
47  * @brief Definition of the codec interface.
48  *
49  * This codec interface makes it possible for third-party
50  * developer to implement and integrate their own codecs and file formats.
51  *
52  * Three entities can be declared within a plug-in:
53  * <ol>
54  * <li>Codecs: transform samples to/from the internal coding scheme
55  *             from/to these described in the plug-in.
56  *
57  * <li>Payloads: special format definition used by the RTP protocol
58  *               and including a codec.
59  *
60  * <li>File formats: collection of subtypes sharing the same header
61  *                   scheme whereby each subtype can use a different codec.
62  * </ol>
63  * @warning
64  *   Please use only the macros at the end of this file
65  *   for export definition. This is a much more portable solution
66  *   than using directly the structures.<br>
67  * \example plug-in/wav/wav.c
68  */
69 
70 /** @def AMCI_RDONLY Read only mode. */
71 #define AMCI_RDONLY   1
72 /** @def AMCI_WRONLY Write only mode. */
73 #define AMCI_WRONLY   2
74 
75   /** @def AMCI_FMT_FRAME_LENGTH  frame length in ms (for framed codecs; must be multiple of 10) see codec_init */
76 #define AMCI_FMT_FRAME_LENGTH       1
77   /** @def AMCI_FMT_FRAME_SIZE frame size in samples */
78 #define AMCI_FMT_FRAME_SIZE         2
79   /** @def AMCI_FMT_ENCODED_FRAME_SIZE encoded frame size in bytes */
80 #define AMCI_FMT_ENCODED_FRAME_SIZE 3
81 
82 struct amci_codec_t;
83 
84 /**
85  * \brief File format declaration
86  */
87 struct amci_file_desc_t {
88 
89     /** subtype from current file format */
90     int     subtype;
91 
92     /** sampling rate */
93     int     rate;
94 
95     /** # channels */
96     int     channels;
97 
98     /** size of the data. -1 for unknown/unlimited */
99     int data_size;
100 
101     /** output buffer size. 0 for no buffering */
102     int buffer_size;
103 
104     /** output buffer refill threshold */
105     int buffer_thresh;
106 
107     /** output buffer refill threshold */
108     int buffer_full_thresh;
109 };
110 
111 /**
112  * \brief Sound converter function pointer.
113  * @param out      [out] output buffer
114  * @param in       [in] input buffer
115  * @param size       [in] size of input buffer
116  * @param channels [in] number of channels
117  * @param rate     [in] sampling rate
118  * @param h_codec  [in] codec handle
119  * @return
120  *     <ul>
121  *     <li>if sucess:  bytes written in output buffer (0 is legal)
122  *     <li>if failure: err < 0
123  *     </ul>
124  * @see amci_codec_t::intern2type
125  * @see amci_codec_t::type2intern
126  */
127 typedef int (*amci_converter_t)( unsigned char* out,
128 				 unsigned char* in,
129 				 unsigned int   size,
130 				 unsigned int   channels,
131 				 unsigned int   rate,
132 				 long           h_codec
133                                );
134 
135 /**
136  * \brief Codec specific packet loss concealment function pointer.
137  * @param out      [out] output buffer
138  * @param size     [in] required size of output
139  * @param channels [in] number of channels
140  * @param rate     [in] sampling rate
141  * @param h_codec  [in] codec handle
142  * @return
143  *     <ul>
144  *     <li>if sucess:  bytes written in output buffer (0 is legal)
145  *     <li>if failure: err < 0
146  *     </ul>
147  * @see amci_codec_t::plc
148  */
149 typedef int (*amci_plc_t)( unsigned char* out,
150 			   unsigned int   size,
151 			   unsigned int   channels,
152 			   unsigned int   rate,
153 			   long           h_codec );
154 
155 /**
156  * \brief File format handler's open function
157  * @param fptr     [in] fresh opened file pointer
158  * @param fmt_desc [out] file description
159  * @param options  [in] options (see amci_inoutfmt_t)
160  * @param h_codec  [in] handle of the codec
161  * @return if failure -1, else 0.
162  * @see amci_inoutfmt_t::open
163  */
164 typedef int (*amci_file_open_t)( FILE* fptr,
165 				    struct amci_file_desc_t* fmt_desc,
166 				    int  options,
167 				    long h_codec
168                                   );
169 
170 /**
171  * File format handler's close function
172  * @param fptr     [in] fresh opened file pointer
173  * @param fmt_desc [out] file description
174  * @param options  [in] options (see amci_inoutfmt_t)
175  * @param h_codec  [in] handle of the codec
176  * @param codec    [in] codec structure
177  * @return if failure -1, else 0.
178  * @see amci_inoutfmt_t::on_close
179  */
180 typedef int (*amci_file_close_t)( FILE* fptr,
181 				    struct amci_file_desc_t* fmt_desc,
182 				    int  options,
183 				    long h_codec,
184 				    struct amci_codec_t *codec
185                                   );
186 
187 /**
188  * File format handler's open function from memory area
189  * @param fptr     [in]  pointer to memory where file is loaded
190  * @param size     [in]  length of file in mem
191  * @param pos      [out] position after open
192  * @param fmt_desc [out] file description
193  * @param options  [in]  options (see amci_inoutfmt_t)
194  * @param h_codec  [in]  handle of the codec
195  * @return if failure -1, else 0.
196  * @see amci_inoutfmt_t::open
197  */
198 typedef int (*amci_file_mem_open_t)(unsigned char* mptr,
199 				    unsigned long size,
200 				    unsigned long* pos,
201 				    struct amci_file_desc_t* fmt_desc,
202 				    int  options,
203 				    long h_codec
204                                   );
205 
206 /**
207  * File format handler's mem close function (usually no-op)
208  * @param fptr     [in]  pointer to memory where file is loaded
209  * @param pos      [in,out]  position in memory
210  * @param fmt_desc [out] file description
211  * @param options  [in]  options (see amci_inoutfmt_t)
212  * @param h_codec  [in]  handle of the codec
213  * @param codec    [in]  codec structure
214  * @return if failure -1, else 0.
215  * @see amci_inoutfmt_t::on_close
216  */
217 typedef int (*amci_file_mem_close_t)( unsigned char* mptr,
218 				    unsigned long* pos,
219 				    struct amci_file_desc_t* fmt_desc,
220 				    int  options,
221 				    long h_codec,
222 				    struct amci_codec_t *codec
223                                   );
224 
225 /**
226  * \brief Codec module 's init function pointer.
227  * this function initializes the codec module.
228  * @return 0 on success, <0 on error
229  */
230 typedef int (*amci_codec_module_load_t)(const char* ModConfigPath);
231 
232 /**
233  * \brief Codec's module's destroy function pointer.
234  */
235 typedef void (*amci_codec_module_destroy_t)(void);
236 
237 
238 /**
239  * \brief Codec's init function pointer.
240  *
241  * @param format_parameters      [in]  parameters as passed by fmtp tag, NULL if none
242  * @param format_parameters_out  [out] parameters passed back to fmtp, NULL if none
243  * @param format_description     [out] pointer to describing block, with amci_codec_fmt_info_t array; zero-terminated.
244         NULL if none
245  *   <table><tr><td><b>key</b></td><td><b>value</b></td></tr>
246  *     <tr><td>AMCI_FMT_FRAME_LENGTH (1)</td><td>  frame length in ms (for framed codecs; must be multiple of 10)</td></tr>
247  *     <tr><td>AMCI_FMT_FRAME_SIZE (2)</td><td>  frame size in samples</td></tr>
248  *     <tr><td>AMCI_FMT_ENCODED_FRAME_SIZE (3)</td><td>  encoded frame size</td></tr></table>
249  * @return -1 if failed, else some handle which will be
250  *         passed by each further call (0 is legal).
251  *
252  */
253 
254   typedef struct {
255     int id;
256     int value;
257   } amci_codec_fmt_info_t;
258 
259   typedef long (*amci_codec_init_t)(const char* format_parameters, const char** format_parameters_out,
260 				    amci_codec_fmt_info_t** fmt_info);
261 
262 /**
263  * \brief Codec's destroy function pointer.
264  * @param h_codec Codec handle (from init function).
265  */
266 typedef void (*amci_codec_destroy_t)(long h_codec);
267 
268 /**
269  * \brief Codec's function for calculating the number of samples from bytes
270  */
271 typedef unsigned int (*amci_codec_bytes2samples_t)(long h_codec, unsigned int num_bytes);
272 
273 /**
274  * \brief Codec's function for calculating the number of bytes from samples
275  */
276 typedef unsigned int (*amci_codec_samples2bytes_t)(long h_codec, unsigned int num_samples);
277 
278 /**
279  * \brief Codec's function for negotiating codec format; this needs to be dry-run, i.e. no codec instantiated
280  */
281 typedef int (*amci_codec_negotiate_fmt_t)(int is_offer, const char* params_in, char* params_out, unsigned int params_out_len);
282 
283 /**
284  * \brief Codec description
285  */
286 struct amci_codec_t {
287 
288     /** internal codec id (the ones from codecs.h) */
289     int id;
290 
291     /**
292      * Converts the input buffer (internal format: Pcm16)
293      * to the format described in this structure.
294      */
295     amci_converter_t encode;
296 
297     /** Does the opposite of encode. */
298     amci_converter_t decode;
299 
300     /** Codec specific packet loss concealment. can be NULL */
301     amci_plc_t plc;
302 
303     /** Init function. can be NULL. */
304     amci_codec_init_t    init;
305     /** Destroy function. can be NULL. */
306     amci_codec_destroy_t destroy;
307 
308     /** Function for calculating the number of bytes from samples. */
309     amci_codec_bytes2samples_t bytes2samples;
310 
311     /** Function for calculating the number of samples from bytes. */
312     amci_codec_samples2bytes_t samples2bytes;
313 
314     /** function for dry-negotiating codec format - no codec instance is created */
315     amci_codec_negotiate_fmt_t negotiate_fmt;
316 };
317 
318   /** \brief supported subtypes for a file */
319 struct amci_subtype_t {
320 
321     /** ex. 0x06 for Wav's Mu-Law */
322     int   type;
323 
324     /** ex. "Mu-Law" */
325     const char* name;
326 
327     /**
328      * This must be initialized.<br>
329      * example: 8000 Hz.
330      */
331     int sample_rate;
332 
333     /**
334      * This must be initialized.<br>
335      * <br>example 1 (mono), 2 (stereo).
336     */
337     int channels;
338 
339     /**
340      * Internal codec id (see codecs.h)
341      */
342     int codec_id;
343 };
344 
345 /**
346  * \brief File format declaration.
347  */
348 struct amci_inoutfmt_t {
349 
350     /** example: "Wav". */
351     char* name;
352 
353     /** example: "wav". */
354     char* ext;
355 
356     /** example: "audio/x-wav". */
357     char* email_content_type;
358 
359     /** options: AMCI_RDONLY, AMCI_WRONLY. */
360     amci_file_open_t open;
361 
362     /** no options at the moment. */
363     amci_file_close_t on_close;
364 
365     /** options: AMCI_RDONLY, AMCI_WRONLY. */
366     amci_file_mem_open_t mem_open;
367 
368     /** no options at the moment. */
369     amci_file_mem_close_t mem_close;
370 
371     /** NULL terminated subtype array. */
372     struct amci_subtype_t*  subtypes;
373 
374 };
375 
376 /** Payload type for continuous audio */
377 #define AMCI_PT_AUDIO_LINEAR 0
378 /** Payload type for frame based audio */
379 #define AMCI_PT_AUDIO_FRAME 1
380 
381 /**
382  * \brief ayload declaration
383  */
384 struct amci_payload_t {
385 
386     /** static payload id (see RFC 1890) */
387     int   payload_id;
388 
389     /** example: "PCMU" (see RFC 1890)*/
390     const char* name;
391 
392     /**
393      * example: 8000 (Hz).
394      * @note For frame based payloads:
395      *    use instead the in/out sampling rate
396      *    needed for the converting functions.
397      */
398     int sample_rate;
399 
400     /**
401      * Sample rate that is advertised in SDP.
402      * example: g722 has advertised_sample_rate 8000, and sample_rate 16000.
403      */
404     int advertised_sample_rate;
405 
406     /**
407      * If this type is not bound to a fixed number of channels,
408      * set this parameter to -1.
409      * <br>example 1 (mono), 2 (stereo).
410     */
411     int channels;
412 
413     /** internal codec id (see codecs.h) */
414     int codec_id;
415 
416     /** @see AMCI_PT_AUDIO_LINEAR, AMCI_PT_AUDIO_FRAME */
417     int type;
418 };
419 
420 
421 /**
422  * \brief Complete plug-in declaration.
423  */
424 struct amci_exports_t {
425 
426     /** Module name */
427     char* name;
428 
429     /** Codec module load function. can be NULL */
430     amci_codec_module_load_t module_load;
431     /** Codec module destroy function. can be NULL */
432     amci_codec_module_destroy_t module_destroy;
433 
434     /** NULL terminated array of amci_codec_t */
435     struct amci_codec_t*    codecs;
436     /** NULL terminated array of amci_payload_t */
437     struct amci_payload_t*  payloads;
438     /** NULL terminated array of amci_inoutfmt_t */
439     struct amci_inoutfmt_t* file_formats;
440 };
441 
442 
443 
444 /**
445  * Portable export definition macro
446  * see example media plug-in 'wav' (plug-in/wav/wav.c).
447  * @hideinitializer
448  */
449 #define BEGIN_EXPORTS(name, module_load, module_destroy)	   \
450             struct amci_exports_t amci_exports = { \
451                 name,\
452                 module_load,\
453 		module_destroy,
454 
455 
456 /**
457  * Portable export definition macro
458  * see example media plug-in 'wav' (plug-in/wav/wav.c).
459  * @hideinitializer
460  */
461 #define END_EXPORTS \
462             };
463 
464 /**
465  * Portable export definition macro
466  * see example media plug-in 'wav' (plug-in/wav/wav.c).
467  * @hideinitializer
468  */
469 #define BEGIN_CODECS \
470                 (struct amci_codec_t[]) {
471 
472 /**
473  * Portable export definition macro
474  * see example media plug-in 'wav' (plug-in/wav/wav.c).
475  * @hideinitializer
476  */
477 #define END_CODECS \
478                     { -1, 0, 0, 0, 0, 0, 0, 0, 0 }			\
479                 },
480 
481 /**
482  * Portable export definition macro
483  * see example media plug-in 'wav' (plug-in/wav/wav.c).
484  * @hideinitializer
485  */
486 #define CODEC(id, intern2type,type2intern,plc,init,destroy,bytes2samples,samples2bytes) \
487        { id, intern2type, type2intern, plc, init, destroy, bytes2samples, samples2bytes, 0 },
488 
489   /**
490      A codec with negotiate_fmt function
491      @hideinitializer
492    */
493 #define CODEC_WITH_FMT(id, intern2type,type2intern,plc,init,destroy,bytes2samples,samples2bytes,negotiate_fmt) \
494        { id, intern2type, type2intern, plc, init, destroy, bytes2samples, samples2bytes, negotiate_fmt},
495 
496 /**
497  * Portable export definition macro
498  * see example media plug-in 'wav' (plug-in/wav/wav.c).
499  * @hideinitializer
500  */
501 #define BEGIN_PAYLOADS \
502                 (struct amci_payload_t[]) {
503 
504 /**
505  * Portable export definition macro
506  * see example media plug-in 'wav' (plug-in/wav/wav.c).
507  * @hideinitializer
508  */
509 #define END_PAYLOADS \
510                     { -1, 0, -1, -1, -1, -1, -1 } \
511                 },
512 
513 /**
514  * Portable export definition macro
515  * see example media plug-in 'wav' (plug-in/wav/wav.c).
516  * @hideinitializer
517  */
518 #define PAYLOAD(id,name,rate,advertised_rate,channels,codec_id,type)	\
519   { id, name, rate, advertised_rate, channels, codec_id, type },
520 
521 /**
522  * Portable export definition macro
523  * see example media plug-in 'wav' (plug-in/wav/wav.c).
524  * @hideinitializer
525  */
526 #define BEGIN_FILE_FORMATS \
527                 (struct amci_inoutfmt_t[]) {
528 
529 /**
530  * Portable export definition macro
531  * see example media plug-in 'wav' (plug-in/wav/wav.c).
532  * @hideinitializer
533  */
534 #define END_FILE_FORMATS \
535                     { 0,0,0,0,0,0,0, \
536                       (struct amci_subtype_t[]) { {-1, 0, -1, -1, -1} } \
537                     } \
538                 }
539 
540 /**
541  * Portable export definition macro
542  * see example media plug-in 'wav' (plug-in/wav/wav.c).
543  * @hideinitializer
544  */
545 #define BEGIN_FILE_FORMAT(name,ext,email_content_type,open,on_close,mem_open,mem_close) \
546                     { name,ext,email_content_type,open,on_close,mem_open,mem_close,
547 
548 /**
549  * Portable export definition macro
550  * see example media plug-in 'wav' (plug-in/wav/wav.c).
551  * @hideinitializer
552  */
553 #define END_FILE_FORMAT \
554                     },
555 
556 /**
557  * Portable export definition macro
558  * see example media plug-in 'wav' (plug-in/wav/wav.c).
559  * @hideinitializer
560  */
561 #define BEGIN_SUBTYPES \
562                         (struct amci_subtype_t[]) {
563 
564 /**
565  * Portable export definition macro
566  * see example media plug-in 'wav' (plug-in/wav/wav.c).
567  * @hideinitializer
568  */
569 #define END_SUBTYPES \
570                             {-1, 0, -1, -1, -1} \
571                         }
572 
573 /**
574  * Portable export definition macro
575  * see example media plug-in 'wav' (plug-in/wav/wav.c).
576  * @hideinitializer
577  */
578 #define SUBTYPE(type,name,rate,channels,codec_id) \
579                         { type, name, rate, channels, codec_id },
580 
581 
582   /* defines to make definitions more expressive */
583 #define AMCI_NO_MODULEINIT    NULL
584 #define AMCI_NO_MODULEDESTROY NULL
585 #define AMCI_NO_CODEC_PLC     NULL
586 #define AMCI_NO_CODECCREATE   NULL
587 #define AMCI_NO_CODECDESTROY  NULL
588 
589 #ifdef __cplusplus
590 }
591 #endif
592 
593 #endif
594 
595 
596 
597 
598 
599 
600 
601