summaryrefslogtreecommitdiff
path: root/apps
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 /apps
parent1832def9b0b52b2a3385f9672aacc35dde9c389a (diff)
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
Diffstat (limited to 'apps')
-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 = {
#if (CONFIG_CODEC == SWCODEC)
pcmbuf_beep,
#endif
+ crc_32,
};
int 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);
#include "ata_idle_notify.h"
#include "settings_list.h"
#include "timefuncs.h"
+#include "crc32.h"
#ifdef HAVE_ALBUMART
#include "albumart.h"
@@ -134,7 +135,7 @@ void* plugin_get_buffer(size_t *buffer_size);
#define PLUGIN_MAGIC 0x526F634B /* RocK */
/* increase this every time the api struct changes */
-#define PLUGIN_API_VERSION 174
+#define PLUGIN_API_VERSION 175
/* update this to latest version if a change to the api struct breaks
backwards compatibility (and please take the opportunity to sort in any
@@ -848,6 +849,7 @@ struct plugin_api {
size_t duration,
int amplitude);
#endif
+ unsigned (*crc_32)(const void *src, unsigned len, unsigned crc32);
};
/* 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;
static bool use_dsp;
+static bool checksum;
+static uint32_t crc32;
+
static volatile unsigned int elapsed;
static volatile bool codec_playing;
static volatile long endtick;
@@ -172,30 +175,31 @@ void init_wav(char* filename)
}
-void close_wav(void) {
- int filesize = rb->filesize(wavinfo.fd);
- int channels = (wavinfo.stereomode == STEREO_MONO) ? 1 : 2;
- int bps = 16; /* TODO */
+void close_wav(void)
+{
+ int filesize = rb->filesize(wavinfo.fd);
+ int channels = (wavinfo.stereomode == STEREO_MONO) ? 1 : 2;
+ int bps = 16; /* TODO */
- /* We assume 16-bit, Stereo */
+ /* We assume 16-bit, Stereo */
- rb->lseek(wavinfo.fd,0,SEEK_SET);
+ rb->lseek(wavinfo.fd,0,SEEK_SET);
- int2le32(wav_header+4, filesize-8); /* ChunkSize */
+ int2le32(wav_header+4, filesize-8); /* ChunkSize */
- int2le16(wav_header+22, channels);
+ int2le16(wav_header+22, channels);
- int2le32(wav_header+24, wavinfo.samplerate);
+ int2le32(wav_header+24, wavinfo.samplerate);
- int2le32(wav_header+28, wavinfo.samplerate * channels * (bps / 8)); /* ByteRate */
+ int2le32(wav_header+28, wavinfo.samplerate * channels * (bps / 8)); /* ByteRate */
- int2le16(wav_header+32, channels * (bps / 8));
+ int2le16(wav_header+32, channels * (bps / 8));
- int2le32(wav_header+40, filesize - 44); /* Subchunk2Size */
+ int2le32(wav_header+40, filesize - 44); /* Subchunk2Size */
- rb->write(wavinfo.fd, wav_header, sizeof(wav_header));
+ rb->write(wavinfo.fd, wav_header, sizeof(wav_header));
- rb->close(wavinfo.fd);
+ rb->close(wavinfo.fd);
}
/* 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)
return written_count;
}
+static inline int32_t clip_sample(int32_t sample)
+{
+ if ((int16_t)sample != sample)
+ sample = 0x7fff ^ (sample >> 31);
+
+ return sample;
+}
+
/* Null output */
static void pcmbuf_insert_null(const void *ch1, const void *ch2, int count)
{
- if (use_dsp) process_dsp(ch1, ch2, count);
+ if (use_dsp)
+ process_dsp(ch1, ch2, count);
/* Prevent idle poweroff */
rb->reset_poweroff_timer();
}
-static inline int32_t clip_sample(int32_t sample)
+static void pcmbuf_insert_checksum(const void *ch1, const void *ch2, int count)
{
- if ((int16_t)sample != sample)
- sample = 0x7fff ^ (sample >> 31);
+ const int16_t* data1_16;
+ const int16_t* data2_16;
+ const int32_t* data1_32;
+ const int32_t* data2_32;
+ const int scale = wavinfo.sampledepth - 15;
+ const int dc_bias = 1 << (scale - 1);
+ int channels = (wavinfo.stereomode == STEREO_MONO) ? 1 : 2;
- return sample;
-}
+ /* Prevent idle poweroff */
+ rb->reset_poweroff_timer();
+
+ if (use_dsp) {
+ count = process_dsp(ch1, ch2, count);
+ wavinfo.totalsamples += count;
+ if (channels == 1)
+ {
+ unsigned char *s = dspbuffer, *d = dspbuffer;
+ int c = count;
+ while (c-- > 0)
+ {
+ *d++ = *s++;
+ *d++ = *s++;
+ s++;
+ s++;
+ }
+ }
+ crc32 = rb->crc_32(dspbuffer, count * 2 * channels, crc32);
+ }
+ else
+ {
+ if (wavinfo.sampledepth <= 16) {
+ data1_16 = ch1;
+ data2_16 = ch2;
+
+ switch(wavinfo.stereomode)
+ {
+ case STEREO_INTERLEAVED:
+ while (count--) {
+ crc32 = rb->crc_32(data1_16, 4, crc32);
+ data1_16 += 2;
+ }
+ break;
+
+ case STEREO_NONINTERLEAVED:
+ while (count--) {
+ crc32 = rb->crc_32(data1_16++, 2, crc32);
+ crc32 = rb->crc_32(data2_16++, 2, crc32);
+ }
+ break;
+
+ case STEREO_MONO:
+ while (count--) {
+ crc32 = rb->crc_32(data1_16++, 2, crc32);
+ }
+ break;
+ }
+ }
+ else
+ {
+ data1_32 = ch1;
+ data2_32 = ch2;
+ switch(wavinfo.stereomode)
+ {
+ case STEREO_INTERLEAVED:
+ while (count--) {
+ int16_t s = clip_sample((*data1_32++ + dc_bias) >> scale);
+ crc32 = rb->crc_32(&s, 2, crc32);
+ s = clip_sample((*data1_32++ + dc_bias) >> scale);
+ crc32 = rb->crc_32(&s, 2, crc32);
+ }
+ break;
+
+ case STEREO_NONINTERLEAVED:
+ while (count--) {
+ int16_t s = clip_sample((*data1_32++ + dc_bias) >> scale);
+ crc32 = rb->crc_32(&s, 2, crc32);
+ s = clip_sample((*data2_32++ + dc_bias) >> scale);
+ crc32 = rb->crc_32(&s, 2, crc32);
+ }
+
+ break;
+
+ case STEREO_MONO:
+ while (count--) {
+ int16_t s = clip_sample((*data1_32++ + dc_bias) >> scale);
+ crc32 = rb->crc_32(&s, 2, crc32);
+ }
+ break;
+ }
+ }
+ }
+}
/* WAV output */
static 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)
}
}
rb->write(wavinfo.fd, dspbuffer, count * 2 * channels);
- } else {
-
- if (wavinfo.sampledepth <= 16) {
- data1_16 = ch1;
- data2_16 = ch2;
+ }
+ else
+ {
+ if (wavinfo.sampledepth <= 16) {
+ data1_16 = ch1;
+ data2_16 = ch2;
- switch(wavinfo.stereomode)
- {
- case STEREO_INTERLEAVED:
- while (count--) {
- int2le16(p,*data1_16++);
- p += 2;
- int2le16(p,*data1_16++);
- p += 2;
- }
- break;
+ switch(wavinfo.stereomode)
+ {
+ case STEREO_INTERLEAVED:
+ while (count--) {
+ int2le16(p,*data1_16++);
+ p += 2;
+ int2le16(p,*data1_16++);
+ p += 2;
+ }
+ break;
- case STEREO_NONINTERLEAVED:
- while (count--) {
- int2le16(p,*data1_16++);
- p += 2;
- int2le16(p,*data2_16++);
- p += 2;
- }
-
- break;
-
- case STEREO_MONO:
- while (count--) {
- int2le16(p,*data1_16++);
- p += 2;
- }
- break;
- }
- } else {
- data1_32 = ch1;
- data2_32 = ch2;
+ case STEREO_NONINTERLEAVED:
+ while (count--) {
+ int2le16(p,*data1_16++);
+ p += 2;
+ int2le16(p,*data2_16++);
+ p += 2;
+ }
+
+ break;
+
+ case STEREO_MONO:
+ while (count--) {
+ int2le16(p,*data1_16++);
+ p += 2;
+ }
+ break;
+ }
+ } else {
+ data1_32 = ch1;
+ data2_32 = ch2;
- switch(wavinfo.stereomode)
- {
- case STEREO_INTERLEAVED:
- while (count--) {
- int2le16(p, clip_sample((*data1_32++ + dc_bias) >> scale));
- p += 2;
- int2le16(p, clip_sample((*data1_32++ + dc_bias) >> scale));
- p += 2;
- }
- break;
+ switch(wavinfo.stereomode)
+ {
+ case STEREO_INTERLEAVED:
+ while (count--) {
+ int2le16(p, clip_sample((*data1_32++ + dc_bias) >> scale));
+ p += 2;
+ int2le16(p, clip_sample((*data1_32++ + dc_bias) >> scale));
+ p += 2;
+ }
+ break;
- case STEREO_NONINTERLEAVED:
- while (count--) {
- int2le16(p, clip_sample((*data1_32++ + dc_bias) >> scale));
- p += 2;
- int2le16(p, clip_sample((*data2_32++ + dc_bias) >> scale));
- p += 2;
- }
-
- break;
-
- case STEREO_MONO:
- while (count--) {
- int2le16(p, clip_sample((*data1_32++ + dc_bias) >> scale));
- p += 2;
- }
- break;
+ case STEREO_NONINTERLEAVED:
+ while (count--) {
+ int2le16(p, clip_sample((*data1_32++ + dc_bias) >> scale));
+ p += 2;
+ int2le16(p, clip_sample((*data2_32++ + dc_bias) >> scale));
+ p += 2;
+ }
+
+ break;
+
+ case STEREO_MONO:
+ while (count--) {
+ int2le16(p, clip_sample((*data1_32++ + dc_bias) >> scale));
+ p += 2;
+ }
+ break;
+ }
}
- }
- wavinfo.totalsamples += count;
- rb->write(wavinfo.fd, wavbuffer, p - wavbuffer);
+ wavinfo.totalsamples += count;
+ rb->write(wavinfo.fd, wavbuffer, p - wavbuffer);
} /* else */
}
@@ -481,9 +582,12 @@ static void init_ci(void)
if (wavinfo.fd >= 0) {
ci.pcmbuf_insert = pcmbuf_insert_wav;
+ } else if (checksum){
+ ci.pcmbuf_insert = pcmbuf_insert_checksum;
} else {
ci.pcmbuf_insert = pcmbuf_insert_null;
}
+
ci.set_elapsed = set_elapsed;
ci.read_filebuf = read_filebuf;
ci.request_buffer = request_buffer;
@@ -636,6 +740,9 @@ static enum plugin_status test_track(const char* filename)
if (use_dsp)
rb->dsp_configure(ci.dsp, DSP_RESET, 0);
+ if (checksum)
+ crc32 = 0xffffffff;
+
starttick = *rb->current_tick;
codec_playing = true;
@@ -656,7 +763,12 @@ static enum plugin_status test_track(const char* filename)
log_text(str,true);
- if (wavinfo.fd < 0)
+ if (checksum)
+ {
+ rb->snprintf(str, sizeof(str), "CRC32 - %x", (unsigned)crc32);
+ log_text(str,true);
+ }
+ else if (wavinfo.fd < 0)
{
/* Display benchmark information */
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)
rb->lcd_clear_display();
rb->lcd_update();
+ enum
+ {
+ SPEED_TEST = 0,
+ SPEED_TEST_DIR,
+ WRITE_WAV,
+ SPEED_TEST_WITH_DSP,
+ SPEED_TEST_DIR_WITH_DSP,
+ WRITE_WAV_WITH_DSP,
+ CHECKSUM,
+ CHECKSUM_DIR,
+ QUIT,
+ };
+
MENUITEM_STRINGLIST(
menu, "test_codec", NULL,
"Speed test",
@@ -735,15 +860,17 @@ enum plugin_status plugin_start(const void* parameter)
"Speed test with DSP",
"Speed test folder with DSP",
"Write WAV with DSP",
+ "Checksum",
+ "Checksum folder",
"Quit",
);
show_menu:
rb->lcd_clear_display();
- result=rb->do_menu(&menu,&selection, NULL, false);
+ result = rb->do_menu(&menu, &selection, NULL, false);
- if (result == 6)
+ if (result == QUIT)
{
res = PLUGIN_OK;
goto exit;
@@ -751,13 +878,17 @@ show_menu:
scandir = 0;
- if ((use_dsp = ((result >= 3) && (result <=5)))) {
+ if ((checksum = (result == CHECKSUM || result == CHECKSUM_DIR)))
+ result -= 6;
+
+ if ((use_dsp = ((result >= SPEED_TEST_WITH_DSP)
+ && (result <= WRITE_WAV_WITH_DSP)))) {
result -= 3;
}
- if (result==0) {
+ if (result == SPEED_TEST) {
wavinfo.fd = -1;
log_init(false);
- } else if (result==1) {
+ } else if (result == SPEED_TEST_DIR) {
wavinfo.fd = -1;
scandir = 1;
@@ -767,7 +898,7 @@ show_menu:
res = PLUGIN_ERROR;
goto exit;
}
- } else if (result==2) {
+ } else if (result == WRITE_WAV) {
log_init(false);
init_wav("/test.wav");
if (wavinfo.fd < 0) {
@@ -817,7 +948,6 @@ show_menu:
close_wav();
log_text("Wrote /test.wav",true);
}
-
while (rb->button_get(true) != TESTCODEC_EXITBUTTON);
}
goto show_menu;