summaryrefslogtreecommitdiff
path: root/uisimulator/x11/mpegplay.c
diff options
context:
space:
mode:
Diffstat (limited to 'uisimulator/x11/mpegplay.c')
-rw-r--r--uisimulator/x11/mpegplay.c232
1 files changed, 232 insertions, 0 deletions
diff --git a/uisimulator/x11/mpegplay.c b/uisimulator/x11/mpegplay.c
new file mode 100644
index 0000000000..2d31c073dd
--- /dev/null
+++ b/uisimulator/x11/mpegplay.c
@@ -0,0 +1,232 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2002 Dave Chapman
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18
19#ifdef MPEG_PLAY
20
21#include <string.h>
22#include <stdlib.h>
23#include <file.h>
24#include <types.h>
25#include <lcd.h>
26#include <button.h>
27#include "id3.h"
28
29#include <stdio.h>
30#include <mad.h>
31#include <linux/soundcard.h>
32
33/* We want to use the "real" open in some cases */
34#undef open
35
36struct mad_stream Stream;
37struct mad_frame Frame;
38struct mad_synth Synth;
39mad_timer_t Timer;
40int sound;
41
42void init_oss(int sound, int sound_freq, int channels) {
43 int format=AFMT_U16_LE;
44 int setting=0x000C000D; // 12 fragments size 8kb ? WHAT IS THIS?
45
46 if (ioctl(sound,SNDCTL_DSP_SETFRAGMENT,&setting)==-1) {
47 perror("SNDCTL_DSP_SETFRAGMENT");
48 }
49
50 if (ioctl(sound,SNDCTL_DSP_STEREO,&channels)==-1) {
51 perror("SNDCTL_DSP_STEREO");
52 }
53 if (channels==0) { fprintf(stderr,"Warning, only mono supported\n"); }
54
55 if (ioctl(sound,SNDCTL_DSP_SETFMT,&format)==-1) {
56 perror("SNDCTL_DSP_SETFMT");
57 }
58
59 fprintf(stderr,"SETTING /dev/dsp to %dHz\n",sound_freq);
60 if (ioctl(sound,SNDCTL_DSP_SPEED,&sound_freq)==-1) {
61 perror("SNDCTL_DSP_SPEED");
62 }
63}
64
65unsigned short MadFixedToUshort(mad_fixed_t Fixed)
66{
67 Fixed=Fixed>>(MAD_F_FRACBITS-15);
68 return((unsigned short)Fixed);
69}
70
71#define INPUT_BUFFER_SIZE (5*8192)
72#define OUTPUT_BUFFER_SIZE 8192 /* Must be an integer multiple of 4. */
73int mpeg_play(char* fname)
74{
75 unsigned char InputBuffer[INPUT_BUFFER_SIZE],
76 OutputBuffer[OUTPUT_BUFFER_SIZE],
77 *OutputPtr=OutputBuffer;
78 const unsigned char *OutputBufferEnd=OutputBuffer+OUTPUT_BUFFER_SIZE;
79 int Status=0,
80 i;
81 unsigned long FrameCount=0;
82 int sound,fd;
83 mp3entry mp3;
84
85 mp3info(&mp3, fname);
86
87 #undef open
88 sound=open("/dev/dsp", O_WRONLY);
89
90 if (sound < 0) {
91 fprintf(stderr,"Can not open /dev/dsp - Aborting - sound=%d\n",sound);
92 exit(-1);
93 }
94
95 init_oss(sound,mp3.frequency,2);
96
97 fd=x11_open(fname,O_RDONLY);
98 if (fd < 0) {
99 fprintf(stderr,"could not open %s\n",fname);
100 return 0;
101 }
102
103 /* First the structures used by libmad must be initialized. */
104 mad_stream_init(&Stream);
105 mad_frame_init(&Frame);
106 mad_synth_init(&Synth);
107 mad_timer_reset(&Timer);
108
109 do
110 {
111 if (button_get()) break; /* Return if a key is pressed */
112
113 if(Stream.buffer==NULL || Stream.error==MAD_ERROR_BUFLEN)
114 {
115 size_t ReadSize,Remaining;
116 unsigned char *ReadStart;
117
118 if(Stream.next_frame!=NULL)
119 {
120 Remaining=Stream.bufend-Stream.next_frame;
121 memmove(InputBuffer,Stream.next_frame,Remaining);
122 ReadStart=InputBuffer+Remaining;
123 ReadSize=INPUT_BUFFER_SIZE-Remaining;
124 }
125 else
126 ReadSize=INPUT_BUFFER_SIZE,
127 ReadStart=InputBuffer,
128 Remaining=0;
129
130 ReadSize=read(fd,ReadStart,ReadSize);
131 if(ReadSize<=0)
132 {
133 fprintf(stderr,"end of input stream\n");
134 break;
135 }
136
137 mad_stream_buffer(&Stream,InputBuffer,ReadSize+Remaining);
138 Stream.error=0;
139 }
140
141 if(mad_frame_decode(&Frame,&Stream)) {
142 if(MAD_RECOVERABLE(Stream.error))
143 {
144 fprintf(stderr,"recoverable frame level error\n");
145 fflush(stderr);
146 continue;
147 }
148 else
149 if(Stream.error==MAD_ERROR_BUFLEN) {
150 continue;
151 } else {
152 fprintf(stderr,"unrecoverable frame level error\n");
153 Status=1;
154 break;
155 }
156 }
157
158 FrameCount++;
159 mad_timer_add(&Timer,Frame.header.duration);
160
161 mad_synth_frame(&Synth,&Frame);
162
163 for(i=0;i<Synth.pcm.length;i++)
164 {
165 unsigned short Sample;
166
167 /* Left channel */
168 Sample=MadFixedToUshort(Synth.pcm.samples[0][i]);
169 *(OutputPtr++)=Sample&0xff;
170 *(OutputPtr++)=Sample>>8;
171
172 /* Right channel. If the decoded stream is monophonic then
173 * the right output channel is the same as the left one.
174 */
175 if(MAD_NCHANNELS(&Frame.header)==2)
176 Sample=MadFixedToUshort(Synth.pcm.samples[1][i]);
177 *(OutputPtr++)=Sample&0xff;
178 *(OutputPtr++)=Sample>>8;
179
180 /* Flush the buffer if it is full. */
181 if(OutputPtr==OutputBufferEnd)
182 {
183 if(write(sound,OutputBuffer,OUTPUT_BUFFER_SIZE)!=OUTPUT_BUFFER_SIZE)
184 {
185 fprintf(stderr,"PCM write error.\n");
186 Status=2;
187 break;
188 }
189 OutputPtr=OutputBuffer;
190 }
191 }
192 }while(1);
193
194 fprintf(stderr,"END OF MAD LOOP\n");
195 /* Mad is no longer used, the structures that were initialized must
196 * now be cleared.
197 */
198 mad_synth_finish(&Synth);
199 mad_frame_finish(&Frame);
200 mad_stream_finish(&Stream);
201
202 /* If the output buffer is not empty and no error occured during
203 * the last write, then flush it.
204 */
205 if(OutputPtr!=OutputBuffer && Status!=2)
206 {
207 size_t BufferSize=OutputPtr-OutputBuffer;
208
209 if(write(sound,OutputBuffer,1,BufferSize)!=BufferSize)
210 {
211 fprintf(stderr,"PCM write error\n");
212 Status=2;
213 }
214 }
215
216 /* Accounting report if no error occured. */
217 if(!Status)
218 {
219 char Buffer[80];
220
221 mad_timer_string(Timer,Buffer,"%lu:%02lu.%03u",
222 MAD_UNITS_MINUTES,MAD_UNITS_MILLISECONDS,0);
223 fprintf(stderr,"%lu frames decoded (%s).\n",FrameCount,Buffer);
224 }
225
226 close(sound);
227 /* That's the end of the world (in the H. G. Wells way). */
228 return(Status);
229}
230
231
232#endif