summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNils Wallménius <nils@rockbox.org>2009-11-22 18:48:07 +0000
committerNils Wallménius <nils@rockbox.org>2009-11-22 18:48:07 +0000
commit4279c9f4aa871fc2bed08c66d1ad0580068d5140 (patch)
treeb2977d0bce92742bc7266e0d4a32364a3cb15af1
parent1832def9b0b52b2a3385f9672aacc35dde9c389a (diff)
downloadrockbox-4279c9f4aa871fc2bed08c66d1ad0580068d5140.tar.gz
rockbox-4279c9f4aa871fc2bed08c66d1ad0580068d5140.zip
Give test_codec the ability to checksum files or folders of files, usefull to verify output integrity.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@23711 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/plugin.c1
-rw-r--r--apps/plugin.h4
-rw-r--r--apps/plugins/test_codec.c314
3 files changed, 226 insertions, 93 deletions
diff --git a/apps/plugin.c b/apps/plugin.c
index f59e42e222..cc208e7500 100644
--- a/apps/plugin.c
+++ b/apps/plugin.c
@@ -675,6 +675,7 @@ static const struct plugin_api rockbox_api = {
675#if (CONFIG_CODEC == SWCODEC) 675#if (CONFIG_CODEC == SWCODEC)
676 pcmbuf_beep, 676 pcmbuf_beep,
677#endif 677#endif
678 crc_32,
678}; 679};
679 680
680int plugin_load(const char* plugin, const void* parameter) 681int plugin_load(const char* plugin, const void* parameter)
diff --git a/apps/plugin.h b/apps/plugin.h
index 227fe5ccbb..ade7f1584b 100644
--- a/apps/plugin.h
+++ b/apps/plugin.h
@@ -95,6 +95,7 @@ void* plugin_get_buffer(size_t *buffer_size);
95#include "ata_idle_notify.h" 95#include "ata_idle_notify.h"
96#include "settings_list.h" 96#include "settings_list.h"
97#include "timefuncs.h" 97#include "timefuncs.h"
98#include "crc32.h"
98 99
99#ifdef HAVE_ALBUMART 100#ifdef HAVE_ALBUMART
100#include "albumart.h" 101#include "albumart.h"
@@ -134,7 +135,7 @@ void* plugin_get_buffer(size_t *buffer_size);
134#define PLUGIN_MAGIC 0x526F634B /* RocK */ 135#define PLUGIN_MAGIC 0x526F634B /* RocK */
135 136
136/* increase this every time the api struct changes */ 137/* increase this every time the api struct changes */
137#define PLUGIN_API_VERSION 174 138#define PLUGIN_API_VERSION 175
138 139
139/* update this to latest version if a change to the api struct breaks 140/* update this to latest version if a change to the api struct breaks
140 backwards compatibility (and please take the opportunity to sort in any 141 backwards compatibility (and please take the opportunity to sort in any
@@ -848,6 +849,7 @@ struct plugin_api {
848 size_t duration, 849 size_t duration,
849 int amplitude); 850 int amplitude);
850#endif 851#endif
852 unsigned (*crc_32)(const void *src, unsigned len, unsigned crc32);
851}; 853};
852 854
853/* plugin header */ 855/* plugin header */
diff --git a/apps/plugins/test_codec.c b/apps/plugins/test_codec.c
index 156852a7b0..74d2e40fd2 100644
--- a/apps/plugins/test_codec.c
+++ b/apps/plugins/test_codec.c
@@ -111,6 +111,9 @@ static bool taginfo_ready = true;
111 111
112static bool use_dsp; 112static bool use_dsp;
113 113
114static bool checksum;
115static uint32_t crc32;
116
114static volatile unsigned int elapsed; 117static volatile unsigned int elapsed;
115static volatile bool codec_playing; 118static volatile bool codec_playing;
116static volatile long endtick; 119static volatile long endtick;
@@ -172,30 +175,31 @@ void init_wav(char* filename)
172} 175}
173 176
174 177
175void close_wav(void) { 178void close_wav(void)
176 int filesize = rb->filesize(wavinfo.fd); 179{
177 int channels = (wavinfo.stereomode == STEREO_MONO) ? 1 : 2; 180 int filesize = rb->filesize(wavinfo.fd);
178 int bps = 16; /* TODO */ 181 int channels = (wavinfo.stereomode == STEREO_MONO) ? 1 : 2;
182 int bps = 16; /* TODO */
179 183
180 /* We assume 16-bit, Stereo */ 184 /* We assume 16-bit, Stereo */
181 185
182 rb->lseek(wavinfo.fd,0,SEEK_SET); 186 rb->lseek(wavinfo.fd,0,SEEK_SET);
183 187
184 int2le32(wav_header+4, filesize-8); /* ChunkSize */ 188 int2le32(wav_header+4, filesize-8); /* ChunkSize */
185 189
186 int2le16(wav_header+22, channels); 190 int2le16(wav_header+22, channels);
187 191
188 int2le32(wav_header+24, wavinfo.samplerate); 192 int2le32(wav_header+24, wavinfo.samplerate);
189 193
190 int2le32(wav_header+28, wavinfo.samplerate * channels * (bps / 8)); /* ByteRate */ 194 int2le32(wav_header+28, wavinfo.samplerate * channels * (bps / 8)); /* ByteRate */
191 195
192 int2le16(wav_header+32, channels * (bps / 8)); 196 int2le16(wav_header+32, channels * (bps / 8));
193 197
194 int2le32(wav_header+40, filesize - 44); /* Subchunk2Size */ 198 int2le32(wav_header+40, filesize - 44); /* Subchunk2Size */
195 199
196 rb->write(wavinfo.fd, wav_header, sizeof(wav_header)); 200 rb->write(wavinfo.fd, wav_header, sizeof(wav_header));
197 201
198 rb->close(wavinfo.fd); 202 rb->close(wavinfo.fd);
199} 203}
200 204
201/* Returns buffer to malloc array. Only codeclib should need this. */ 205/* Returns buffer to malloc array. Only codeclib should need this. */
@@ -238,23 +242,119 @@ static int process_dsp(const void *ch1, const void *ch2, int count)
238 return written_count; 242 return written_count;
239} 243}
240 244
245static inline int32_t clip_sample(int32_t sample)
246{
247 if ((int16_t)sample != sample)
248 sample = 0x7fff ^ (sample >> 31);
249
250 return sample;
251}
252
241/* Null output */ 253/* Null output */
242static void pcmbuf_insert_null(const void *ch1, const void *ch2, int count) 254static void pcmbuf_insert_null(const void *ch1, const void *ch2, int count)
243{ 255{
244 if (use_dsp) process_dsp(ch1, ch2, count); 256 if (use_dsp)
257 process_dsp(ch1, ch2, count);
245 258
246 /* Prevent idle poweroff */ 259 /* Prevent idle poweroff */
247 rb->reset_poweroff_timer(); 260 rb->reset_poweroff_timer();
248} 261}
249 262
250static inline int32_t clip_sample(int32_t sample) 263static void pcmbuf_insert_checksum(const void *ch1, const void *ch2, int count)
251{ 264{
252 if ((int16_t)sample != sample) 265 const int16_t* data1_16;
253 sample = 0x7fff ^ (sample >> 31); 266 const int16_t* data2_16;
267 const int32_t* data1_32;
268 const int32_t* data2_32;
269 const int scale = wavinfo.sampledepth - 15;
270 const int dc_bias = 1 << (scale - 1);
271 int channels = (wavinfo.stereomode == STEREO_MONO) ? 1 : 2;
254 272
255 return sample; 273 /* Prevent idle poweroff */
256} 274 rb->reset_poweroff_timer();
275
276 if (use_dsp) {
277 count = process_dsp(ch1, ch2, count);
278 wavinfo.totalsamples += count;
279 if (channels == 1)
280 {
281 unsigned char *s = dspbuffer, *d = dspbuffer;
282 int c = count;
283 while (c-- > 0)
284 {
285 *d++ = *s++;
286 *d++ = *s++;
287 s++;
288 s++;
289 }
290 }
291 crc32 = rb->crc_32(dspbuffer, count * 2 * channels, crc32);
292 }
293 else
294 {
295 if (wavinfo.sampledepth <= 16) {
296 data1_16 = ch1;
297 data2_16 = ch2;
298
299 switch(wavinfo.stereomode)
300 {
301 case STEREO_INTERLEAVED:
302 while (count--) {
303 crc32 = rb->crc_32(data1_16, 4, crc32);
304 data1_16 += 2;
305 }
306 break;
307
308 case STEREO_NONINTERLEAVED:
309 while (count--) {
310 crc32 = rb->crc_32(data1_16++, 2, crc32);
311 crc32 = rb->crc_32(data2_16++, 2, crc32);
312 }
313 break;
314
315 case STEREO_MONO:
316 while (count--) {
317 crc32 = rb->crc_32(data1_16++, 2, crc32);
318 }
319 break;
320 }
321 }
322 else
323 {
324 data1_32 = ch1;
325 data2_32 = ch2;
257 326
327 switch(wavinfo.stereomode)
328 {
329 case STEREO_INTERLEAVED:
330 while (count--) {
331 int16_t s = clip_sample((*data1_32++ + dc_bias) >> scale);
332 crc32 = rb->crc_32(&s, 2, crc32);
333 s = clip_sample((*data1_32++ + dc_bias) >> scale);
334 crc32 = rb->crc_32(&s, 2, crc32);
335 }
336 break;
337
338 case STEREO_NONINTERLEAVED:
339 while (count--) {
340 int16_t s = clip_sample((*data1_32++ + dc_bias) >> scale);
341 crc32 = rb->crc_32(&s, 2, crc32);
342 s = clip_sample((*data2_32++ + dc_bias) >> scale);
343 crc32 = rb->crc_32(&s, 2, crc32);
344 }
345
346 break;
347
348 case STEREO_MONO:
349 while (count--) {
350 int16_t s = clip_sample((*data1_32++ + dc_bias) >> scale);
351 crc32 = rb->crc_32(&s, 2, crc32);
352 }
353 break;
354 }
355 }
356 }
357}
258 358
259/* WAV output */ 359/* WAV output */
260static void pcmbuf_insert_wav(const void *ch1, const void *ch2, int count) 360static void pcmbuf_insert_wav(const void *ch1, const void *ch2, int count)
@@ -287,76 +387,77 @@ static void pcmbuf_insert_wav(const void *ch1, const void *ch2, int count)
287 } 387 }
288 } 388 }
289 rb->write(wavinfo.fd, dspbuffer, count * 2 * channels); 389 rb->write(wavinfo.fd, dspbuffer, count * 2 * channels);
290 } else { 390 }
291 391 else
292 if (wavinfo.sampledepth <= 16) { 392 {
293 data1_16 = ch1; 393 if (wavinfo.sampledepth <= 16) {
294 data2_16 = ch2; 394 data1_16 = ch1;
395 data2_16 = ch2;
295 396
296 switch(wavinfo.stereomode) 397 switch(wavinfo.stereomode)
297 { 398 {
298 case STEREO_INTERLEAVED: 399 case STEREO_INTERLEAVED:
299 while (count--) { 400 while (count--) {
300 int2le16(p,*data1_16++); 401 int2le16(p,*data1_16++);
301 p += 2; 402 p += 2;
302 int2le16(p,*data1_16++); 403 int2le16(p,*data1_16++);
303 p += 2; 404 p += 2;
304 } 405 }
305 break; 406 break;
306 407
307 case STEREO_NONINTERLEAVED: 408 case STEREO_NONINTERLEAVED:
308 while (count--) { 409 while (count--) {
309 int2le16(p,*data1_16++); 410 int2le16(p,*data1_16++);
310 p += 2; 411 p += 2;
311 int2le16(p,*data2_16++); 412 int2le16(p,*data2_16++);
312 p += 2; 413 p += 2;
313 } 414 }
314 415
315 break; 416 break;
316 417
317 case STEREO_MONO: 418 case STEREO_MONO:
318 while (count--) { 419 while (count--) {
319 int2le16(p,*data1_16++); 420 int2le16(p,*data1_16++);
320 p += 2; 421 p += 2;
321 } 422 }
322 break; 423 break;
323 } 424 }
324 } else { 425 } else {
325 data1_32 = ch1; 426 data1_32 = ch1;
326 data2_32 = ch2; 427 data2_32 = ch2;
327 428
328 switch(wavinfo.stereomode) 429 switch(wavinfo.stereomode)
329 { 430 {
330 case STEREO_INTERLEAVED: 431 case STEREO_INTERLEAVED:
331 while (count--) { 432 while (count--) {
332 int2le16(p, clip_sample((*data1_32++ + dc_bias) >> scale)); 433 int2le16(p, clip_sample((*data1_32++ + dc_bias) >> scale));
333 p += 2; 434 p += 2;
334 int2le16(p, clip_sample((*data1_32++ + dc_bias) >> scale)); 435 int2le16(p, clip_sample((*data1_32++ + dc_bias) >> scale));
335 p += 2; 436 p += 2;
336 } 437 }
337 break; 438 break;
338 439
339 case STEREO_NONINTERLEAVED: 440 case STEREO_NONINTERLEAVED:
340 while (count--) { 441 while (count--) {
341 int2le16(p, clip_sample((*data1_32++ + dc_bias) >> scale)); 442 int2le16(p, clip_sample((*data1_32++ + dc_bias) >> scale));
342 p += 2; 443 p += 2;
343 int2le16(p, clip_sample((*data2_32++ + dc_bias) >> scale)); 444 int2le16(p, clip_sample((*data2_32++ + dc_bias) >> scale));
344 p += 2; 445 p += 2;
345 } 446 }
346 447
347 break; 448 break;
348 449
349 case STEREO_MONO: 450 case STEREO_MONO:
350 while (count--) { 451 while (count--) {
351 int2le16(p, clip_sample((*data1_32++ + dc_bias) >> scale)); 452 int2le16(p, clip_sample((*data1_32++ + dc_bias) >> scale));
352 p += 2; 453 p += 2;
353 } 454 }
354 break; 455 break;
456 }
355 } 457 }
356 }
357 458
358 wavinfo.totalsamples += count; 459 wavinfo.totalsamples += count;
359 rb->write(wavinfo.fd, wavbuffer, p - wavbuffer); 460 rb->write(wavinfo.fd, wavbuffer, p - wavbuffer);
360 } /* else */ 461 } /* else */
361} 462}
362 463
@@ -481,9 +582,12 @@ static void init_ci(void)
481 582
482 if (wavinfo.fd >= 0) { 583 if (wavinfo.fd >= 0) {
483 ci.pcmbuf_insert = pcmbuf_insert_wav; 584 ci.pcmbuf_insert = pcmbuf_insert_wav;
585 } else if (checksum){
586 ci.pcmbuf_insert = pcmbuf_insert_checksum;
484 } else { 587 } else {
485 ci.pcmbuf_insert = pcmbuf_insert_null; 588 ci.pcmbuf_insert = pcmbuf_insert_null;
486 } 589 }
590
487 ci.set_elapsed = set_elapsed; 591 ci.set_elapsed = set_elapsed;
488 ci.read_filebuf = read_filebuf; 592 ci.read_filebuf = read_filebuf;
489 ci.request_buffer = request_buffer; 593 ci.request_buffer = request_buffer;
@@ -636,6 +740,9 @@ static enum plugin_status test_track(const char* filename)
636 if (use_dsp) 740 if (use_dsp)
637 rb->dsp_configure(ci.dsp, DSP_RESET, 0); 741 rb->dsp_configure(ci.dsp, DSP_RESET, 0);
638 742
743 if (checksum)
744 crc32 = 0xffffffff;
745
639 starttick = *rb->current_tick; 746 starttick = *rb->current_tick;
640 747
641 codec_playing = true; 748 codec_playing = true;
@@ -656,7 +763,12 @@ static enum plugin_status test_track(const char* filename)
656 763
657 log_text(str,true); 764 log_text(str,true);
658 765
659 if (wavinfo.fd < 0) 766 if (checksum)
767 {
768 rb->snprintf(str, sizeof(str), "CRC32 - %x", (unsigned)crc32);
769 log_text(str,true);
770 }
771 else if (wavinfo.fd < 0)
660 { 772 {
661 /* Display benchmark information */ 773 /* Display benchmark information */
662 rb->snprintf(str,sizeof(str),"Decode time - %d.%02ds",(int)ticks/100,(int)ticks%100); 774 rb->snprintf(str,sizeof(str),"Decode time - %d.%02ds",(int)ticks/100,(int)ticks%100);
@@ -727,6 +839,19 @@ enum plugin_status plugin_start(const void* parameter)
727 rb->lcd_clear_display(); 839 rb->lcd_clear_display();
728 rb->lcd_update(); 840 rb->lcd_update();
729 841
842 enum
843 {
844 SPEED_TEST = 0,
845 SPEED_TEST_DIR,
846 WRITE_WAV,
847 SPEED_TEST_WITH_DSP,
848 SPEED_TEST_DIR_WITH_DSP,
849 WRITE_WAV_WITH_DSP,
850 CHECKSUM,
851 CHECKSUM_DIR,
852 QUIT,
853 };
854
730 MENUITEM_STRINGLIST( 855 MENUITEM_STRINGLIST(
731 menu, "test_codec", NULL, 856 menu, "test_codec", NULL,
732 "Speed test", 857 "Speed test",
@@ -735,15 +860,17 @@ enum plugin_status plugin_start(const void* parameter)
735 "Speed test with DSP", 860 "Speed test with DSP",
736 "Speed test folder with DSP", 861 "Speed test folder with DSP",
737 "Write WAV with DSP", 862 "Write WAV with DSP",
863 "Checksum",
864 "Checksum folder",
738 "Quit", 865 "Quit",
739 ); 866 );
740 867
741show_menu: 868show_menu:
742 rb->lcd_clear_display(); 869 rb->lcd_clear_display();
743 870
744 result=rb->do_menu(&menu,&selection, NULL, false); 871 result = rb->do_menu(&menu, &selection, NULL, false);
745 872
746 if (result == 6) 873 if (result == QUIT)
747 { 874 {
748 res = PLUGIN_OK; 875 res = PLUGIN_OK;
749 goto exit; 876 goto exit;
@@ -751,13 +878,17 @@ show_menu:
751 878
752 scandir = 0; 879 scandir = 0;
753 880
754 if ((use_dsp = ((result >= 3) && (result <=5)))) { 881 if ((checksum = (result == CHECKSUM || result == CHECKSUM_DIR)))
882 result -= 6;
883
884 if ((use_dsp = ((result >= SPEED_TEST_WITH_DSP)
885 && (result <= WRITE_WAV_WITH_DSP)))) {
755 result -= 3; 886 result -= 3;
756 } 887 }
757 if (result==0) { 888 if (result == SPEED_TEST) {
758 wavinfo.fd = -1; 889 wavinfo.fd = -1;
759 log_init(false); 890 log_init(false);
760 } else if (result==1) { 891 } else if (result == SPEED_TEST_DIR) {
761 wavinfo.fd = -1; 892 wavinfo.fd = -1;
762 scandir = 1; 893 scandir = 1;
763 894
@@ -767,7 +898,7 @@ show_menu:
767 res = PLUGIN_ERROR; 898 res = PLUGIN_ERROR;
768 goto exit; 899 goto exit;
769 } 900 }
770 } else if (result==2) { 901 } else if (result == WRITE_WAV) {
771 log_init(false); 902 log_init(false);
772 init_wav("/test.wav"); 903 init_wav("/test.wav");
773 if (wavinfo.fd < 0) { 904 if (wavinfo.fd < 0) {
@@ -817,7 +948,6 @@ show_menu:
817 close_wav(); 948 close_wav();
818 log_text("Wrote /test.wav",true); 949 log_text("Wrote /test.wav",true);
819 } 950 }
820
821 while (rb->button_get(true) != TESTCODEC_EXITBUTTON); 951 while (rb->button_get(true) != TESTCODEC_EXITBUTTON);
822 } 952 }
823 goto show_menu; 953 goto show_menu;