]> git.sesse.net Git - vlc/blob - modules/codec/araw.c
Improvements to preferences
[vlc] / modules / codec / araw.c
1 /*****************************************************************************
2  * araw.c: Pseudo audio decoder; for raw pcm data
3  *****************************************************************************
4  * Copyright (C) 2001, 2003 VideoLAN
5  * $Id$
6  *
7  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
22  *****************************************************************************/
23
24 /*****************************************************************************
25  * Preamble
26  *****************************************************************************/
27 #include <vlc/vlc.h>
28 #include <vlc/decoder.h>
29
30 /*****************************************************************************
31  * Module descriptor
32  *****************************************************************************/
33 static int  DecoderOpen ( vlc_object_t * );
34 static void DecoderClose( vlc_object_t * );
35
36 static int  EncoderOpen ( vlc_object_t * );
37 static void EncoderClose( vlc_object_t * );
38
39 vlc_module_begin();
40     /* audio decoder module */
41     set_description( _("Raw/Log Audio decoder") );
42     set_capability( "decoder", 100 );
43     set_category( CAT_INPUT );
44     set_subcategory( SUBCAT_INPUT_ACODEC );
45     set_callbacks( DecoderOpen, DecoderClose );
46
47     /* audio encoder submodule */
48     add_submodule();
49     set_description( _("Raw audio encoder") );
50     set_capability( "encoder", 150 );
51     set_callbacks( EncoderOpen, EncoderClose );
52 vlc_module_end();
53
54 /*****************************************************************************
55  * Local prototypes
56  *****************************************************************************/
57 static aout_buffer_t *DecodeBlock( decoder_t *, block_t ** );
58 static block_t *EncoderEncode( encoder_t *, aout_buffer_t * );
59
60 struct decoder_sys_t
61 {
62     int16_t *p_logtos16;  /* used with m/alaw to int16_t */
63
64     audio_date_t end_date;
65 };
66
67 static int pi_channels_maps[] =
68 {
69     0,
70     AOUT_CHAN_CENTER,
71     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
72     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER,
73     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT
74      | AOUT_CHAN_REARRIGHT,
75     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
76      | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT,
77     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
78      | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT | AOUT_CHAN_LFE,
79     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
80      | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT
81      | AOUT_CHAN_MIDDLELEFT | AOUT_CHAN_MIDDLERIGHT,
82     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
83      | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT
84      | AOUT_CHAN_MIDDLELEFT | AOUT_CHAN_MIDDLERIGHT | AOUT_CHAN_LFE
85 };
86
87 static int16_t ulawtos16[256] =
88 {
89     -32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956,
90     -23932, -22908, -21884, -20860, -19836, -18812, -17788, -16764,
91     -15996, -15484, -14972, -14460, -13948, -13436, -12924, -12412,
92     -11900, -11388, -10876, -10364,  -9852,  -9340,  -8828,  -8316,
93      -7932,  -7676,  -7420,  -7164,  -6908,  -6652,  -6396,  -6140,
94      -5884,  -5628,  -5372,  -5116,  -4860,  -4604,  -4348,  -4092,
95      -3900,  -3772,  -3644,  -3516,  -3388,  -3260,  -3132,  -3004,
96      -2876,  -2748,  -2620,  -2492,  -2364,  -2236,  -2108,  -1980,
97      -1884,  -1820,  -1756,  -1692,  -1628,  -1564,  -1500,  -1436,
98      -1372,  -1308,  -1244,  -1180,  -1116,  -1052,   -988,   -924,
99       -876,   -844,   -812,   -780,   -748,   -716,   -684,   -652,
100       -620,   -588,   -556,   -524,   -492,   -460,   -428,   -396,
101       -372,   -356,   -340,   -324,   -308,   -292,   -276,   -260,
102       -244,   -228,   -212,   -196,   -180,   -164,   -148,   -132,
103       -120,   -112,   -104,    -96,    -88,    -80,    -72,    -64,
104        -56,    -48,    -40,    -32,    -24,    -16,     -8,      0,
105      32124,  31100,  30076,  29052,  28028,  27004,  25980,  24956,
106      23932,  22908,  21884,  20860,  19836,  18812,  17788,  16764,
107      15996,  15484,  14972,  14460,  13948,  13436,  12924,  12412,
108      11900,  11388,  10876,  10364,   9852,   9340,   8828,   8316,
109       7932,   7676,   7420,   7164,   6908,   6652,   6396,   6140,
110       5884,   5628,   5372,   5116,   4860,   4604,   4348,   4092,
111       3900,   3772,   3644,   3516,   3388,   3260,   3132,   3004,
112       2876,   2748,   2620,   2492,   2364,   2236,   2108,   1980,
113       1884,   1820,   1756,   1692,   1628,   1564,   1500,   1436,
114       1372,   1308,   1244,   1180,   1116,   1052,    988,    924,
115        876,    844,    812,    780,    748,    716,    684,    652,
116        620,    588,    556,    524,    492,    460,    428,    396,
117        372,    356,    340,    324,    308,    292,    276,    260,
118        244,    228,    212,    196,    180,    164,    148,    132,
119        120,    112,    104,     96,     88,     80,     72,     64,
120         56,     48,     40,     32,     24,     16,      8,      0
121 };
122
123 static int16_t alawtos16[256] =
124 {
125      -5504,  -5248,  -6016,  -5760,  -4480,  -4224,  -4992,  -4736,
126      -7552,  -7296,  -8064,  -7808,  -6528,  -6272,  -7040,  -6784,
127      -2752,  -2624,  -3008,  -2880,  -2240,  -2112,  -2496,  -2368,
128      -3776,  -3648,  -4032,  -3904,  -3264,  -3136,  -3520,  -3392,
129     -22016, -20992, -24064, -23040, -17920, -16896, -19968, -18944,
130     -30208, -29184, -32256, -31232, -26112, -25088, -28160, -27136,
131     -11008, -10496, -12032, -11520,  -8960,  -8448,  -9984,  -9472,
132     -15104, -14592, -16128, -15616, -13056, -12544, -14080, -13568,
133       -344,   -328,   -376,   -360,   -280,   -264,   -312,   -296,
134       -472,   -456,   -504,   -488,   -408,   -392,   -440,   -424,
135        -88,    -72,   -120,   -104,    -24,     -8,    -56,    -40,
136       -216,   -200,   -248,   -232,   -152,   -136,   -184,   -168,
137      -1376,  -1312,  -1504,  -1440,  -1120,  -1056,  -1248,  -1184,
138      -1888,  -1824,  -2016,  -1952,  -1632,  -1568,  -1760,  -1696,
139       -688,   -656,   -752,   -720,   -560,   -528,   -624,   -592,
140       -944,   -912,  -1008,   -976,   -816,   -784,   -880,   -848,
141       5504,   5248,   6016,   5760,   4480,   4224,   4992,   4736,
142       7552,   7296,   8064,   7808,   6528,   6272,   7040,   6784,
143       2752,   2624,   3008,   2880,   2240,   2112,   2496,   2368,
144       3776,   3648,   4032,   3904,   3264,   3136,   3520,   3392,
145      22016,  20992,  24064,  23040,  17920,  16896,  19968,  18944,
146      30208,  29184,  32256,  31232,  26112,  25088,  28160,  27136,
147      11008,  10496,  12032,  11520,   8960,   8448,   9984,   9472,
148      15104,  14592,  16128,  15616,  13056,  12544,  14080,  13568,
149        344,    328,    376,    360,    280,    264,    312,    296,
150        472,    456,    504,    488,    408,    392,    440,    424,
151         88,     72,    120,    104,     24,      8,     56,     40,
152        216,    200,    248,    232,    152,    136,    184,    168,
153       1376,   1312,   1504,   1440,   1120,   1056,   1248,   1184,
154       1888,   1824,   2016,   1952,   1632,   1568,   1760,   1696,
155        688,    656,    752,    720,    560,    528,    624,    592,
156        944,    912,   1008,    976,    816,    784,    880,    848
157 };
158
159 /*****************************************************************************
160  * DecoderOpen: probe the decoder and return score
161  *****************************************************************************/
162 static int DecoderOpen( vlc_object_t *p_this )
163 {
164     decoder_t *p_dec = (decoder_t*)p_this;
165     decoder_sys_t *p_sys;
166
167     switch( p_dec->fmt_in.i_codec )
168     {
169     /* from wav/avi/asf file */
170     case VLC_FOURCC('a','r','a','w'):
171     case VLC_FOURCC('a','f','l','t'):
172     /* _signed_ big endian samples (mov)*/
173     case VLC_FOURCC('t','w','o','s'):
174     /* _signed_ little endian samples (mov)*/
175     case VLC_FOURCC('s','o','w','t'):
176
177     case VLC_FOURCC('a','l','a','w'):
178     case VLC_FOURCC('u','l','a','w'):
179     case VLC_FOURCC('m','l','a','w'):
180
181     case VLC_FOURCC('f','l','6','4'):
182     case VLC_FOURCC('f','l','3','2'):
183     case VLC_FOURCC('s','3','2','l'):
184     case VLC_FOURCC('s','3','2','b'):
185     case VLC_FOURCC('s','2','4','l'):
186     case VLC_FOURCC('s','2','4','b'):
187     case VLC_FOURCC('s','1','6','l'):
188     case VLC_FOURCC('s','1','6','b'):
189     case VLC_FOURCC('s','8',' ',' '):
190     case VLC_FOURCC('u','8',' ',' '):
191         break;
192
193     default:
194         return VLC_EGENERIC;
195     }
196
197     if( p_dec->fmt_in.audio.i_channels <= 0 ||
198         p_dec->fmt_in.audio.i_channels > 8 )
199     {
200         msg_Err( p_dec, "bad channels count (1-8)" );
201         return VLC_EGENERIC;
202     }
203
204     if( p_dec->fmt_in.audio.i_rate <= 0 )
205     {
206         msg_Err( p_dec, "bad samplerate" );
207         return VLC_EGENERIC;
208     }
209
210     /* Allocate the memory needed to store the decoder's structure */
211     if( ( p_dec->p_sys = p_sys =
212           (decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL )
213     {
214         msg_Err( p_dec, "out of memory" );
215         return VLC_EGENERIC;
216     }
217
218     p_sys->p_logtos16 = NULL;
219
220     msg_Dbg( p_dec, "samplerate:%dHz channels:%d bits/sample:%d",
221              p_dec->fmt_in.audio.i_rate, p_dec->fmt_in.audio.i_channels,
222              p_dec->fmt_in.audio.i_bitspersample );
223
224     if( p_dec->fmt_in.i_codec == VLC_FOURCC( 'f', 'l', '6', '4' ) )
225     {
226         p_dec->fmt_out.i_codec = p_dec->fmt_in.i_codec;
227         p_dec->fmt_in.audio.i_bitspersample = 64;
228     }
229     else if( p_dec->fmt_in.i_codec == VLC_FOURCC( 'f', 'l', '3', '2' ) )
230     {
231         p_dec->fmt_out.i_codec = p_dec->fmt_in.i_codec;
232         p_dec->fmt_in.audio.i_bitspersample = 32;
233     }
234     else if( p_dec->fmt_in.i_codec == VLC_FOURCC( 's', '3', '2', 'l' ) ||
235              p_dec->fmt_in.i_codec == VLC_FOURCC( 's', '3', '2', 'b' ) )
236     {
237         p_dec->fmt_out.i_codec = p_dec->fmt_in.i_codec;
238         p_dec->fmt_in.audio.i_bitspersample = 32;
239     }
240     else if( p_dec->fmt_in.i_codec == VLC_FOURCC( 's', '2', '4', 'l' ) ||
241              p_dec->fmt_in.i_codec == VLC_FOURCC( 's', '2', '4', 'b' ) )
242     {
243         p_dec->fmt_out.i_codec = p_dec->fmt_in.i_codec;
244         p_dec->fmt_in.audio.i_bitspersample = 24;
245     }
246     else if( p_dec->fmt_in.i_codec == VLC_FOURCC( 's', '1', '6', 'l' ) ||
247              p_dec->fmt_in.i_codec == VLC_FOURCC( 's', '1', '6', 'b' ) )
248     {
249         p_dec->fmt_out.i_codec = p_dec->fmt_in.i_codec;
250         p_dec->fmt_in.audio.i_bitspersample = 16;
251     }
252     else if( p_dec->fmt_in.i_codec == VLC_FOURCC( 's', '8', ' ', ' ' ) ||
253              p_dec->fmt_in.i_codec == VLC_FOURCC( 'u', '8', ' ', ' ' ) )
254     {
255         p_dec->fmt_out.i_codec = p_dec->fmt_in.i_codec;
256         p_dec->fmt_in.audio.i_bitspersample = 8;
257     }
258     else if( p_dec->fmt_in.i_codec == VLC_FOURCC( 'a', 'f', 'l', 't' ) )
259     {
260         switch( ( p_dec->fmt_in.audio.i_bitspersample + 7 ) / 8 )
261         {
262         case 4:
263             p_dec->fmt_out.i_codec = VLC_FOURCC('f','l','3','2');
264             break;
265         case 8:
266             p_dec->fmt_out.i_codec = VLC_FOURCC('f','l','6','4');
267             break;
268         default:
269             msg_Err( p_dec, "bad parameters(bits/sample)" );
270             return VLC_EGENERIC;
271         }
272     }
273     else if( p_dec->fmt_in.i_codec == VLC_FOURCC( 'a', 'r', 'a', 'w' ) )
274     {
275         switch( ( p_dec->fmt_in.audio.i_bitspersample + 7 ) / 8 )
276         {
277         case 1:
278             p_dec->fmt_out.i_codec = VLC_FOURCC('u','8',' ',' ');
279             break;
280         case 2:
281             p_dec->fmt_out.i_codec = VLC_FOURCC('s','1','6','l');
282             break;
283         case 3:
284             p_dec->fmt_out.i_codec = VLC_FOURCC('s','2','4','l');
285             break;
286         case 4:
287             p_dec->fmt_out.i_codec = VLC_FOURCC('s','3','2','l');
288             break;
289         default:
290             msg_Err( p_dec, "bad parameters(bits/sample)" );
291             return VLC_EGENERIC;
292         }
293     }
294     else if( p_dec->fmt_in.i_codec == VLC_FOURCC( 't', 'w', 'o', 's' ) )
295     {
296         switch( ( p_dec->fmt_in.audio.i_bitspersample + 7 ) / 8 )
297         {
298         case 1:
299             p_dec->fmt_out.i_codec = VLC_FOURCC('s','8',' ',' ');
300             break;
301         case 2:
302             p_dec->fmt_out.i_codec = VLC_FOURCC('s','1','6','b');
303             break;
304         case 3:
305             p_dec->fmt_out.i_codec = VLC_FOURCC('s','2','4','b');
306             break;
307         case 4:
308             p_dec->fmt_out.i_codec = VLC_FOURCC('s','3','2','b');
309             break;
310         default:
311             msg_Err( p_dec, "bad parameters(bits/sample)" );
312             return VLC_EGENERIC;
313         }
314     }
315     else if( p_dec->fmt_in.i_codec == VLC_FOURCC( 's', 'o', 'w', 't' ) )
316     {
317         switch( ( p_dec->fmt_in.audio.i_bitspersample + 7 ) / 8 )
318         {
319         case 1:
320             p_dec->fmt_out.i_codec = VLC_FOURCC('s','8',' ',' ');
321             break;
322         case 2:
323             p_dec->fmt_out.i_codec = VLC_FOURCC('s','1','6','l');
324             break;
325         case 3:
326             p_dec->fmt_out.i_codec = VLC_FOURCC('s','2','4','l');
327             break;
328         case 4:
329             p_dec->fmt_out.i_codec = VLC_FOURCC('s','3','2','l');
330             break;
331         default:
332             msg_Err( p_dec, "bad parameters(bits/sample)" );
333             return VLC_EGENERIC;
334         }
335     }
336     else if( p_dec->fmt_in.i_codec == VLC_FOURCC( 'a', 'l', 'a', 'w' ) )
337     {
338         p_dec->fmt_out.i_codec = AOUT_FMT_S16_NE;
339         p_sys->p_logtos16  = alawtos16;
340         p_dec->fmt_in.audio.i_bitspersample = 8;
341     }
342     else if( p_dec->fmt_in.i_codec == VLC_FOURCC( 'u', 'l', 'a', 'w' ) ||
343              p_dec->fmt_in.i_codec == VLC_FOURCC( 'm', 'l', 'a', 'w' ) )
344     {
345         p_dec->fmt_out.i_codec = AOUT_FMT_S16_NE;
346         p_sys->p_logtos16  = ulawtos16;
347         p_dec->fmt_in.audio.i_bitspersample = 8;
348     }
349
350     /* Set output properties */
351     p_dec->fmt_out.i_cat = AUDIO_ES;
352     p_dec->fmt_out.audio.i_rate = p_dec->fmt_in.audio.i_rate;
353     p_dec->fmt_out.audio.i_channels = p_dec->fmt_in.audio.i_channels;
354     p_dec->fmt_out.audio.i_bitspersample = p_dec->fmt_in.audio.i_bitspersample;
355     p_dec->fmt_out.audio.i_physical_channels =
356         p_dec->fmt_out.audio.i_original_channels =
357             pi_channels_maps[p_dec->fmt_in.audio.i_channels];
358     if( p_dec->fmt_in.audio.i_physical_channels )
359         p_dec->fmt_out.audio.i_physical_channels =
360             p_dec->fmt_in.audio.i_physical_channels;
361     if( p_dec->fmt_in.audio.i_original_channels )
362         p_dec->fmt_out.audio.i_original_channels =
363             p_dec->fmt_in.audio.i_original_channels;
364
365     if( p_dec->fmt_in.i_codec == VLC_FOURCC( 'a', 'l', 'a', 'w' ) ||
366         p_dec->fmt_in.i_codec == VLC_FOURCC( 'u', 'l', 'a', 'w' ) ||
367         p_dec->fmt_in.i_codec == VLC_FOURCC( 'm', 'l', 'a', 'w' ) )
368     {
369         p_dec->fmt_out.audio.i_bitspersample = 16;
370     }
371
372     aout_DateInit( &p_sys->end_date, p_dec->fmt_out.audio.i_rate );
373     aout_DateSet( &p_sys->end_date, 0 );
374
375     p_dec->pf_decode_audio = DecodeBlock;
376
377     return VLC_SUCCESS;
378 }
379
380 /****************************************************************************
381  * DecodeBlock: the whole thing
382  ****************************************************************************
383  * This function must be fed with whole samples (see nBlockAlign).
384  ****************************************************************************/
385 static aout_buffer_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
386 {
387     decoder_sys_t *p_sys = p_dec->p_sys;
388     block_t *p_block;
389     aout_buffer_t *p_out;
390     int i_samples;
391
392     if( !pp_block || !*pp_block ) return NULL;
393
394     p_block = *pp_block;
395
396     if( p_block->i_pts != 0 &&
397         p_block->i_pts != aout_DateGet( &p_sys->end_date ) )
398     {
399         aout_DateSet( &p_sys->end_date, p_block->i_pts );
400     }
401     else if( !aout_DateGet( &p_sys->end_date ) )
402     {
403         /* We've just started the stream, wait for the first PTS. */
404         block_Release( p_block );
405         return NULL;
406     }
407
408     /* Don't re-use the same pts twice */
409     p_block->i_pts = 0;
410
411     i_samples = p_block->i_buffer * 8 / p_dec->fmt_in.audio.i_bitspersample /
412         p_dec->fmt_in.audio.i_channels;
413
414     if( i_samples <= 0 )
415     {
416         block_Release( p_block );
417         return NULL;
418     }
419
420     /* Create chunks of max 1024 samples */
421     i_samples = __MIN( i_samples, 1024 );
422
423     p_out = p_dec->pf_aout_buffer_new( p_dec, i_samples );
424     if( p_out == NULL )
425     {
426         block_Release( p_block );
427         return NULL;
428     }
429
430     p_out->start_date = aout_DateGet( &p_sys->end_date );
431     p_out->end_date   = aout_DateIncrement( &p_sys->end_date, i_samples );
432
433     if( p_sys->p_logtos16 )
434     {
435         int16_t *s = (int16_t*)p_out->p_buffer;
436         unsigned int i;
437
438         for( i = 0; i < p_out->i_nb_bytes / 2; i++ )
439         {
440             *s++ = p_sys->p_logtos16[*p_block->p_buffer++];
441             p_block->i_buffer--;
442         }
443     }
444     else
445     {
446         memcpy( p_out->p_buffer, p_block->p_buffer, p_out->i_nb_bytes );
447         p_block->p_buffer += p_out->i_nb_bytes;
448         p_block->i_buffer -= p_out->i_nb_bytes;
449     }
450
451     return p_out;
452 }
453
454 /*****************************************************************************
455  * DecoderClose: decoder destruction
456  *****************************************************************************/
457 static void DecoderClose( vlc_object_t *p_this )
458 {
459     decoder_t *p_dec = (decoder_t *)p_this;
460
461     free( p_dec->p_sys );
462 }
463
464 /*****************************************************************************
465  * EncoderOpen:
466  *****************************************************************************/
467 static int EncoderOpen( vlc_object_t *p_this )
468 {
469     encoder_t *p_enc = (encoder_t *)p_this;
470
471     if( p_enc->fmt_out.i_codec == VLC_FOURCC('u','8',' ',' ') ||
472         p_enc->fmt_out.i_codec == VLC_FOURCC('s','8',' ',' ') )
473     {
474         p_enc->fmt_out.audio.i_bitspersample = 8;
475     }
476     else if( p_enc->fmt_out.i_codec == VLC_FOURCC('u','1','6','l') ||
477              p_enc->fmt_out.i_codec == VLC_FOURCC('u','1','6','b') ||
478              p_enc->fmt_out.i_codec == VLC_FOURCC('s','1','6','l') ||
479              p_enc->fmt_out.i_codec == VLC_FOURCC('s','1','6','b') )
480     {
481         p_enc->fmt_out.audio.i_bitspersample = 16;
482     }
483     else if( p_enc->fmt_out.i_codec == VLC_FOURCC('u','2','4','l') ||
484              p_enc->fmt_out.i_codec == VLC_FOURCC('u','2','4','b') ||
485              p_enc->fmt_out.i_codec == VLC_FOURCC('s','2','4','l') ||
486              p_enc->fmt_out.i_codec == VLC_FOURCC('s','2','4','b') )
487     {
488         p_enc->fmt_out.audio.i_bitspersample = 24;
489     }
490     else if( p_enc->fmt_out.i_codec == VLC_FOURCC('u','3','2','l') ||
491              p_enc->fmt_out.i_codec == VLC_FOURCC('u','3','2','b') ||
492              p_enc->fmt_out.i_codec == VLC_FOURCC('s','3','2','l') ||
493              p_enc->fmt_out.i_codec == VLC_FOURCC('s','3','2','b') ||
494              p_enc->fmt_out.i_codec == VLC_FOURCC('f','i','3','2') ||
495              p_enc->fmt_out.i_codec == VLC_FOURCC('f','l','3','2') )
496     {
497         p_enc->fmt_out.audio.i_bitspersample = 32;
498     }
499     else if( p_enc->fmt_out.i_codec == VLC_FOURCC('f','l','6','4') )
500     {
501         p_enc->fmt_out.audio.i_bitspersample = 64;
502     }
503     else
504     {
505         return VLC_EGENERIC;
506     }
507
508     p_enc->p_sys = NULL;
509     p_enc->pf_encode_audio = EncoderEncode;
510     p_enc->fmt_in.i_codec = p_enc->fmt_out.i_codec;
511
512     return VLC_SUCCESS;
513 }
514
515 /*****************************************************************************
516  * EncoderClose:
517  *****************************************************************************/
518 static void EncoderClose ( vlc_object_t *p_this )
519 {
520     return;
521 }
522
523 /*****************************************************************************
524  * EncoderEncode:
525  *****************************************************************************/
526 static block_t *EncoderEncode( encoder_t *p_enc, aout_buffer_t *p_aout_buf )
527 {
528     block_t *p_block = NULL;
529
530     if( !p_aout_buf || !p_aout_buf->i_nb_bytes ) return NULL;
531
532     if( ( p_block = block_New( p_enc, p_aout_buf->i_nb_bytes ) ) )
533     {
534         memcpy( p_block->p_buffer, p_aout_buf->p_buffer,
535                 p_aout_buf->i_nb_bytes );
536     }
537
538     if( p_block )
539     {
540         p_block->i_dts = p_block->i_pts = p_aout_buf->start_date;
541         p_block->i_length = (int64_t)p_aout_buf->i_nb_samples *
542             (int64_t)1000000 / p_enc->fmt_in.audio.i_rate;
543     }
544
545     return p_block;
546 }