]> git.sesse.net Git - vlc/blob - modules/codec/a52.c
* include/vlc_block_helper.h, modules/codec/a52.c: same as thedj ;)
[vlc] / modules / codec / a52.c
1 /*****************************************************************************
2  * a52.c: A/52 basic parser
3  *****************************************************************************
4  * Copyright (C) 2001-2002 VideoLAN
5  * $Id: a52.c,v 1.25 2003/09/30 20:36:46 gbazin Exp $
6  *
7  * Authors: Stéphane Borel <stef@via.ecp.fr>
8  *          Christophe Massiot <massiot@via.ecp.fr>
9  *          Gildas Bazin <gbazin@netcourrier.com>
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
24  *****************************************************************************/
25
26 /*****************************************************************************
27  * Preamble
28  *****************************************************************************/
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>                                              /* memcpy() */
32 #include <fcntl.h>
33
34 #include <vlc/vlc.h>
35 #include <vlc/decoder.h>
36 #include <vlc/input.h>
37 #include <vlc/aout.h>
38 #include <vlc/sout.h>
39
40 #ifdef HAVE_UNISTD_H
41 #   include <unistd.h>
42 #endif
43
44 #include "vlc_block_helper.h"
45
46 #define A52_HEADER_SIZE 7
47
48 /*****************************************************************************
49  * decoder_sys_t : decoder descriptor
50  *****************************************************************************/
51 struct decoder_sys_t
52 {
53     /* Module mode */
54     vlc_bool_t b_packetizer;
55
56     /*
57      * Input properties
58      */
59     int        i_state;
60     vlc_bool_t b_synchro;
61
62     block_t *p_chain;
63     block_bytestream_t bytestream;
64
65     /*
66      * Decoder output properties
67      */
68     aout_instance_t *     p_aout;                                  /* opaque */
69     aout_input_t *        p_aout_input;                            /* opaque */
70     audio_sample_format_t aout_format;
71     aout_buffer_t *       p_aout_buffer; /* current aout buffer being filled */
72
73     /*
74      * Packetizer output properties
75      */
76     sout_packetizer_input_t *p_sout_input;
77     sout_format_t           sout_format;
78     sout_buffer_t *         p_sout_buffer;            /* current sout buffer */
79
80     /*
81      * Common properties
82      */
83     uint8_t               *p_out_buffer;                    /* output buffer */
84     int                   i_out_buffer;         /* position in output buffer */
85     audio_date_t          end_date;
86
87     mtime_t pts;
88     int i_frame_size, i_bit_rate;
89     unsigned int i_rate, i_channels, i_channels_conf;
90
91 };
92
93 enum {
94
95     STATE_NOSYNC,
96     STATE_SYNC,
97     STATE_HEADER,
98     STATE_DATA
99 };
100
101 /****************************************************************************
102  * Local prototypes
103  ****************************************************************************/
104 static int  OpenDecoder   ( vlc_object_t * );
105 static int  OpenPacketizer( vlc_object_t * );
106
107 static int  InitDecoder   ( decoder_t * );
108 static int  RunDecoder    ( decoder_t *, block_t * );
109 static int  EndDecoder    ( decoder_t * );
110
111 static int  SyncInfo      ( const byte_t *, int *, int *, int *,int * );
112
113 static int GetOutBuffer ( decoder_t *, uint8_t ** );
114 static int GetAoutBuffer( decoder_t *, aout_buffer_t ** );
115 static int GetSoutBuffer( decoder_t *, sout_buffer_t ** );
116 static int SendOutBuffer( decoder_t * );
117
118 /*****************************************************************************
119  * Module descriptor
120  *****************************************************************************/
121 vlc_module_begin();
122     set_description( _("A/52 parser") );
123     set_capability( "decoder", 100 );
124     set_callbacks( OpenDecoder, NULL );
125
126     add_submodule();
127     set_description( _("A/52 audio packetizer") );
128     set_capability( "packetizer", 10 );
129     set_callbacks( OpenPacketizer, NULL );
130 vlc_module_end();
131
132 /*****************************************************************************
133  * OpenDecoder: probe the decoder and return score
134  *****************************************************************************/
135 static int OpenDecoder( vlc_object_t *p_this )
136 {
137     decoder_t *p_dec = (decoder_t*)p_this;
138
139     if( p_dec->p_fifo->i_fourcc != VLC_FOURCC('a','5','2',' ')
140          && p_dec->p_fifo->i_fourcc != VLC_FOURCC('a','5','2','b') )
141     {
142         return VLC_EGENERIC;
143     }
144
145     p_dec->pf_init = InitDecoder;
146     p_dec->pf_decode = RunDecoder;
147     p_dec->pf_end = EndDecoder;
148
149     /* Allocate the memory needed to store the decoder's structure */
150     if( ( p_dec->p_sys =
151           (decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL )
152     {
153         msg_Err( p_dec, "out of memory" );
154         return VLC_EGENERIC;
155     }
156     p_dec->p_sys->b_packetizer = VLC_FALSE;
157
158     return VLC_SUCCESS;
159 }
160
161 static int OpenPacketizer( vlc_object_t *p_this )
162 {
163     decoder_t *p_dec = (decoder_t*)p_this;
164
165     int i_ret = OpenDecoder( p_this );
166
167     if( i_ret == VLC_SUCCESS ) p_dec->p_sys->b_packetizer = VLC_TRUE;
168
169     return i_ret;
170 }
171
172 /*****************************************************************************
173  * InitDecoder: Initalize the decoder
174  *****************************************************************************/
175 static int InitDecoder( decoder_t *p_dec )
176 {
177     p_dec->p_sys->i_state = STATE_NOSYNC;
178     p_dec->p_sys->b_synchro = VLC_FALSE;
179
180     p_dec->p_sys->p_out_buffer = NULL;
181     p_dec->p_sys->i_out_buffer = 0;
182     aout_DateSet( &p_dec->p_sys->end_date, 0 );
183
184     p_dec->p_sys->p_aout = NULL;
185     p_dec->p_sys->p_aout_input = NULL;
186     p_dec->p_sys->p_aout_buffer = NULL;
187     p_dec->p_sys->aout_format.i_format = VLC_FOURCC('a','5','2',' ');
188
189     p_dec->p_sys->p_sout_input = NULL;
190     p_dec->p_sys->p_sout_buffer = NULL;
191     p_dec->p_sys->sout_format.i_cat = AUDIO_ES;
192     p_dec->p_sys->sout_format.i_fourcc = VLC_FOURCC( 'a', '5', '2', ' ' );
193
194     p_dec->p_sys->p_chain = NULL;
195
196     return VLC_SUCCESS;
197 }
198
199 /****************************************************************************
200  * RunDecoder: the whole thing
201  ****************************************************************************
202  * This function is called just after the thread is launched.
203  ****************************************************************************/
204 static int RunDecoder( decoder_t *p_dec, block_t *p_block )
205 {
206     decoder_sys_t *p_sys = p_dec->p_sys;
207     uint8_t p_header[A52_HEADER_SIZE];
208
209     if( p_sys->p_chain )
210     {
211         block_ChainAppend( &p_sys->p_chain, p_block );
212     }
213     else
214     {
215         block_ChainAppend( &p_sys->p_chain, p_block );
216         p_sys->bytestream = block_BytestreamInit( p_dec, p_sys->p_chain, 0 );
217     }
218
219     while( 1 )
220     {
221         switch( p_sys->i_state )
222         {
223
224         case STATE_NOSYNC:
225             while( block_PeekBytes( &p_sys->bytestream, p_header, 2 )
226                    == VLC_SUCCESS )
227             {
228                 if( p_header[0] == 0x0b && p_header[1] == 0x77 )
229                 {
230                     p_sys->i_state = STATE_SYNC;
231                     break;
232                 }
233                 block_SkipByte( &p_sys->bytestream );
234                 p_dec->p_sys->b_synchro = VLC_FALSE;
235             }
236             if( p_sys->i_state != STATE_SYNC )
237             {
238                 block_ChainRelease( p_sys->p_chain );
239                 p_sys->p_chain = NULL;
240
241                 /* Need more data */
242                 return VLC_SUCCESS;
243             }
244
245         case STATE_SYNC:
246             /* New frame, set the Presentation Time Stamp */
247             p_sys->pts = p_sys->bytestream.p_block->i_pts;
248             if( p_sys->pts != 0 &&
249                 p_sys->pts != aout_DateGet( &p_sys->end_date ) )
250             {
251                 aout_DateSet( &p_sys->end_date, p_sys->pts );
252             }
253             p_sys->i_state = STATE_HEADER;
254             break;
255
256         case STATE_HEADER:
257             /* Get A/52 frame header (A52_HEADER_SIZE bytes) */
258             if( block_PeekBytes( &p_sys->bytestream, p_header,
259                                  A52_HEADER_SIZE ) != VLC_SUCCESS )
260             {
261                 /* Need more data */
262                 return VLC_SUCCESS;
263             }
264
265             /* Check if frame is valid and get frame info */
266             p_sys->i_frame_size = SyncInfo( p_header,
267                                             &p_sys->i_channels,
268                                             &p_sys->i_channels_conf,
269                                             &p_sys->i_rate,
270                                             &p_sys->i_bit_rate );
271             if( !p_sys->i_frame_size )
272             {
273                 msg_Dbg( p_dec, "emulated sync word" );
274                 block_SkipByte( &p_sys->bytestream );
275                 p_sys->i_state = STATE_NOSYNC;
276                 p_dec->p_sys->b_synchro = VLC_FALSE;
277                 break;
278             }
279             p_sys->i_state = STATE_DATA;
280
281         case STATE_DATA:
282             /* TODO: If p_block == NULL, flush the buffer without checking the
283              * next sync word */
284
285             if( !p_dec->p_sys->b_synchro )
286             {
287                 /* Check if next expected frame contains the sync word */
288                 if( block_PeekOffsetBytes( &p_sys->bytestream,
289                                            p_sys->i_frame_size, p_header, 2 )
290                     != VLC_SUCCESS )
291                 {
292                     /* Need more data */
293                     return VLC_SUCCESS;
294                 }
295
296                 if( p_header[0] != 0x0b || p_header[1] != 0x77 )
297                 {
298                     msg_Dbg( p_dec, "emulated sync word "
299                              "(no sync on following frame)" );
300                     p_sys->i_state = STATE_NOSYNC;
301                     block_SkipByte( &p_sys->bytestream );
302                     p_dec->p_sys->b_synchro = VLC_FALSE;
303                     break;
304                 }
305             }
306
307             if( !p_dec->p_sys->p_out_buffer )
308             if( GetOutBuffer( p_dec, &p_sys->p_out_buffer ) != VLC_SUCCESS )
309             {
310                 return VLC_EGENERIC;
311             }
312
313             /* Copy the whole frame into the buffer */
314             if( block_GetBytes( &p_sys->bytestream, p_sys->p_out_buffer,
315                                 p_sys->i_frame_size ) != VLC_SUCCESS )
316             {
317                 /* Need more data */
318                 return VLC_SUCCESS;
319             }
320
321             p_sys->p_chain = block_BytestreamFlush( &p_sys->bytestream );
322
323             SendOutBuffer( p_dec );
324             p_sys->i_state = STATE_NOSYNC;
325             p_dec->p_sys->b_synchro = VLC_TRUE;
326
327             /* Make sure we don't reuse the same pts twice */
328             if( p_sys->pts == p_sys->bytestream.p_block->i_pts )
329                 p_sys->pts = p_sys->bytestream.p_block->i_pts = 0;
330         }
331     }
332
333     return VLC_SUCCESS;
334 }
335
336 /*****************************************************************************
337  * EndDecoder: clean up the decoder
338  *****************************************************************************/
339 static int EndDecoder( decoder_t *p_dec )
340 {
341     if( p_dec->p_sys->p_aout_input != NULL )
342     {
343         if( p_dec->p_sys->p_aout_buffer )
344         {
345             aout_DecDeleteBuffer( p_dec->p_sys->p_aout,
346                                   p_dec->p_sys->p_aout_input,
347                                   p_dec->p_sys->p_aout_buffer );
348         }
349
350         aout_DecDelete( p_dec->p_sys->p_aout, p_dec->p_sys->p_aout_input );
351     }
352
353     if( p_dec->p_sys->p_sout_input != NULL )
354     {
355         if( p_dec->p_sys->p_sout_buffer )
356         {
357             sout_BufferDelete( p_dec->p_sys->p_sout_input->p_sout,
358                                p_dec->p_sys->p_sout_buffer );
359         }
360
361         sout_InputDelete( p_dec->p_sys->p_sout_input );
362     }
363
364     if( p_dec->p_sys->p_chain ) block_ChainRelease( p_dec->p_sys->p_chain );
365
366     free( p_dec->p_sys );
367
368     return VLC_SUCCESS;
369 }
370
371 /*****************************************************************************
372  * GetOutBuffer:
373  *****************************************************************************/
374 static int GetOutBuffer( decoder_t *p_dec, uint8_t **pp_out_buffer )
375 {
376     decoder_sys_t *p_sys = p_dec->p_sys;
377     int i_ret;
378
379     if( p_sys->b_packetizer )
380     {
381         i_ret= GetSoutBuffer( p_dec, &p_sys->p_sout_buffer );
382         *pp_out_buffer =
383             p_sys->p_sout_buffer ? p_sys->p_sout_buffer->p_buffer : NULL;
384     }
385     else
386     {
387         i_ret = GetAoutBuffer( p_dec, &p_sys->p_aout_buffer );
388         *pp_out_buffer =
389             p_sys->p_aout_buffer ? p_sys->p_aout_buffer->p_buffer : NULL;
390     }
391
392     return i_ret;
393 }
394
395 /*****************************************************************************
396  * GetAoutBuffer:
397  *****************************************************************************/
398 static int GetAoutBuffer( decoder_t *p_dec, aout_buffer_t **pp_buffer )
399 {
400     decoder_sys_t *p_sys = p_dec->p_sys;
401
402     if( p_sys->p_aout_input != NULL &&
403         ( p_sys->aout_format.i_rate != p_sys->i_rate
404         || p_sys->aout_format.i_original_channels != p_sys->i_channels_conf
405         || (int)p_sys->aout_format.i_bytes_per_frame != p_sys->i_frame_size ) )
406     {
407         /* Parameters changed - this should not happen. */
408         aout_DecDelete( p_sys->p_aout, p_sys->p_aout_input );
409         p_sys->p_aout_input = NULL;
410     }
411
412     /* Creating the audio input if not created yet. */
413     if( p_sys->p_aout_input == NULL )
414     {
415         p_sys->aout_format.i_rate = p_sys->i_rate;
416         p_sys->aout_format.i_original_channels = p_sys->i_channels_conf;
417         p_sys->aout_format.i_physical_channels
418             = p_sys->i_channels_conf & AOUT_CHAN_PHYSMASK;
419         p_sys->aout_format.i_bytes_per_frame = p_sys->i_frame_size;
420         p_sys->aout_format.i_frame_length = A52_FRAME_NB;
421         aout_DateInit( &p_sys->end_date, p_sys->i_rate );
422         aout_DateSet( &p_sys->end_date, p_sys->pts );
423         p_sys->p_aout_input = aout_DecNew( p_dec,
424                                            &p_sys->p_aout,
425                                            &p_sys->aout_format );
426
427         if ( p_sys->p_aout_input == NULL )
428         {
429             *pp_buffer = NULL;
430             return VLC_SUCCESS;
431         }
432     }
433
434     if( !aout_DateGet( &p_sys->end_date ) )
435     {
436         /* We've just started the stream, wait for the first PTS. */
437         *pp_buffer = NULL;
438         return VLC_SUCCESS;
439     }
440
441     *pp_buffer = aout_DecNewBuffer( p_sys->p_aout, p_sys->p_aout_input,
442                                     A52_FRAME_NB );
443     if( *pp_buffer == NULL )
444     {
445         return VLC_SUCCESS;
446     }
447
448     (*pp_buffer)->start_date = aout_DateGet( &p_sys->end_date );
449     (*pp_buffer)->end_date =
450          aout_DateIncrement( &p_sys->end_date, A52_FRAME_NB );
451
452     return VLC_SUCCESS;
453 }
454
455 /*****************************************************************************
456  * GetSoutBuffer:
457  *****************************************************************************/
458 static int GetSoutBuffer( decoder_t *p_dec, sout_buffer_t **pp_buffer )
459 {
460     decoder_sys_t *p_sys = p_dec->p_sys;
461
462     if( p_sys->p_sout_input != NULL &&
463         ( p_sys->sout_format.i_sample_rate != (int)p_sys->i_rate
464           || p_sys->sout_format.i_channels != (int)p_sys->i_channels ) )
465     {
466         /* Parameters changed - this should not happen. */
467     }
468
469     /* Creating the sout input if not created yet. */
470     if( p_sys->p_sout_input == NULL )
471     {
472         p_sys->sout_format.i_sample_rate = p_sys->i_rate;
473         p_sys->sout_format.i_channels    = p_sys->i_channels;
474         p_sys->sout_format.i_block_align = 0;
475         p_sys->sout_format.i_bitrate     = p_sys->i_bit_rate;
476         p_sys->sout_format.i_extra_data  = 0;
477         p_sys->sout_format.p_extra_data  = NULL;
478
479         aout_DateInit( &p_sys->end_date, p_sys->i_rate );
480         aout_DateSet( &p_sys->end_date, p_sys->pts );
481
482         p_sys->p_sout_input = sout_InputNew( p_dec, &p_sys->sout_format );
483         if( p_sys->p_sout_input == NULL )
484         {
485             msg_Err( p_dec, "cannot add a new stream" );
486             *pp_buffer = NULL;
487             return VLC_EGENERIC;
488         }
489         msg_Info( p_dec, "A/52 channels:%d samplerate:%d bitrate:%d",
490                   p_sys->i_channels, p_sys->i_rate, p_sys->i_bit_rate );
491     }
492
493     if( !aout_DateGet( &p_sys->end_date ) )
494     {
495         /* We've just started the stream, wait for the first PTS. */
496         *pp_buffer = NULL;
497         return VLC_SUCCESS;
498     }
499
500     *pp_buffer = sout_BufferNew( p_sys->p_sout_input->p_sout,
501                                  p_sys->i_frame_size );
502     if( *pp_buffer == NULL )
503     {
504         return VLC_SUCCESS;
505     }
506
507     (*pp_buffer)->i_pts =
508         (*pp_buffer)->i_dts = aout_DateGet( &p_sys->end_date );
509
510     (*pp_buffer)->i_length =
511         aout_DateIncrement( &p_sys->end_date, A52_FRAME_NB )
512         - (*pp_buffer)->i_pts;
513
514     return VLC_SUCCESS;
515 }
516
517 /*****************************************************************************
518  * SendOutBuffer:
519  *****************************************************************************/
520 static int SendOutBuffer( decoder_t *p_dec )
521 {
522     decoder_sys_t *p_sys = p_dec->p_sys;
523
524     if( p_sys->b_packetizer )
525     {
526         sout_InputSendBuffer( p_sys->p_sout_input, p_sys->p_sout_buffer );
527         p_sys->p_sout_buffer = NULL;
528     }
529     else
530     {
531         /* We have all we need, send the buffer to the aout core. */
532         aout_DecPlay( p_sys->p_aout, p_sys->p_aout_input,
533                       p_sys->p_aout_buffer );
534         p_sys->p_aout_buffer = NULL;
535     }
536
537     p_sys->p_out_buffer = NULL;
538
539     return VLC_SUCCESS;
540 }
541
542 /*****************************************************************************
543  * SyncInfo: parse A/52 sync info
544  *****************************************************************************
545  * This code is borrowed from liba52 by Aaron Holtzman & Michel Lespinasse,
546  * since we don't want to oblige S/PDIF people to use liba52 just to get
547  * their SyncInfo...
548  *****************************************************************************/
549 static int SyncInfo( const byte_t * p_buf,
550                      int * pi_channels, int * pi_channels_conf,
551                      int * pi_sample_rate, int * pi_bit_rate )
552 {
553     static const uint8_t halfrate[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3 };
554     static const int rate[] = { 32,  40,  48,  56,  64,  80,  96, 112,
555                                 128, 160, 192, 224, 256, 320, 384, 448,
556                                 512, 576, 640 };
557     static const uint8_t lfeon[8] = { 0x10, 0x10, 0x04, 0x04,
558                                       0x04, 0x01, 0x04, 0x01 };
559     int frmsizecod;
560     int bitrate;
561     int half;
562     int acmod;
563
564     if ((p_buf[0] != 0x0b) || (p_buf[1] != 0x77))        /* syncword */
565         return 0;
566
567     if (p_buf[5] >= 0x60)                /* bsid >= 12 */
568         return 0;
569     half = halfrate[p_buf[5] >> 3];
570
571     /* acmod, dsurmod and lfeon */
572     acmod = p_buf[6] >> 5;
573     if ( (p_buf[6] & 0xf8) == 0x50 )
574     {
575         /* Dolby surround = stereo + Dolby */
576         *pi_channels = 2;
577         *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT
578                             | AOUT_CHAN_DOLBYSTEREO;
579     }
580     else switch ( acmod )
581     {
582     case 0x0:
583         /* Dual-mono = stereo + dual-mono */
584         *pi_channels = 2;
585         *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT
586                             | AOUT_CHAN_DUALMONO;
587         break;
588     case 0x1:
589         /* Mono */
590         *pi_channels = 1;
591         *pi_channels_conf = AOUT_CHAN_CENTER;
592         break;
593     case 0x2:
594         /* Stereo */
595         *pi_channels = 2;
596         *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT;
597         break;
598     case 0x3:
599         /* 3F */
600         *pi_channels = 3;
601         *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT
602                             | AOUT_CHAN_CENTER;
603         break;
604     case 0x4:
605         /* 2F1R */
606         *pi_channels = 3;
607         *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT
608                             | AOUT_CHAN_REARCENTER;
609         break;
610     case 0x5:
611         /* 3F1R */
612         *pi_channels = 4;
613         *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
614                             | AOUT_CHAN_REARCENTER;
615         break;
616     case 0x6:
617         /* 2F2R */
618         *pi_channels = 4;
619         *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT
620                             | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT;
621         break;
622     case 0x7:
623         /* 3F2R */
624         *pi_channels = 5;
625         *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
626                             | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT;
627         break;
628     default:
629         return 0;
630     }
631
632     if ( p_buf[6] & lfeon[acmod] )
633     {
634         (*pi_channels)++;
635         *pi_channels_conf |= AOUT_CHAN_LFE;
636     }
637
638     frmsizecod = p_buf[4] & 63;
639     if (frmsizecod >= 38)
640         return 0;
641     bitrate = rate [frmsizecod >> 1];
642     *pi_bit_rate = (bitrate * 1000) >> half;
643
644     switch (p_buf[4] & 0xc0) {
645     case 0:
646         *pi_sample_rate = 48000 >> half;
647         return 4 * bitrate;
648     case 0x40:
649         *pi_sample_rate = 44100 >> half;
650         return 2 * (320 * bitrate / 147 + (frmsizecod & 1));
651     case 0x80:
652         *pi_sample_rate = 32000 >> half;
653         return 6 * bitrate;
654     default:
655         return 0;
656     }
657 }