summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--uisimulator/common/mpegplay.c269
-rw-r--r--uisimulator/common/mpegplay.h2
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. */
122int mpeg_play(char* fname) 122void 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
21int mpeg_play(char* fname); 21void mpeg_play(char* fname);
22 22
23#endif 23#endif