diff options
author | Dave Chapman <dave@dchapman.com> | 2005-02-16 16:07:25 +0000 |
---|---|---|
committer | Dave Chapman <dave@dchapman.com> | 2005-02-16 16:07:25 +0000 |
commit | 711f763a127b5be80018c49db333841178103913 (patch) | |
tree | 000845d2828b49d632f805c6473fbb8578790eaa /apps/plugins | |
parent | a9b7109b6778fb90d8321f888b822e2a3085833c (diff) | |
download | rockbox-711f763a127b5be80018c49db333841178103913.tar.gz rockbox-711f763a127b5be80018c49db333841178103913.zip |
Code cleanup and change to use contents of xxx2wav.h (still more work to do)
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@5981 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/plugins')
-rw-r--r-- | apps/plugins/mpa2wav.c | 261 |
1 files changed, 31 insertions, 230 deletions
diff --git a/apps/plugins/mpa2wav.c b/apps/plugins/mpa2wav.c index 025cb82dcb..2f1f329275 100644 --- a/apps/plugins/mpa2wav.c +++ b/apps/plugins/mpa2wav.c | |||
@@ -24,24 +24,11 @@ | |||
24 | 24 | ||
25 | #include <codecs/libmad/mad.h> | 25 | #include <codecs/libmad/mad.h> |
26 | 26 | ||
27 | typedef struct ao_sample_format { | 27 | static struct plugin_api* rb; |
28 | int bits; /* bits per sample */ | 28 | |
29 | int rate; /* samples per second (in a single channel) */ | 29 | /* Helper functions common to all decoder test viewers (uses rb) */ |
30 | int channels; /* number of audio channels */ | ||
31 | int byte_format; /* Byte ordering in sample, see constants below */ | ||
32 | } ao_sample_format; | ||
33 | |||
34 | typedef struct { | ||
35 | int infile; | ||
36 | int outfile; | ||
37 | off_t curpos; | ||
38 | off_t filesize; | ||
39 | ao_sample_format samfmt; /* bits, rate, channels, byte_format */ | ||
40 | int framesize; | ||
41 | unsigned long total_samples; | ||
42 | unsigned long current_sample; | ||
43 | } file_info_struct; | ||
44 | 30 | ||
31 | #include "xxx2wav.h" | ||
45 | 32 | ||
46 | struct mad_stream Stream; | 33 | struct mad_stream Stream; |
47 | struct mad_frame Frame; | 34 | struct mad_frame Frame; |
@@ -49,81 +36,11 @@ struct mad_synth Synth; | |||
49 | mad_timer_t Timer; | 36 | mad_timer_t Timer; |
50 | struct dither d0, d1; | 37 | struct dither d0, d1; |
51 | 38 | ||
52 | file_info_struct file_info; | 39 | /* The following function is used inside libmad - let's hope it's never |
53 | 40 | called. | |
54 | #define MALLOC_BUFSIZE (512*1024) | 41 | */ |
55 | |||
56 | int mem_ptr; | ||
57 | int bufsize; | ||
58 | unsigned char* mp3buf; // The actual MP3 buffer from Rockbox | ||
59 | unsigned char* mallocbuf; // 512K from the start of MP3 buffer | ||
60 | unsigned char* filebuf; // The rest of the MP3 buffer | ||
61 | |||
62 | /* here is a global api struct pointer. while not strictly necessary, | ||
63 | it's nice not to have to pass the api pointer in all function calls | ||
64 | in the plugin */ | ||
65 | static struct plugin_api* rb; | ||
66 | |||
67 | void* malloc(size_t size) { | ||
68 | void* x; | ||
69 | char s[32]; | ||
70 | |||
71 | x=&mallocbuf[mem_ptr]; | ||
72 | mem_ptr+=size+(size%4); // Keep memory 32-bit aligned (if it was already?) | ||
73 | |||
74 | rb->snprintf(s,30,"Memory used: %d",mem_ptr); | ||
75 | rb->lcd_putsxy(0,80,s); | ||
76 | rb->lcd_update(); | ||
77 | return(x); | ||
78 | } | ||
79 | |||
80 | void* calloc(size_t nmemb, size_t size) { | ||
81 | void* x; | ||
82 | x=malloc(nmemb*size); | ||
83 | rb->memset(x,0,nmemb*size); | ||
84 | return(x); | ||
85 | } | ||
86 | |||
87 | void free(void* ptr) { | ||
88 | (void)ptr; | ||
89 | } | ||
90 | |||
91 | void* realloc(void* ptr, size_t size) { | ||
92 | void* x; | ||
93 | (void)ptr; | ||
94 | x=malloc(size); | ||
95 | return(x); | ||
96 | } | ||
97 | |||
98 | void *memcpy(void *dest, const void *src, size_t n) { | ||
99 | return(rb->memcpy(dest,src,n)); | ||
100 | } | ||
101 | |||
102 | void *memset(void *s, int c, size_t n) { | ||
103 | return(rb->memset(s,c,n)); | ||
104 | } | ||
105 | |||
106 | int memcmp(const void *s1, const void *s2, size_t n) { | ||
107 | return(rb->memcmp(s1,s2,n)); | ||
108 | } | ||
109 | |||
110 | void* memmove(const void *s1, const void *s2, size_t n) { | ||
111 | char* dest=(char*)s1; | ||
112 | char* src=(char*)s2; | ||
113 | size_t i; | ||
114 | |||
115 | for (i=0;i<n;i++) { dest[i]=src[i]; } | ||
116 | // while(n>0) { *(dest++)=*(src++); n--; } | ||
117 | return(dest); | ||
118 | } | ||
119 | |||
120 | void qsort(void *base, size_t nmemb, size_t size, int(*compar)(const void *, const void *)) { | ||
121 | rb->qsort(base,nmemb,size,compar); | ||
122 | } | ||
123 | |||
124 | 42 | ||
125 | void abort(void) { | 43 | void abort(void) { |
126 | /* Let's hope this is never called by libmad */ | ||
127 | } | 44 | } |
128 | 45 | ||
129 | /* The "dither" code to convert the 24-bit samples produced by libmad was | 46 | /* The "dither" code to convert the 24-bit samples produced by libmad was |
@@ -206,60 +123,6 @@ signed int dither(mad_fixed_t sample, struct dither *dither) | |||
206 | 123 | ||
207 | #define SHRT_MAX 32767 | 124 | #define SHRT_MAX 32767 |
208 | 125 | ||
209 | static unsigned char wav_header[44]={'R','I','F','F', // 0 - ChunkID | ||
210 | 0,0,0,0, // 4 - ChunkSize (filesize-8) | ||
211 | 'W','A','V','E', // 8 - Format | ||
212 | 'f','m','t',' ', // 12 - SubChunkID | ||
213 | 16,0,0,0, // 16 - SubChunk1ID // 16 for PCM | ||
214 | 1,0, // 20 - AudioFormat (1=16-bit) | ||
215 | 2,0, // 22 - NumChannels | ||
216 | 0,0,0,0, // 24 - SampleRate in Hz | ||
217 | 0,0,0,0, // 28 - Byte Rate (SampleRate*NumChannels*(BitsPerSample/8) | ||
218 | 4,0, // 32 - BlockAlign (== NumChannels * BitsPerSample/8) | ||
219 | 16,0, // 34 - BitsPerSample | ||
220 | 'd','a','t','a', // 36 - Subchunk2ID | ||
221 | 0,0,0,0 // 40 - Subchunk2Size | ||
222 | }; | ||
223 | |||
224 | void close_wav(file_info_struct* file_info) { | ||
225 | int x; | ||
226 | int filesize=rb->filesize(file_info->outfile); | ||
227 | |||
228 | /* We assume 16-bit, Stereo */ | ||
229 | |||
230 | rb->lseek(file_info->outfile,0,SEEK_SET); | ||
231 | |||
232 | // ChunkSize | ||
233 | x=filesize-8; | ||
234 | wav_header[4]=(x&0xff); | ||
235 | wav_header[5]=(x&0xff00)>>8; | ||
236 | wav_header[6]=(x&0xff0000)>>16; | ||
237 | wav_header[7]=(x&0xff000000)>>24; | ||
238 | |||
239 | // Samplerate | ||
240 | wav_header[24]=file_info->samfmt.rate&0xff; | ||
241 | wav_header[25]=(file_info->samfmt.rate&0xff00)>>8; | ||
242 | wav_header[26]=(file_info->samfmt.rate&0xff0000)>>16; | ||
243 | wav_header[27]=(file_info->samfmt.rate&0xff000000)>>24; | ||
244 | |||
245 | // ByteRate | ||
246 | x=file_info->samfmt.rate*4; | ||
247 | wav_header[28]=(x&0xff); | ||
248 | wav_header[29]=(x&0xff00)>>8; | ||
249 | wav_header[30]=(x&0xff0000)>>16; | ||
250 | wav_header[31]=(x&0xff000000)>>24; | ||
251 | |||
252 | // Subchunk2Size | ||
253 | x=filesize-44; | ||
254 | wav_header[40]=(x&0xff); | ||
255 | wav_header[41]=(x&0xff00)>>8; | ||
256 | wav_header[42]=(x&0xff0000)>>16; | ||
257 | wav_header[43]=(x&0xff000000)>>24; | ||
258 | |||
259 | rb->write(file_info->outfile,wav_header,sizeof(wav_header)); | ||
260 | rb->close(file_info->outfile); | ||
261 | } | ||
262 | |||
263 | #define INPUT_BUFFER_SIZE (5*8192) | 126 | #define INPUT_BUFFER_SIZE (5*8192) |
264 | #define OUTPUT_BUFFER_SIZE 8192 /* Must be an integer multiple of 4. */ | 127 | #define OUTPUT_BUFFER_SIZE 8192 /* Must be an integer multiple of 4. */ |
265 | 128 | ||
@@ -272,29 +135,23 @@ const unsigned char *OutputBufferEnd=OutputBuffer+OUTPUT_BUFFER_SIZE; | |||
272 | /* this is the plugin entry point */ | 135 | /* this is the plugin entry point */ |
273 | enum plugin_status plugin_start(struct plugin_api* api, void* file) | 136 | enum plugin_status plugin_start(struct plugin_api* api, void* file) |
274 | { | 137 | { |
275 | int i,n,bytesleft; | 138 | file_info_struct file_info; |
276 | char s[32]; | ||
277 | unsigned long ticks_taken; | ||
278 | unsigned long start_tick; | ||
279 | unsigned long long speed; | ||
280 | unsigned long xspeed; | ||
281 | long file_ptr; | ||
282 | |||
283 | int Status=0; | 139 | int Status=0; |
284 | unsigned long FrameCount=0; | 140 | unsigned short Sample; |
141 | int i; | ||
142 | size_t ReadSize, Remaining; | ||
143 | unsigned char *ReadStart; | ||
285 | 144 | ||
286 | TEST_PLUGIN_API(api); | 145 | /* Generic plugin inititialisation */ |
287 | 146 | ||
147 | TEST_PLUGIN_API(api); | ||
288 | rb = api; | 148 | rb = api; |
289 | 149 | ||
290 | mem_ptr=0; | 150 | /* This function sets up the buffers and reads the file into RAM */ |
291 | mp3buf=rb->plugin_get_mp3_buffer(&bufsize); | ||
292 | mallocbuf=mp3buf; | ||
293 | filebuf=&mp3buf[MALLOC_BUFSIZE]; | ||
294 | 151 | ||
295 | rb->snprintf(s,32,"mp3 bufsize: %d",bufsize); | 152 | if (local_init(file,"/libmadtest.wav",&file_info)) { |
296 | rb->lcd_putsxy(0,100,s); | 153 | return PLUGIN_ERROR; |
297 | rb->lcd_update(); | 154 | } |
298 | 155 | ||
299 | /* Create a decoder instance */ | 156 | /* Create a decoder instance */ |
300 | 157 | ||
@@ -305,51 +162,14 @@ enum plugin_status plugin_start(struct plugin_api* api, void* file) | |||
305 | 162 | ||
306 | //if error: return PLUGIN_ERROR; | 163 | //if error: return PLUGIN_ERROR; |
307 | 164 | ||
308 | file_info.infile=rb->open(file,O_RDONLY); | ||
309 | file_info.outfile=rb->creat("/libmadtest.wav",O_WRONLY); | ||
310 | rb->write(file_info.outfile,wav_header,sizeof(wav_header)); | ||
311 | file_info.curpos=0; | 165 | file_info.curpos=0; |
312 | file_info.filesize=rb->filesize(file_info.infile); | 166 | file_info.start_tick=*(rb->current_tick); |
313 | |||
314 | if (file_info.filesize > (bufsize-512*1024)) { | ||
315 | rb->close(file_info.infile); | ||
316 | rb->splash(HZ*2, true, "File too large"); | ||
317 | return PLUGIN_ERROR; | ||
318 | } | ||
319 | |||
320 | rb->snprintf(s,32,"Loading file..."); | ||
321 | rb->lcd_putsxy(0,0,s); | ||
322 | rb->lcd_update(); | ||
323 | |||
324 | bytesleft=file_info.filesize; | ||
325 | i=0; | ||
326 | while (bytesleft > 0) { | ||
327 | n=rb->read(file_info.infile,&filebuf[i],bytesleft); | ||
328 | if (n < 0) { | ||
329 | rb->close(file_info.infile); | ||
330 | rb->splash(HZ*2, true, "ERROR READING FILE"); | ||
331 | return PLUGIN_ERROR; | ||
332 | } | ||
333 | n+=i; bytesleft-=n; | ||
334 | } | ||
335 | rb->close(file_info.infile); | ||
336 | |||
337 | mad_stream_init(&Stream); | ||
338 | mad_frame_init(&Frame); | ||
339 | mad_synth_init(&Synth); | ||
340 | mad_timer_reset(&Timer); | ||
341 | |||
342 | file_ptr=0; | ||
343 | start_tick=*(rb->current_tick); | ||
344 | 167 | ||
345 | rb->button_clear_queue(); | 168 | rb->button_clear_queue(); |
346 | 169 | ||
347 | /* This is the decoding loop. */ | 170 | /* This is the decoding loop. */ |
348 | while (file_ptr < file_info.filesize) { | 171 | while (file_info.curpos < file_info.filesize) { |
349 | if(Stream.buffer==NULL || Stream.error==MAD_ERROR_BUFLEN) { | 172 | if(Stream.buffer==NULL || Stream.error==MAD_ERROR_BUFLEN) { |
350 | size_t ReadSize, Remaining; | ||
351 | unsigned char *ReadStart; | ||
352 | |||
353 | if(Stream.next_frame!=NULL) { | 173 | if(Stream.next_frame!=NULL) { |
354 | Remaining=Stream.bufend-Stream.next_frame; | 174 | Remaining=Stream.bufend-Stream.next_frame; |
355 | memmove(InputBuffer,Stream.next_frame,Remaining); | 175 | memmove(InputBuffer,Stream.next_frame,Remaining); |
@@ -367,22 +187,20 @@ enum plugin_status plugin_start(struct plugin_api* api, void* file) | |||
367 | * left untouched. | 187 | * left untouched. |
368 | */ | 188 | */ |
369 | 189 | ||
370 | if ((file_info.filesize-file_ptr) < (int) ReadSize) { | 190 | if ((file_info.filesize-file_info.curpos) < (int) ReadSize) { |
371 | ReadSize=file_info.filesize-file_ptr; | 191 | ReadSize=file_info.filesize-file_info.curpos; |
372 | } | 192 | } |
373 | memcpy(ReadStart,&filebuf[file_ptr],ReadSize); | 193 | memcpy(ReadStart,&filebuf[file_info.curpos],ReadSize); |
374 | file_ptr+=ReadSize; | 194 | file_info.curpos+=ReadSize; |
375 | 195 | ||
376 | if (file_ptr >= file_info.filesize) | 196 | if (file_info.curpos >= file_info.filesize) |
377 | { | 197 | { |
378 | GuardPtr=ReadStart+ReadSize; | 198 | GuardPtr=ReadStart+ReadSize; |
379 | memset(GuardPtr,0,MAD_BUFFER_GUARD); | 199 | memset(GuardPtr,0,MAD_BUFFER_GUARD); |
380 | ReadSize+=MAD_BUFFER_GUARD; | 200 | ReadSize+=MAD_BUFFER_GUARD; |
381 | } | 201 | } |
382 | 202 | ||
383 | /* Pipe the new buffer content to libmad's stream decoder | 203 | /* Pipe the new buffer content to libmad's stream decoder facility */ |
384 | * facility. | ||
385 | */ | ||
386 | mad_stream_buffer(&Stream,InputBuffer,ReadSize+Remaining); | 204 | mad_stream_buffer(&Stream,InputBuffer,ReadSize+Remaining); |
387 | Stream.error=0; | 205 | Stream.error=0; |
388 | } | 206 | } |
@@ -410,11 +228,12 @@ enum plugin_status plugin_start(struct plugin_api* api, void* file) | |||
410 | } | 228 | } |
411 | 229 | ||
412 | /* We assume all frames have same samplerate as the first */ | 230 | /* We assume all frames have same samplerate as the first */ |
413 | if(FrameCount==0) { | 231 | if(file_info.frames_decoded==0) { |
414 | file_info.samfmt.rate=Frame.header.samplerate; | 232 | file_info.samplerate=Frame.header.samplerate; |
415 | } | 233 | } |
416 | 234 | ||
417 | FrameCount++; | 235 | file_info.frames_decoded++; |
236 | |||
418 | /* ?? Do we need the timer module? */ | 237 | /* ?? Do we need the timer module? */ |
419 | mad_timer_add(&Timer,Frame.header.duration); | 238 | mad_timer_add(&Timer,Frame.header.duration); |
420 | 239 | ||
@@ -427,8 +246,6 @@ enum plugin_status plugin_start(struct plugin_api* api, void* file) | |||
427 | /* Convert MAD's numbers to an array of 16-bit LE signed integers */ | 246 | /* Convert MAD's numbers to an array of 16-bit LE signed integers */ |
428 | for(i=0;i<Synth.pcm.length;i++) | 247 | for(i=0;i<Synth.pcm.length;i++) |
429 | { | 248 | { |
430 | unsigned short Sample; | ||
431 | |||
432 | /* Left channel */ | 249 | /* Left channel */ |
433 | Sample=scale(Synth.pcm.samples[0][i],&d0); | 250 | Sample=scale(Synth.pcm.samples[0][i],&d0); |
434 | *(OutputPtr++)=Sample&0xff; | 251 | *(OutputPtr++)=Sample&0xff; |
@@ -450,26 +267,10 @@ enum plugin_status plugin_start(struct plugin_api* api, void* file) | |||
450 | } | 267 | } |
451 | } | 268 | } |
452 | 269 | ||
453 | rb->snprintf(s,32,"Bytes Read: %d ",file_ptr); | ||
454 | rb->lcd_putsxy(0,0,s); | ||
455 | |||
456 | rb->snprintf(s,32,"Samples Decoded: %d",file_info.current_sample); | ||
457 | rb->lcd_putsxy(0,20,s); | ||
458 | rb->snprintf(s,32,"Frames Decoded: %d",FrameCount); | ||
459 | rb->lcd_putsxy(0,40,s); | ||
460 | |||
461 | file_info.current_sample+=Synth.pcm.length; | 270 | file_info.current_sample+=Synth.pcm.length; |
462 | 271 | ||
463 | ticks_taken=*(rb->current_tick)-start_tick; | 272 | display_status(&file_info); |
464 | |||
465 | if (ticks_taken==0) { ticks_taken=1; } // Avoid fp exception. | ||
466 | |||
467 | speed=(100*file_info.current_sample)/file_info.samfmt.rate; | ||
468 | xspeed=(speed*10000)/ticks_taken; | ||
469 | rb->snprintf(s,32,"Speed %ld.%02ld%% Secs: %d",(xspeed/100),(xspeed%100),ticks_taken/100); | ||
470 | rb->lcd_putsxy(0,60,s); | ||
471 | 273 | ||
472 | rb->lcd_update(); | ||
473 | if (rb->button_get(false)!=BUTTON_NONE) { | 274 | if (rb->button_get(false)!=BUTTON_NONE) { |
474 | close_wav(&file_info); | 275 | close_wav(&file_info); |
475 | return PLUGIN_OK; | 276 | return PLUGIN_OK; |