1 /*
2 * This file is part of MPlayer.
3 *
4 * MPlayer is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * MPlayer is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <unistd.h>
22
23 #include "config.h"
24 #include "mp_msg.h"
25 #include "ad_internal.h"
26
27 static const ad_info_t info = {
28 "libmad mpeg audio decoder",
29 "libmad",
30 "A'rpi",
31 "libmad...",
32 "based on Xine's libmad/xine_decoder.c"
33 };
34
35 LIBAD_EXTERN(libmad)
36
37 #include <mad.h>
38
39 typedef struct mad_decoder_s {
40
41 struct mad_synth synth;
42 struct mad_stream stream;
43 struct mad_frame frame;
44
45 int have_frame;
46
47 int output_sampling_rate;
48 int output_open;
49 int output_mode;
50
51 } mad_decoder_t;
52
preinit(sh_audio_t * sh)53 static int preinit(sh_audio_t *sh){
54
55 mad_decoder_t *this = calloc(1, sizeof(mad_decoder_t));
56 sh->context = this;
57
58 mad_synth_init (&this->synth);
59 mad_stream_init (&this->stream);
60 mad_frame_init (&this->frame);
61
62 sh->audio_out_minsize=2*4608;
63 sh->audio_in_minsize=4096;
64
65 return 1;
66 }
67
read_frame(sh_audio_t * sh)68 static int read_frame(sh_audio_t *sh){
69 mad_decoder_t *this = sh->context;
70
71 while(1){
72 int ret;
73 mad_stream_buffer (&this->stream, sh->a_in_buffer, sh->a_in_buffer_len);
74 ret=mad_frame_decode (&this->frame, &this->stream);
75 if (this->stream.next_frame) {
76 unsigned processed = this->stream.next_frame - (uint8_t *)sh->a_in_buffer;
77 sh->a_in_buffer_len -= processed;
78 memmove(sh->a_in_buffer, this->stream.next_frame, sh->a_in_buffer_len);
79 mp_msg(MSGT_DECAUDIO,MSGL_DBG2,"libmad: %d bytes processed\n",processed);
80 }
81 if (ret == 0) return 1; // OK!!!
82 // error! try to resync!
83 if(this->stream.error==MAD_ERROR_BUFLEN) {
84 int len=demux_read_data(sh->ds,&sh->a_in_buffer[sh->a_in_buffer_len],
85 sh->a_in_buffer_size-sh->a_in_buffer_len);
86 if (len <= 0) break;
87 sh->a_in_buffer_len+=len;
88 }
89 }
90 mp_msg(MSGT_DECAUDIO,MSGL_INFO,"Cannot sync MAD frame\n");
91 return 0;
92 }
93
init(sh_audio_t * sh)94 static int init(sh_audio_t *sh){
95 mad_decoder_t *this = sh->context;
96
97 this->have_frame=read_frame(sh);
98 if(!this->have_frame) return 0; // failed to sync...
99
100 sh->channels=(this->frame.header.mode == MAD_MODE_SINGLE_CHANNEL) ? 1 : 2;
101 sh->samplerate=this->frame.header.samplerate;
102 if (sh->i_bps < 1)
103 sh->i_bps=this->frame.header.bitrate/8;
104 sh->samplesize=2;
105
106 return 1;
107 }
108
uninit(sh_audio_t * sh)109 static void uninit(sh_audio_t *sh){
110 mad_decoder_t *this = sh->context;
111 mad_synth_finish (&this->synth);
112 mad_frame_finish (&this->frame);
113 mad_stream_finish(&this->stream);
114 free(sh->context);
115 }
116
117 /* utility to scale and round samples to 16 bits */
scale(mad_fixed_t sample)118 static inline signed int scale(mad_fixed_t sample) {
119 /* round */
120 sample += (1L << (MAD_F_FRACBITS - 16));
121
122 /* clip */
123 if (sample >= MAD_F_ONE)
124 sample = MAD_F_ONE - 1;
125 else if (sample < -MAD_F_ONE)
126 sample = -MAD_F_ONE;
127
128 /* quantize */
129 return sample >> (MAD_F_FRACBITS + 1 - 16);
130 }
131
decode_audio(sh_audio_t * sh,unsigned char * buf,int minlen,int maxlen)132 static int decode_audio(sh_audio_t *sh,unsigned char *buf,int minlen,int maxlen){
133 mad_decoder_t *this = sh->context;
134 int len=0;
135
136 while(len<minlen && len+4608<=maxlen){
137 if(!this->have_frame) this->have_frame=read_frame(sh);
138 if(!this->have_frame) break; // failed to sync... or EOF
139 this->have_frame=0;
140
141 mad_synth_frame (&this->synth, &this->frame);
142
143 { unsigned int nchannels, nsamples;
144 mad_fixed_t const *left_ch, *right_ch;
145 struct mad_pcm *pcm = &this->synth.pcm;
146 uint16_t *output = (uint16_t*) buf;
147
148 nchannels = pcm->channels;
149 nsamples = pcm->length;
150 left_ch = pcm->samples[0];
151 right_ch = pcm->samples[1];
152
153 len+=2*nchannels*nsamples;
154 buf+=2*nchannels*nsamples;
155
156 while (nsamples--) {
157 /* output sample(s) in 16-bit signed little-endian PCM */
158
159 *output++ = scale(*left_ch++);
160
161 if (nchannels == 2)
162 *output++ = scale(*right_ch++);
163
164 }
165 }
166 }
167
168 return len?len:-1;
169 }
170
control(sh_audio_t * sh,int cmd,void * arg,...)171 static int control(sh_audio_t *sh,int cmd,void* arg, ...){
172 mad_decoder_t *this = sh->context;
173 // various optional functions you MAY implement:
174 switch(cmd){
175 case ADCTRL_RESYNC_STREAM:
176 this->have_frame=0;
177 mad_synth_init (&this->synth);
178 mad_stream_init (&this->stream);
179 mad_frame_init (&this->frame);
180 return CONTROL_TRUE;
181 case ADCTRL_SKIP_FRAME:
182 this->have_frame=read_frame(sh);
183 return CONTROL_TRUE;
184 }
185 return CONTROL_UNKNOWN;
186 }
187