OSDN Git Service

Softer resampling when audio dates are messed up (fix for LPCM issues).
[handbrake-jp/handbrake-jp-git.git] / libhb / declpcm.c
1 /* $Id: declpcm.c,v 1.8 2005/11/04 14:44:01 titer Exp $
2
3    This file is part of the HandBrake source code.
4    Homepage: <http://handbrake.m0k.org/>.
5    It may be used under the terms of the GNU General Public License. */
6
7 #include "hb.h"
8
9 struct hb_work_object_s
10 {
11     HB_WORK_COMMON;
12
13     hb_job_t    * job;
14     hb_audio_t  * audio;
15 };
16
17 static int Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
18                  hb_buffer_t ** buf_out )
19 {
20     hb_buffer_t * in = *buf_in, * out;
21     int samplerate = 0;
22     int count;
23     uint8_t * samples_u8;
24     float   * samples_fl32;
25     int i;
26     uint64_t duration;
27
28     *buf_out = NULL;
29
30     if( in->data[5] != 0x80 )
31     {
32         hb_log( "no LPCM frame sync (%02x)", in->data[5] );
33         return HB_WORK_OK;
34     }
35
36     switch( ( in->data[4] >> 4 ) & 0x3 )
37     {
38         case 0:
39             samplerate = 48000;
40             break;
41         case 1:
42             samplerate = 96000;//32000; /* FIXME vlc says it is 96000 */
43             break;
44         case 2:
45             samplerate = 44100;
46             break;
47         case 3:
48             samplerate = 32000;
49             break;
50     }
51
52     count       = ( in->size - 6 ) / 2;
53     out         = hb_buffer_init( count * sizeof( float ) );
54     duration    = count * 90000 / samplerate / 2;
55     out->start  = in->start;
56     out->stop   = out->start + duration;
57
58     samples_u8   = in->data + 6;
59     samples_fl32 = (float *) out->data;
60
61     /* Big endian int16 -> float conversion */
62     for( i = 0; i < count; i++ )
63     {
64 #ifdef WORDS_BIGENDIAN
65         samples_fl32[0] = *( (int16_t *) samples_u8 );
66 #else
67         samples_fl32[0] = (int16_t) ( ( samples_u8[0] << 8 ) | samples_u8[1] );
68 #endif
69         samples_u8   += 2;
70         samples_fl32 += 1;
71     }
72
73     *buf_out = out;
74
75     return HB_WORK_OK;
76 }
77
78 static void Close( hb_work_object_t ** _w )
79 {
80     hb_work_object_t * w = *_w;
81     free( w->name );
82     free( w );
83     *_w = NULL;
84 }
85
86 hb_work_object_t * hb_work_declpcm_init( hb_job_t * job, hb_audio_t * audio )
87 {
88     hb_work_object_t * w = calloc( sizeof( hb_work_object_t ), 1 );
89     w->name  = strdup( "LPCM decoder" );
90     w->work  = Work;
91     w->close = Close;
92
93     w->job   = job;
94     w->audio = audio;
95
96     return w;
97 }
98