summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJaroslav Kysela <perex@perex.cz>2010-08-18 08:22:23 +0200
committerJaroslav Kysela <perex@perex.cz>2010-08-18 08:22:23 +0200
commit4c337275d1cc0579cc8ad45b4c138287e8658f0d (patch)
tree1a77b8258bff99cdced99e7e1627a36cd28dfe25
parent73c79ebf26a51a2d9b582a4cae82867873875743 (diff)
downloadalsa-utils-4c337275d1cc0579cc8ad45b4c138287e8658f0d.tar.gz
speaker-test: add test pattern for PCM layer debugging purposes
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
-rw-r--r--speaker-test/speaker-test.c75
1 files changed, 73 insertions, 2 deletions
diff --git a/speaker-test/speaker-test.c b/speaker-test/speaker-test.c
index d8d68e2..458a8d7 100644
--- a/speaker-test/speaker-test.c
+++ b/speaker-test/speaker-test.c
@@ -63,7 +63,8 @@
enum {
TEST_PINK_NOISE = 1,
TEST_SINE,
- TEST_WAV
+ TEST_WAV,
+ TEST_PATTERN,
};
#define MAX_CHANNELS 16
@@ -303,6 +304,71 @@ static void generate_pink_noise( uint8_t *frames, int channel, int count) {
}
}
+/*
+ * useful for tests
+ */
+static void generate_pattern(uint8_t *frames, int channel, int count, int *_pattern) {
+ int pattern = *_pattern;
+ int chn;
+ int8_t *samp8 = (int8_t*) frames;
+ int16_t *samp16 = (int16_t*) frames;
+ int32_t *samp32 = (int32_t*) frames;
+ float *samp_f = (float*) frames;
+
+ while (count-- > 0) {
+ for(chn=0;chn<channels;chn++,pattern++) {
+ switch (format) {
+ case SND_PCM_FORMAT_S8:
+ if (chn==channel) {
+ *samp8++ = pattern & 0xff;
+ } else {
+ *samp8++ = 0;
+ }
+ break;
+ case SND_PCM_FORMAT_S16_LE:
+ if (chn==channel) {
+ *samp16++ = LE_SHORT(pattern & 0xfffff);
+ } else {
+ *samp16++ = 0;
+ }
+ break;
+ case SND_PCM_FORMAT_S16_BE:
+ if (chn==channel) {
+ *samp16++ = BE_SHORT(pattern & 0xffff);
+ } else {
+ *samp16++ = 0;
+ }
+ break;
+ case SND_PCM_FORMAT_FLOAT_LE:
+ if (chn==channel) {
+ *samp_f++ = LE_INT(((double)pattern) / INT32_MAX);
+ } else {
+ *samp_f++ = 0.0;
+ }
+ break;
+ case SND_PCM_FORMAT_S32_LE:
+ if (chn==channel) {
+ *samp32++ = LE_INT(pattern);
+ } else {
+ *samp32++ = 0;
+ }
+ break;
+ case SND_PCM_FORMAT_S32_BE:
+ if (chn==channel) {
+ *samp32++ = BE_INT(pattern);
+ } else {
+ *samp32++ = 0;
+ }
+ break;
+ default:
+ ;
+ }
+ }
+ }
+
+ *_pattern = pattern;
+}
+
static int set_hwparams(snd_pcm_t *handle, snd_pcm_hw_params_t *params, snd_pcm_access_t access) {
unsigned int rrate;
int err;
@@ -687,6 +753,7 @@ static int write_buffer(snd_pcm_t *handle, uint8_t *ptr, int cptr)
static int write_loop(snd_pcm_t *handle, int channel, int periods, uint8_t *frames)
{
double phase = 0;
+ int pattern = 0;
int err, n;
fflush(stdout);
@@ -713,6 +780,8 @@ static int write_loop(snd_pcm_t *handle, int channel, int periods, uint8_t *fram
for(n = 0; n < periods; n++) {
if (test_type == TEST_PINK_NOISE)
generate_pink_noise(frames, channel, period_size);
+ else if (test_type == TEST_PATTERN)
+ generate_pattern(frames, channel, period_size, &pattern);
else
generate_sine(frames, channel, period_size, &phase);
@@ -860,9 +929,11 @@ int main(int argc, char *argv[]) {
test_type = TEST_SINE;
else if (*optarg == 'w')
test_type = TEST_WAV;
+ else if (*optarg == 't')
+ test_type = TEST_PATTERN;
else if (isdigit(*optarg)) {
test_type = atoi(optarg);
- if (test_type < TEST_PINK_NOISE || test_type > TEST_WAV) {
+ if (test_type < TEST_PINK_NOISE || test_type > TEST_PATTERN) {
fprintf(stderr, _("Invalid test type %s\n"), optarg);
exit(1);
}