diff options
Diffstat (limited to 'uisimulator/common')
-rw-r--r-- | uisimulator/common/mpegplay.c | 269 | ||||
-rw-r--r-- | uisimulator/common/mpegplay.h | 2 |
2 files changed, 131 insertions, 140 deletions
diff --git a/uisimulator/common/mpegplay.c b/uisimulator/common/mpegplay.c index 09799ad176..f48fc699f6 100644 --- a/uisimulator/common/mpegplay.c +++ b/uisimulator/common/mpegplay.c | |||
@@ -119,160 +119,151 @@ signed int dither(mad_fixed_t sample, struct dither *dither) | |||
119 | 119 | ||
120 | #define INPUT_BUFFER_SIZE (5*8192) | 120 | #define INPUT_BUFFER_SIZE (5*8192) |
121 | #define OUTPUT_BUFFER_SIZE 8192 /* Must be an integer multiple of 4. */ | 121 | #define OUTPUT_BUFFER_SIZE 8192 /* Must be an integer multiple of 4. */ |
122 | int mpeg_play(char* fname) | 122 | void mpeg_play(char* fname) |
123 | { | 123 | { |
124 | unsigned char InputBuffer[INPUT_BUFFER_SIZE], | 124 | unsigned char InputBuffer[INPUT_BUFFER_SIZE], |
125 | OutputBuffer[OUTPUT_BUFFER_SIZE], | 125 | OutputBuffer[OUTPUT_BUFFER_SIZE], |
126 | *OutputPtr=OutputBuffer; | 126 | *OutputPtr=OutputBuffer; |
127 | const unsigned char *OutputBufferEnd=OutputBuffer+OUTPUT_BUFFER_SIZE; | 127 | const unsigned char *OutputBufferEnd=OutputBuffer+OUTPUT_BUFFER_SIZE; |
128 | int Status=0, | 128 | int Status=0, i, fd; |
129 | i; | 129 | unsigned long FrameCount=0; |
130 | unsigned long FrameCount=0; | 130 | sound_t sound; |
131 | sound_t sound; | 131 | mp3entry mp3; |
132 | int fd; | 132 | register signed int s0, s1; |
133 | mp3entry mp3; | 133 | static struct dither d0, d1; |
134 | register signed int s0, s1; | ||
135 | static struct dither d0, d1; | ||
136 | 134 | ||
137 | mp3info(&mp3, fname); | 135 | mp3info(&mp3, fname); |
138 | 136 | ||
139 | init_sound(&sound); | 137 | init_sound(&sound); |
140 | 138 | ||
141 | /* Configure sound device for this file - always select Stereo because | 139 | /* Configure sound device for this file - always select Stereo because |
142 | some sound cards don't support mono */ | 140 | some sound cards don't support mono */ |
143 | config_sound(&sound,mp3.frequency,2); | 141 | config_sound(&sound,mp3.frequency,2); |
144 | 142 | ||
145 | fd=open(fname,O_RDONLY); | 143 | if ((fd=open(fname,O_RDONLY)) < 0) { |
146 | if (fd < 0) { | 144 | fprintf(stderr,"could not open %s\n",fname); |
147 | fprintf(stderr,"could not open %s\n",fname); | 145 | return; |
148 | return 0; | ||
149 | } | ||
150 | |||
151 | /* First the structures used by libmad must be initialized. */ | ||
152 | mad_stream_init(&Stream); | ||
153 | mad_frame_init(&Frame); | ||
154 | mad_synth_init(&Synth); | ||
155 | mad_timer_reset(&Timer); | ||
156 | |||
157 | do | ||
158 | { | ||
159 | if (button_get()) break; /* Return if a key is pressed */ | ||
160 | |||
161 | if(Stream.buffer==NULL || Stream.error==MAD_ERROR_BUFLEN) | ||
162 | { | ||
163 | size_t ReadSize,Remaining; | ||
164 | unsigned char *ReadStart; | ||
165 | |||
166 | if(Stream.next_frame!=NULL) | ||
167 | { | ||
168 | Remaining=Stream.bufend-Stream.next_frame; | ||
169 | memmove(InputBuffer,Stream.next_frame,Remaining); | ||
170 | ReadStart=InputBuffer+Remaining; | ||
171 | ReadSize=INPUT_BUFFER_SIZE-Remaining; | ||
172 | } | ||
173 | else | ||
174 | ReadSize=INPUT_BUFFER_SIZE, | ||
175 | ReadStart=InputBuffer, | ||
176 | Remaining=0; | ||
177 | |||
178 | ReadSize=read(fd,ReadStart,ReadSize); | ||
179 | if(ReadSize<=0) | ||
180 | { | ||
181 | fprintf(stderr,"end of input stream\n"); | ||
182 | break; | ||
183 | } | ||
184 | |||
185 | mad_stream_buffer(&Stream,InputBuffer,ReadSize+Remaining); | ||
186 | Stream.error=0; | ||
187 | } | 146 | } |
188 | 147 | ||
189 | if(mad_frame_decode(&Frame,&Stream)) { | 148 | /* First the structures used by libmad must be initialized. */ |
190 | if(MAD_RECOVERABLE(Stream.error)) | 149 | mad_stream_init(&Stream); |
191 | { | 150 | mad_frame_init(&Frame); |
192 | fprintf(stderr,"recoverable frame level error\n"); | 151 | mad_synth_init(&Synth); |
193 | fflush(stderr); | 152 | mad_timer_reset(&Timer); |
194 | continue; | 153 | |
195 | } | 154 | do { |
196 | else | 155 | if (button_get()) |
197 | if(Stream.error==MAD_ERROR_BUFLEN) { | 156 | break; |
198 | continue; | 157 | |
199 | } else { | 158 | if (Stream.buffer==NULL || Stream.error==MAD_ERROR_BUFLEN) { |
200 | fprintf(stderr,"unrecoverable frame level error\n"); | 159 | size_t ReadSize,Remaining; |
201 | Status=1; | 160 | unsigned char *ReadStart; |
202 | break; | 161 | |
162 | if(Stream.next_frame!=NULL) { | ||
163 | Remaining=Stream.bufend-Stream.next_frame; | ||
164 | memmove(InputBuffer,Stream.next_frame,Remaining); | ||
165 | ReadStart=InputBuffer+Remaining; | ||
166 | ReadSize=INPUT_BUFFER_SIZE-Remaining; | ||
167 | } else { | ||
168 | ReadSize=INPUT_BUFFER_SIZE, | ||
169 | ReadStart=InputBuffer, | ||
170 | Remaining=0; | ||
171 | } | ||
172 | |||
173 | if ((ReadSize=read(fd,ReadStart,ReadSize)) < 0) { | ||
174 | fprintf(stderr,"end of input stream\n"); | ||
175 | break; | ||
176 | } | ||
177 | |||
178 | mad_stream_buffer(&Stream,InputBuffer,ReadSize+Remaining); | ||
179 | Stream.error=0; | ||
203 | } | 180 | } |
204 | } | ||
205 | 181 | ||
206 | FrameCount++; | 182 | if(mad_frame_decode(&Frame,&Stream)) { |
207 | mad_timer_add(&Timer,Frame.header.duration); | 183 | if(MAD_RECOVERABLE(Stream.error)) { |
208 | 184 | fprintf(stderr,"recoverable frame level error\n"); | |
209 | mad_synth_frame(&Synth,&Frame); | 185 | fflush(stderr); |
210 | 186 | continue; | |
211 | for(i=0;i<Synth.pcm.length;i++) | 187 | } else { |
212 | { | 188 | if(Stream.error==MAD_ERROR_BUFLEN) { |
213 | unsigned short Sample; | 189 | continue; |
214 | 190 | } else { | |
215 | /* Left channel */ | 191 | fprintf(stderr,"unrecoverable frame level error\n"); |
216 | Sample=scale(Synth.pcm.samples[0][i],&d0); | 192 | Status=1; |
217 | *(OutputPtr++)=Sample&0xff; | 193 | break; |
218 | *(OutputPtr++)=Sample>>8; | 194 | } |
219 | 195 | } | |
220 | /* Right channel. If the decoded stream is monophonic then | ||
221 | * the right output channel is the same as the left one. | ||
222 | */ | ||
223 | if(MAD_NCHANNELS(&Frame.header)==2) | ||
224 | Sample=scale(Synth.pcm.samples[1][i],&d1); | ||
225 | *(OutputPtr++)=Sample&0xff; | ||
226 | *(OutputPtr++)=Sample>>8; | ||
227 | |||
228 | /* Flush the buffer if it is full. */ | ||
229 | if(OutputPtr==OutputBufferEnd) | ||
230 | { | ||
231 | if(output_sound(&sound,OutputBuffer,OUTPUT_BUFFER_SIZE)!=OUTPUT_BUFFER_SIZE) | ||
232 | { | ||
233 | fprintf(stderr,"PCM write error.\n"); | ||
234 | Status=2; | ||
235 | break; | ||
236 | } | 196 | } |
237 | OutputPtr=OutputBuffer; | ||
238 | } | ||
239 | } | ||
240 | }while(1); | ||
241 | 197 | ||
242 | /* Mad is no longer used, the structures that were initialized must | 198 | FrameCount++; |
199 | mad_timer_add(&Timer,Frame.header.duration); | ||
200 | |||
201 | mad_synth_frame(&Synth,&Frame); | ||
202 | |||
203 | for(i=0;i<Synth.pcm.length;i++) { | ||
204 | unsigned short Sample; | ||
205 | |||
206 | /* Left channel */ | ||
207 | Sample=scale(Synth.pcm.samples[0][i],&d0); | ||
208 | *(OutputPtr++)=Sample&0xff; | ||
209 | *(OutputPtr++)=Sample>>8; | ||
210 | |||
211 | /* Right channel. If the decoded stream is monophonic then | ||
212 | * the right output channel is the same as the left one. | ||
213 | */ | ||
214 | if(MAD_NCHANNELS(&Frame.header)==2) { | ||
215 | Sample=scale(Synth.pcm.samples[1][i],&d1); | ||
216 | } | ||
217 | |||
218 | *(OutputPtr++)=Sample&0xff; | ||
219 | *(OutputPtr++)=Sample>>8; | ||
220 | |||
221 | /* Flush the buffer if it is full. */ | ||
222 | if (OutputPtr==OutputBufferEnd) { | ||
223 | if (output_sound(&sound, OutputBuffer, | ||
224 | OUTPUT_BUFFER_SIZE)!=OUTPUT_BUFFER_SIZE) { | ||
225 | fprintf(stderr,"PCM write error.\n"); | ||
226 | Status=2; | ||
227 | break; | ||
228 | } | ||
229 | OutputPtr=OutputBuffer; | ||
230 | } | ||
231 | } | ||
232 | }while(1); | ||
233 | |||
234 | /* Mad is no longer used, the structures that were initialized must | ||
243 | * now be cleared. | 235 | * now be cleared. |
244 | */ | 236 | */ |
245 | mad_synth_finish(&Synth); | 237 | mad_synth_finish(&Synth); |
246 | mad_frame_finish(&Frame); | 238 | mad_frame_finish(&Frame); |
247 | mad_stream_finish(&Stream); | 239 | mad_stream_finish(&Stream); |
248 | 240 | ||
249 | /* If the output buffer is not empty and no error occured during | 241 | /* If the output buffer is not empty and no error occured during |
250 | * the last write, then flush it. | 242 | * the last write, then flush it. */ |
251 | */ | 243 | if(OutputPtr!=OutputBuffer && Status!=2) |
252 | if(OutputPtr!=OutputBuffer && Status!=2) | 244 | { |
253 | { | 245 | size_t BufferSize=OutputPtr-OutputBuffer; |
254 | size_t BufferSize=OutputPtr-OutputBuffer; | ||
255 | |||
256 | if(write(sound,OutputBuffer,1,BufferSize)!=BufferSize) | ||
257 | { | ||
258 | fprintf(stderr,"PCM write error\n"); | ||
259 | Status=2; | ||
260 | } | ||
261 | } | ||
262 | 246 | ||
263 | /* Accounting report if no error occured. */ | 247 | if(write(sound,OutputBuffer,1,BufferSize)!=BufferSize) |
264 | if(!Status) | 248 | { |
265 | { | 249 | fprintf(stderr,"PCM write error\n"); |
266 | char Buffer[80]; | 250 | Status=2; |
251 | } | ||
252 | } | ||
267 | 253 | ||
268 | mad_timer_string(Timer,Buffer,"%lu:%02lu.%03u", | 254 | /* Accounting report if no error occured. */ |
269 | MAD_UNITS_MINUTES,MAD_UNITS_MILLISECONDS,0); | 255 | if(!Status) |
270 | fprintf(stderr,"%lu frames decoded (%s).\n",FrameCount,Buffer); | 256 | { |
271 | } | 257 | char Buffer[80]; |
258 | |||
259 | mad_timer_string(Timer,Buffer,"%lu:%02lu.%03u", | ||
260 | MAD_UNITS_MINUTES,MAD_UNITS_MILLISECONDS,0); | ||
261 | fprintf(stderr,"%lu frames decoded (%s).\n",FrameCount,Buffer); | ||
262 | } | ||
272 | 263 | ||
273 | close_sound(&sound); | 264 | close_sound(&sound); |
274 | /* That's the end of the world (in the H. G. Wells way). */ | 265 | /* That's the end of the world (in the H. G. Wells way). */ |
275 | return(Status); | 266 | return; |
276 | } | 267 | } |
277 | 268 | ||
278 | 269 | ||
diff --git a/uisimulator/common/mpegplay.h b/uisimulator/common/mpegplay.h index cde9fe183f..d0c100c45b 100644 --- a/uisimulator/common/mpegplay.h +++ b/uisimulator/common/mpegplay.h | |||
@@ -18,6 +18,6 @@ | |||
18 | 18 | ||
19 | #ifdef MPEG_PLAY | 19 | #ifdef MPEG_PLAY |
20 | 20 | ||
21 | int mpeg_play(char* fname); | 21 | void mpeg_play(char* fname); |
22 | 22 | ||
23 | #endif | 23 | #endif |