struct pcm_data *next;
};
-int num_pcms = 0;
struct pcm_data *pcm_list = NULL;
int num_missing = 0;
pcm_data->pcm_config = conf_get_subtree(card_config, key, NULL);
pcm_data->next = pcm_list;
pcm_list = pcm_data;
- num_pcms++;
}
}
}
snd_config_delete(config);
}
-static void test_pcm_time1(struct pcm_data *data,
- const char *cfg_prefix, const char *sformat,
- long srate, long schannels,
- long speriod_size, long sbuffer_size)
+static void test_pcm_time(struct pcm_data *data, const char *test_name, snd_config_t *pcm_cfg)
{
char name[64], key[128], msg[256];
const char *cs;
int i, err;
snd_pcm_t *handle = NULL;
snd_pcm_access_t access = SND_PCM_ACCESS_RW_INTERLEAVED;
- snd_pcm_format_t format;
+ snd_pcm_format_t format, old_format;
+ const char *alt_formats[8];
unsigned char *samples = NULL;
snd_pcm_sframes_t frames;
long long ms;
unsigned int rrate;
snd_pcm_uframes_t rperiod_size, rbuffer_size, start_threshold;
timestamp_t tstamp;
- bool pass = false, automatic = true;
+ bool pass = false;
snd_pcm_hw_params_t *hw_params;
snd_pcm_sw_params_t *sw_params;
snd_pcm_hw_params_alloca(&hw_params);
snd_pcm_sw_params_alloca(&sw_params);
- cs = conf_get_string(data->pcm_config, cfg_prefix, "format", sformat);
+ cs = conf_get_string(pcm_cfg, "format", NULL, "S16_LE");
format = snd_pcm_format_value(cs);
if (format == SND_PCM_FORMAT_UNKNOWN)
ksft_exit_fail_msg("Wrong format '%s'\n", cs);
- rate = conf_get_long(data->pcm_config, cfg_prefix, "rate", srate);
- channels = conf_get_long(data->pcm_config, cfg_prefix, "channels", schannels);
- period_size = conf_get_long(data->pcm_config, cfg_prefix, "period_size", speriod_size);
- buffer_size = conf_get_long(data->pcm_config, cfg_prefix, "buffer_size", sbuffer_size);
-
- automatic = strcmp(sformat, snd_pcm_format_name(format)) == 0 &&
- srate == rate &&
- schannels == channels &&
- speriod_size == period_size &&
- sbuffer_size == buffer_size;
+ conf_get_string_array(pcm_cfg, "alt_formats", NULL,
+ alt_formats, ARRAY_SIZE(alt_formats), NULL);
+ rate = conf_get_long(pcm_cfg, "rate", NULL, 48000);
+ channels = conf_get_long(pcm_cfg, "channels", NULL, 2);
+ period_size = conf_get_long(pcm_cfg, "period_size", NULL, 4096);
+ buffer_size = conf_get_long(pcm_cfg, "buffer_size", NULL, 16384);
samples = malloc((rate * channels * snd_pcm_format_physical_width(format)) / 8);
if (!samples)
snd_pcm_access_name(access), snd_strerror(err));
goto __close;
}
+ i = -1;
__format:
err = snd_pcm_hw_params_set_format(handle, hw_params, format);
if (err < 0) {
- if (automatic && format == SND_PCM_FORMAT_S16_LE) {
- format = SND_PCM_FORMAT_S32_LE;
- ksft_print_msg("%s.%d.%d.%d.%s.%s format S16_LE -> S32_LE\n",
- cfg_prefix,
- data->card, data->device, data->subdevice,
- snd_pcm_stream_name(data->stream),
- snd_pcm_access_name(access));
+ i++;
+ if (i < ARRAY_SIZE(alt_formats) && alt_formats[i]) {
+ old_format = format;
+ format = snd_pcm_format_value(alt_formats[i]);
+ if (format != SND_PCM_FORMAT_UNKNOWN) {
+ ksft_print_msg("%s.%d.%d.%d.%s.%s format %s -> %s\n",
+ test_name,
+ data->card, data->device, data->subdevice,
+ snd_pcm_stream_name(data->stream),
+ snd_pcm_access_name(access),
+ snd_pcm_format_name(old_format),
+ snd_pcm_format_name(format));
+ samples = realloc(samples, (rate * channels *
+ snd_pcm_format_physical_width(format)) / 8);
+ if (!samples)
+ ksft_exit_fail_msg("Out of memory\n");
+ snd_pcm_format_set_silence(format, samples, rate * channels);
+ goto __format;
+ }
}
snprintf(msg, sizeof(msg), "snd_pcm_hw_params_set_format %s: %s",
snd_pcm_format_name(format), snd_strerror(err));
}
ksft_print_msg("%s.%d.%d.%d.%s hw_params.%s.%s.%ld.%ld.%ld.%ld sw_params.%ld\n",
- cfg_prefix,
+ test_name,
data->card, data->device, data->subdevice,
snd_pcm_stream_name(data->stream),
snd_pcm_access_name(access),
pass = true;
__close:
ksft_test_result(pass, "%s.%d.%d.%d.%s%s%s\n",
- cfg_prefix,
+ test_name,
data->card, data->device, data->subdevice,
snd_pcm_stream_name(data->stream),
msg[0] ? " " : "", msg);
snd_pcm_close(handle);
}
-#define TESTS_PER_PCM 2
-
int main(void)
{
struct pcm_data *pcm;
+ snd_config_t *global_config, *default_pcm_config, *cfg, *pcm_cfg;
+ snd_config_iterator_t i, next;
+ int num_pcm_tests = 0, num_tests;
+ const char *test_name, *test_type;
ksft_print_header();
+ global_config = conf_load_from_file("pcm-test.conf");
+ default_pcm_config = conf_get_subtree(global_config, "pcm", NULL);
+ if (default_pcm_config == NULL)
+ ksft_exit_fail_msg("default pcm test configuration (pcm compound) is missing\n");
+
conf_load();
find_pcms();
- ksft_set_plan(num_missing + num_pcms * TESTS_PER_PCM);
+ for (pcm = pcm_list; pcm != NULL; pcm = pcm->next) {
+ cfg = pcm->pcm_config;
+ if (cfg == NULL)
+ cfg = default_pcm_config;
+ num_tests = conf_get_count(cfg, "test", NULL);
+ if (num_tests > 0)
+ num_pcm_tests += num_tests;
+ }
+
+ ksft_set_plan(num_missing + num_pcm_tests);
for (pcm = pcm_missing; pcm != NULL; pcm = pcm->next) {
ksft_test_result(false, "test.missing.%d.%d.%d.%s\n",
}
for (pcm = pcm_list; pcm != NULL; pcm = pcm->next) {
- test_pcm_time1(pcm, "test.time1", "S16_LE", 48000, 2, 512, 4096);
- test_pcm_time1(pcm, "test.time2", "S16_LE", 48000, 2, 24000, 192000);
+ cfg = pcm->pcm_config;
+ if (cfg == NULL)
+ cfg = default_pcm_config;
+ cfg = conf_get_subtree(cfg, "test", NULL);
+ if (cfg == NULL)
+ continue;
+ snd_config_for_each(i, next, cfg) {
+ pcm_cfg = snd_config_iterator_entry(i);
+ if (snd_config_get_id(pcm_cfg, &test_name) < 0)
+ ksft_exit_fail_msg("snd_config_get_id\n");
+ test_type = conf_get_string(pcm_cfg, "type", NULL, "time");
+ if (strcmp(test_type, "time") == 0)
+ test_pcm_time(pcm, test_name, pcm_cfg);
+ else
+ ksft_exit_fail_msg("unknown test type '%s'\n", test_type);
+ }
}
+ snd_config_delete(global_config);
conf_free();
ksft_exit_pass();