diff options
Diffstat (limited to 'uisimulator/x11')
-rw-r--r-- | uisimulator/x11/Makefile | 8 | ||||
-rw-r--r-- | uisimulator/x11/mpegplay.c | 232 | ||||
-rw-r--r-- | uisimulator/x11/mpegplay.h | 23 |
3 files changed, 262 insertions, 1 deletions
diff --git a/uisimulator/x11/Makefile b/uisimulator/x11/Makefile index 9753394456..7cc8b088c3 100644 --- a/uisimulator/x11/Makefile +++ b/uisimulator/x11/Makefile | |||
@@ -57,6 +57,12 @@ APPS = tetris.c screensaver.c tree.c app.c play.c menu.c icons.c | |||
57 | SRCS = screenhack.c uibasic.c resources.c visual.c lcd-x11.c \ | 57 | SRCS = screenhack.c uibasic.c resources.c visual.c lcd-x11.c \ |
58 | button-x11.c io.c sleep.c $(APPS) $(FIRMSRCS) | 58 | button-x11.c io.c sleep.c $(APPS) $(FIRMSRCS) |
59 | 59 | ||
60 | ifdef MPEG_PLAY | ||
61 | SRCS += mpegplay.c | ||
62 | DEFINES += -DMPEG_PLAY | ||
63 | LIBS = -lmad | ||
64 | endif | ||
65 | |||
60 | OBJS := $(SRCS:c=o) | 66 | OBJS := $(SRCS:c=o) |
61 | 67 | ||
62 | all: $(TARGET) | 68 | all: $(TARGET) |
@@ -108,7 +114,7 @@ sprintf.o: $(COMMON)/sprintf.c | |||
108 | $(CC) $(CFLAGS) -c $< | 114 | $(CC) $(CFLAGS) -c $< |
109 | 115 | ||
110 | $(TARGET): $(OBJS) | 116 | $(TARGET): $(OBJS) |
111 | $(CC) -g -o $(TARGET) $(LIBDIRS) $(LDFLAGS) $(OBJS) | 117 | $(CC) -g -o $(TARGET) $(LIBDIRS) $(LDFLAGS) $(OBJS) $(LIBS) |
112 | 118 | ||
113 | DEPS:=.deps | 119 | DEPS:=.deps |
114 | 120 | ||
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 | |||
36 | struct mad_stream Stream; | ||
37 | struct mad_frame Frame; | ||
38 | struct mad_synth Synth; | ||
39 | mad_timer_t Timer; | ||
40 | int sound; | ||
41 | |||
42 | void 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 | |||
65 | unsigned 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. */ | ||
73 | int 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 | ||
diff --git a/uisimulator/x11/mpegplay.h b/uisimulator/x11/mpegplay.h new file mode 100644 index 0000000000..cde9fe183f --- /dev/null +++ b/uisimulator/x11/mpegplay.h | |||
@@ -0,0 +1,23 @@ | |||
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 | int mpeg_play(char* fname); | ||
22 | |||
23 | #endif | ||