1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
9 * Copyright (C) 2002 Dave Chapman
11 * This file contains significant code from two other projects:
13 * 1) madldd - a sample application to use libmad
14 * 2) CoolPlayer - a win32 audio player that also uses libmad
16 * All files in this archive are subject to the GNU General Public License.
17 * See the file COPYING in the source tree root for full license agreement.
19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 * KIND, either express or implied.
22 ****************************************************************************/
39 /* The "dither" code to convert the 24-bit samples produced by libmad was
40 taken from the coolplayer project - coolplayer.sourceforge.net */
46 # define SAMPLE_DEPTH 16
47 # define scale(x, y) dither((x), (y))
49 struct mad_stream Stream
;
50 struct mad_frame Frame
;
51 struct mad_synth Synth
;
56 * DESCRIPTION: 32-bit pseudo-random number generator
59 unsigned long prng(unsigned long state
)
61 return (state
* 0x0019660dL
+ 0x3c6ef35fL
) & 0xffffffffL
;
66 * DESCRIPTION: dither and scale sample
69 signed int dither(mad_fixed_t sample
, struct dither
*dither
)
71 unsigned int scalebits
;
72 mad_fixed_t output
, mask
, random
;
80 sample
+= dither
->error
[0] - dither
->error
[1] + dither
->error
[2];
82 dither
->error
[2] = dither
->error
[1];
83 dither
->error
[1] = dither
->error
[0] / 2;
86 output
= sample
+ (1L << (MAD_F_FRACBITS
+ 1 - SAMPLE_DEPTH
- 1));
88 scalebits
= MAD_F_FRACBITS
+ 1 - SAMPLE_DEPTH
;
89 mask
= (1L << scalebits
) - 1;
92 random
= prng(dither
->random
);
93 output
+= (random
& mask
) - (dither
->random
& mask
);
95 dither
->random
= random
;
104 else if (output
< MIN
) {
115 dither
->error
[0] = sample
- output
;
118 return output
>> scalebits
;
121 #define INPUT_BUFFER_SIZE (5*8192)
122 #define OUTPUT_BUFFER_SIZE 8192 /* Must be an integer multiple of 4. */
123 void real_mpeg_play(char* fname
)
125 unsigned char InputBuffer
[INPUT_BUFFER_SIZE
],
126 OutputBuffer
[OUTPUT_BUFFER_SIZE
],
127 *OutputPtr
=OutputBuffer
;
128 const unsigned char *OutputBufferEnd
=OutputBuffer
+OUTPUT_BUFFER_SIZE
;
130 unsigned long FrameCount
=0;
133 static struct dither d0
, d1
;
136 mp3info(&mp3
, fname
, false); /* FIXME: honor the v1first setting */
140 /* Configure sound device for this file - always select Stereo because
141 some sound cards don't support mono */
142 config_sound(&sound
,mp3
.frequency
,2);
144 if ((fd
=open(fname
,O_RDONLY
)) < 0) {
145 fprintf(stderr
,"could not open %s\n",fname
);
149 /* First the structures used by libmad must be initialized. */
150 mad_stream_init(&Stream
);
151 mad_frame_init(&Frame
);
152 mad_synth_init(&Synth
);
153 mad_timer_reset(&Timer
);
156 if (Stream
.buffer
==NULL
|| Stream
.error
==MAD_ERROR_BUFLEN
) {
157 size_t ReadSize
,Remaining
;
158 unsigned char *ReadStart
;
160 if(Stream
.next_frame
!=NULL
) {
161 Remaining
=Stream
.bufend
-Stream
.next_frame
;
162 memmove(InputBuffer
,Stream
.next_frame
,Remaining
);
163 ReadStart
=InputBuffer
+Remaining
;
164 ReadSize
=INPUT_BUFFER_SIZE
-Remaining
;
166 ReadSize
=INPUT_BUFFER_SIZE
,
167 ReadStart
=InputBuffer
,
171 if ((int)(ReadSize
=read(fd
,ReadStart
,ReadSize
)) < 0) {
172 fprintf(stderr
,"end of input stream\n");
176 mad_stream_buffer(&Stream
,InputBuffer
,ReadSize
+Remaining
);
180 if(mad_frame_decode(&Frame
,&Stream
)) {
181 if(MAD_RECOVERABLE(Stream
.error
)) {
182 fprintf(stderr
,"recoverable frame level error\n");
186 if(Stream
.error
==MAD_ERROR_BUFLEN
) {
189 fprintf(stderr
,"unrecoverable frame level error\n");
197 mad_timer_add(&Timer
,Frame
.header
.duration
);
199 mad_synth_frame(&Synth
,&Frame
);
201 for(i
=0;i
<Synth
.pcm
.length
;i
++) {
202 unsigned short Sample
;
205 Sample
=scale(Synth
.pcm
.samples
[0][i
],&d0
);
206 *(OutputPtr
++)=Sample
&0xff;
207 *(OutputPtr
++)=Sample
>>8;
209 /* Right channel. If the decoded stream is monophonic then
210 * the right output channel is the same as the left one.
212 if(MAD_NCHANNELS(&Frame
.header
)==2) {
213 Sample
=scale(Synth
.pcm
.samples
[1][i
],&d1
);
216 *(OutputPtr
++)=Sample
&0xff;
217 *(OutputPtr
++)=Sample
>>8;
219 /* Flush the buffer if it is full. */
220 if (OutputPtr
==OutputBufferEnd
) {
221 if (output_sound(&sound
, OutputBuffer
,
222 OUTPUT_BUFFER_SIZE
)!=OUTPUT_BUFFER_SIZE
) {
223 fprintf(stderr
,"PCM write error.\n");
227 OutputPtr
=OutputBuffer
;
231 if ((key
=button_get(0))==BUTTON_STOP
)
238 /* Mad is no longer used, the structures that were initialized must
241 mad_synth_finish(&Synth
);
242 mad_frame_finish(&Frame
);
243 mad_stream_finish(&Stream
);
245 /* If the output buffer is not empty and no error occured during
246 * the last write, then flush it. */
247 if(OutputPtr
!=OutputBuffer
&& Status
!=2)
249 size_t BufferSize
=OutputPtr
-OutputBuffer
;
251 if (output_sound(&sound
, OutputPtr
, BufferSize
)!=(int)BufferSize
)
253 fprintf(stderr
,"PCM write error\n");
258 /* Accounting report if no error occured. */
263 mad_timer_string(Timer
,Buffer
,"%lu:%02lu.%03u",
264 MAD_UNITS_MINUTES
,MAD_UNITS_MILLISECONDS
,0);
265 fprintf(stderr
,"%lu frames decoded (%s).\n",FrameCount
,Buffer
);
269 /* That's the end of the world (in the H. G. Wells way). */
274 #endif /* HAVE_LIBMAD */
275 #endif /* HAVE_MPEG_PLAY */