2 * Copyright (C) 2000-2004 James Courtier-Dutton
3 * Copyright (C) 2005 Nathan Hurst
5 * This file is part of the speaker-test tool.
7 * This small program sends a simple sinusoidal wave to your speakers.
9 * speaker-test is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * speaker-test is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
24 * Main program by James Courtier-Dutton (including some source code fragments from the alsa project.)
25 * Some cleanup from Daniel Caujolle-Bert <segfault@club-internet.fr>
26 * Pink noise option added Nathan Hurst,
27 * based on generator by Phil Burk (pink.c)
30 * 0.0.8 Added support for pink noise output.
32 * 0.0.7 Added support for more than 6 channels.
34 * 0.0.6 Added support for different sample formats.
36 * $Id: speaker_test.c,v 1.00 2003/11/26 19:43:38 jcdutton Exp $
49 #define ALSA_PCM_NEW_HW_PARAMS_API
50 #define ALSA_PCM_NEW_SW_PARAMS_API
51 #include <alsa/asoundlib.h>
70 #define MAX_CHANNELS 16
72 #if __BYTE_ORDER == __LITTLE_ENDIAN
73 #define COMPOSE_ID(a,b,c,d) ((a) | ((b)<<8) | ((c)<<16) | ((d)<<24))
74 #define LE_SHORT(v) (v)
76 #define BE_SHORT(v) bswap_16(v)
77 #define BE_INT(v) bswap_32(v)
78 #else /* __BIG_ENDIAN */
79 #define COMPOSE_ID(a,b,c,d) ((d) | ((c)<<8) | ((b)<<16) | ((a)<<24))
80 #define LE_SHORT(v) bswap_16(v)
81 #define LE_INT(v) bswap_32(v)
82 #define BE_SHORT(v) (v)
86 static char *device = "default"; /* playback device */
87 static snd_pcm_format_t format = SND_PCM_FORMAT_S16; /* sample format */
88 static unsigned int rate = 48000; /* stream rate */
89 static unsigned int channels = 1; /* count of channels */
90 static unsigned int speaker = 0; /* count of channels */
91 static unsigned int buffer_time = 0; /* ring buffer length in us */
92 static unsigned int period_time = 0; /* period time in us */
93 static unsigned int nperiods = 4; /* number of periods */
94 static double freq = 440.0; /* sinusoidal wave frequency in Hz */
95 static int test_type = TEST_PINK_NOISE; /* Test type. 1 = noise, 2 = sine wave */
96 static pink_noise_t pink;
97 static snd_pcm_uframes_t buffer_size;
98 static snd_pcm_uframes_t period_size;
99 static const char *given_test_wav_file = NULL;
100 static char *wav_file_dir = SOUNDSDIR;
101 static int debug = 0;
103 static const char *const channel_name[MAX_CHANNELS] = {
104 /* 0 */ N_("Front Left"),
105 /* 1 */ N_("Front Right"),
106 /* 2 */ N_("Rear Left"),
107 /* 3 */ N_("Rear Right"),
108 /* 4 */ N_("Center"),
110 /* 6 */ N_("Side Left"),
111 /* 7 */ N_("Side Right"),
112 /* 8 */ N_("Channel 9"),
113 /* 9 */ N_("Channel 10"),
114 /* 10 */ N_("Channel 11"),
115 /* 11 */ N_("Channel 12"),
116 /* 12 */ N_("Channel 13"),
117 /* 13 */ N_("Channel 14"),
118 /* 14 */ N_("Channel 15"),
119 /* 15 */ N_("Channel 16")
122 static const int channels4[] = {
128 static const int channels6[] = {
136 static const int channels8[] = {
146 static const int supported_formats[] = {
148 SND_PCM_FORMAT_S16_LE,
149 SND_PCM_FORMAT_S16_BE,
150 SND_PCM_FORMAT_FLOAT_LE,
151 SND_PCM_FORMAT_S32_LE,
152 SND_PCM_FORMAT_S32_BE,
156 static void generate_sine(uint8_t *frames, int channel, int count, double *_phase) {
157 double phase = *_phase;
158 double max_phase = 1.0 / freq;
159 double step = 1.0 / (double)rate;
164 int8_t *samp8 = (int8_t*) frames;
165 int16_t *samp16 = (int16_t*) frames;
166 int32_t *samp32 = (int32_t*) frames;
167 float *samp_f = (float*) frames;
169 while (count-- > 0) {
170 for(chn=0;chn<channels;chn++) {
172 case SND_PCM_FORMAT_S8:
174 res = (sin((phase * 2 * M_PI) / max_phase - M_PI)) * 0x03fffffff; /* Don't use MAX volume */
176 *samp8++ = ires >> 24;
181 case SND_PCM_FORMAT_S16_LE:
183 res = (sin((phase * 2 * M_PI) / max_phase - M_PI)) * 0x03fffffff; /* Don't use MAX volume */
185 *samp16++ = LE_SHORT(ires >> 16);
190 case SND_PCM_FORMAT_S16_BE:
192 res = (sin((phase * 2 * M_PI) / max_phase - M_PI)) * 0x03fffffff; /* Don't use MAX volume */
194 *samp16++ = BE_SHORT(ires >> 16);
199 case SND_PCM_FORMAT_FLOAT_LE:
201 res = (sin((phase * 2 * M_PI) / max_phase - M_PI)) * 0.75 ; /* Don't use MAX volume */
208 case SND_PCM_FORMAT_S32_LE:
210 res = (sin((phase * 2 * M_PI) / max_phase - M_PI)) * 0x03fffffff; /* Don't use MAX volume */
212 *samp32++ = LE_INT(ires);
217 case SND_PCM_FORMAT_S32_BE:
219 res = (sin((phase * 2 * M_PI) / max_phase - M_PI)) * 0x03fffffff; /* Don't use MAX volume */
221 *samp32++ = BE_INT(ires);
232 if (phase >= max_phase)
239 /* Pink noise is a better test than sine wave because we can tell
240 * where pink noise is coming from more easily that a sine wave.
244 static void generate_pink_noise( uint8_t *frames, int channel, int count) {
248 int8_t *samp8 = (int8_t*) frames;
249 int16_t *samp16 = (int16_t*) frames;
250 int32_t *samp32 = (int32_t*) frames;
252 while (count-- > 0) {
253 for(chn=0;chn<channels;chn++) {
255 case SND_PCM_FORMAT_S8:
257 res = generate_pink_noise_sample(&pink) * 0x03fffffff; /* Don't use MAX volume */
259 *samp8++ = ires >> 24;
264 case SND_PCM_FORMAT_S16_LE:
266 res = generate_pink_noise_sample(&pink) * 0x03fffffff; /* Don't use MAX volume */
268 *samp16++ = LE_SHORT(ires >> 16);
273 case SND_PCM_FORMAT_S16_BE:
275 res = generate_pink_noise_sample(&pink) * 0x03fffffff; /* Don't use MAX volume */
277 *samp16++ = BE_SHORT(ires >> 16);
282 case SND_PCM_FORMAT_S32_LE:
284 res = generate_pink_noise_sample(&pink) * 0x03fffffff; /* Don't use MAX volume */
286 *samp32++ = LE_INT(ires);
291 case SND_PCM_FORMAT_S32_BE:
293 res = generate_pink_noise_sample(&pink) * 0x03fffffff; /* Don't use MAX volume */
295 *samp32++ = BE_INT(ires);
310 static void generate_pattern(uint8_t *frames, int channel, int count, int *_pattern) {
311 int pattern = *_pattern;
313 int8_t *samp8 = (int8_t*) frames;
314 int16_t *samp16 = (int16_t*) frames;
315 int32_t *samp32 = (int32_t*) frames;
316 float *samp_f = (float*) frames;
318 while (count-- > 0) {
319 for(chn=0;chn<channels;chn++,pattern++) {
321 case SND_PCM_FORMAT_S8:
323 *samp8++ = pattern & 0xff;
328 case SND_PCM_FORMAT_S16_LE:
330 *samp16++ = LE_SHORT(pattern & 0xfffff);
335 case SND_PCM_FORMAT_S16_BE:
337 *samp16++ = BE_SHORT(pattern & 0xffff);
342 case SND_PCM_FORMAT_FLOAT_LE:
344 *samp_f++ = LE_INT(((double)pattern) / INT32_MAX);
349 case SND_PCM_FORMAT_S32_LE:
351 *samp32++ = LE_INT(pattern);
356 case SND_PCM_FORMAT_S32_BE:
358 *samp32++ = BE_INT(pattern);
372 static int set_hwparams(snd_pcm_t *handle, snd_pcm_hw_params_t *params, snd_pcm_access_t access) {
375 snd_pcm_uframes_t period_size_min;
376 snd_pcm_uframes_t period_size_max;
377 snd_pcm_uframes_t buffer_size_min;
378 snd_pcm_uframes_t buffer_size_max;
380 /* choose all parameters */
381 err = snd_pcm_hw_params_any(handle, params);
383 fprintf(stderr, _("Broken configuration for playback: no configurations available: %s\n"), snd_strerror(err));
387 /* set the interleaved read/write format */
388 err = snd_pcm_hw_params_set_access(handle, params, access);
390 fprintf(stderr, _("Access type not available for playback: %s\n"), snd_strerror(err));
394 /* set the sample format */
395 err = snd_pcm_hw_params_set_format(handle, params, format);
397 fprintf(stderr, _("Sample format not available for playback: %s\n"), snd_strerror(err));
401 /* set the count of channels */
402 err = snd_pcm_hw_params_set_channels(handle, params, channels);
404 fprintf(stderr, _("Channels count (%i) not available for playbacks: %s\n"), channels, snd_strerror(err));
408 /* set the stream rate */
410 err = snd_pcm_hw_params_set_rate(handle, params, rate, 0);
412 fprintf(stderr, _("Rate %iHz not available for playback: %s\n"), rate, snd_strerror(err));
417 fprintf(stderr, _("Rate doesn't match (requested %iHz, get %iHz, err %d)\n"), rate, rrate, err);
421 printf(_("Rate set to %iHz (requested %iHz)\n"), rrate, rate);
422 /* set the buffer time */
423 err = snd_pcm_hw_params_get_buffer_size_min(params, &buffer_size_min);
424 err = snd_pcm_hw_params_get_buffer_size_max(params, &buffer_size_max);
425 err = snd_pcm_hw_params_get_period_size_min(params, &period_size_min, NULL);
426 err = snd_pcm_hw_params_get_period_size_max(params, &period_size_max, NULL);
427 printf(_("Buffer size range from %lu to %lu\n"),buffer_size_min, buffer_size_max);
428 printf(_("Period size range from %lu to %lu\n"),period_size_min, period_size_max);
429 if (period_time > 0) {
430 printf(_("Requested period time %u us\n"), period_time);
431 err = snd_pcm_hw_params_set_period_time_near(handle, params, &period_time, NULL);
433 fprintf(stderr, _("Unable to set period time %u us for playback: %s\n"),
434 period_time, snd_strerror(err));
438 if (buffer_time > 0) {
439 printf(_("Requested buffer time %u us\n"), buffer_time);
440 err = snd_pcm_hw_params_set_buffer_time_near(handle, params, &buffer_time, NULL);
442 fprintf(stderr, _("Unable to set buffer time %u us for playback: %s\n"),
443 buffer_time, snd_strerror(err));
447 if (! buffer_time && ! period_time) {
448 buffer_size = buffer_size_max;
450 buffer_size = (buffer_size / nperiods) * nperiods;
451 printf(_("Using max buffer size %lu\n"), buffer_size);
452 err = snd_pcm_hw_params_set_buffer_size_near(handle, params, &buffer_size);
454 fprintf(stderr, _("Unable to set buffer size %lu for playback: %s\n"),
455 buffer_size, snd_strerror(err));
459 if (! buffer_time || ! period_time) {
460 printf(_("Periods = %u\n"), nperiods);
461 err = snd_pcm_hw_params_set_periods_near(handle, params, &nperiods, NULL);
463 fprintf(stderr, _("Unable to set nperiods %u for playback: %s\n"),
464 nperiods, snd_strerror(err));
469 /* write the parameters to device */
470 err = snd_pcm_hw_params(handle, params);
472 fprintf(stderr, _("Unable to set hw params for playback: %s\n"), snd_strerror(err));
476 snd_pcm_hw_params_get_buffer_size(params, &buffer_size);
477 snd_pcm_hw_params_get_period_size(params, &period_size, NULL);
478 printf(_("was set period_size = %lu\n"),period_size);
479 printf(_("was set buffer_size = %lu\n"),buffer_size);
480 if (2*period_size > buffer_size) {
481 fprintf(stderr, _("buffer to small, could not use\n"));
488 static int set_swparams(snd_pcm_t *handle, snd_pcm_sw_params_t *swparams) {
491 /* get the current swparams */
492 err = snd_pcm_sw_params_current(handle, swparams);
494 fprintf(stderr, _("Unable to determine current swparams for playback: %s\n"), snd_strerror(err));
498 /* start the transfer when a buffer is full */
499 err = snd_pcm_sw_params_set_start_threshold(handle, swparams, buffer_size);
501 fprintf(stderr, _("Unable to set start threshold mode for playback: %s\n"), snd_strerror(err));
505 /* allow the transfer when at least period_size frames can be processed */
506 err = snd_pcm_sw_params_set_avail_min(handle, swparams, period_size);
508 fprintf(stderr, _("Unable to set avail min for playback: %s\n"), snd_strerror(err));
512 /* write the parameters to the playback device */
513 err = snd_pcm_sw_params(handle, swparams);
515 fprintf(stderr, _("Unable to set sw params for playback: %s\n"), snd_strerror(err));
523 * Underrun and suspend recovery
526 static int xrun_recovery(snd_pcm_t *handle, int err) {
527 if (err == -EPIPE) { /* under-run */
528 err = snd_pcm_prepare(handle);
530 fprintf(stderr, _("Can't recovery from underrun, prepare failed: %s\n"), snd_strerror(err));
533 else if (err == -ESTRPIPE) {
535 while ((err = snd_pcm_resume(handle)) == -EAGAIN)
536 sleep(1); /* wait until the suspend flag is released */
539 err = snd_pcm_prepare(handle);
541 fprintf(stderr, _("Can't recovery from suspend, prepare failed: %s\n"), snd_strerror(err));
554 static const char *wav_file[MAX_CHANNELS];
555 static int wav_file_size[MAX_CHANNELS];
571 uint32_t bytes_per_sec;
572 uint16_t sample_size;
573 uint16_t sample_bits;
581 #define WAV_RIFF COMPOSE_ID('R','I','F','F')
582 #define WAV_WAVE COMPOSE_ID('W','A','V','E')
583 #define WAV_FMT COMPOSE_ID('f','m','t',' ')
584 #define WAV_DATA COMPOSE_ID('d','a','t','a')
585 #define WAV_PCM_CODE 1
587 static const char *search_for_file(const char *name)
592 file = malloc(strlen(wav_file_dir) + strlen(name) + 2);
594 sprintf(file, "%s/%s", wav_file_dir, name);
598 static int check_wav_file(int channel, const char *name)
600 struct wave_header header;
603 wav_file[channel] = search_for_file(name);
604 if (! wav_file[channel]) {
605 fprintf(stderr, _("No enough memory\n"));
609 if ((fd = open(wav_file[channel], O_RDONLY)) < 0) {
610 fprintf(stderr, _("Cannot open WAV file %s\n"), wav_file[channel]);
613 if (read(fd, &header, sizeof(header)) < (int)sizeof(header)) {
614 fprintf(stderr, _("Invalid WAV file %s\n"), wav_file[channel]);
618 if (header.hdr.magic != WAV_RIFF || header.hdr.type != WAV_WAVE) {
619 fprintf(stderr, _("Not a WAV file: %s\n"), wav_file[channel]);
622 if (header.body.format != LE_SHORT(WAV_PCM_CODE)) {
623 fprintf(stderr, _("Unsupported WAV format %d for %s\n"),
624 LE_SHORT(header.body.format), wav_file[channel]);
627 if (header.body.channels != LE_SHORT(1)) {
628 fprintf(stderr, _("%s is not a mono stream (%d channels)\n"),
629 wav_file[channel], LE_SHORT(header.body.channels));
632 if (header.body.rate != LE_INT(rate)) {
633 fprintf(stderr, _("Sample rate doesn't match (%d) for %s\n"),
634 LE_INT(header.body.rate), wav_file[channel]);
637 if (header.body.sample_bits != LE_SHORT(16)) {
638 fprintf(stderr, _("Unsupported sample format bits %d for %s\n"),
639 LE_SHORT(header.body.sample_bits), wav_file[channel]);
642 if (header.chunk.type != WAV_DATA) {
643 fprintf(stderr, _("Invalid WAV file %s\n"), wav_file[channel]);
646 wav_file_size[channel] = LE_INT(header.chunk.length);
655 static int setup_wav_file(int chn)
657 static const char *const wavs[MAX_CHANNELS] = {
663 "Rear_Center.wav", /* FIXME: should be "Bass" or so */
676 if (given_test_wav_file)
677 return check_wav_file(chn, given_test_wav_file);
679 return check_wav_file(chn, wavs[chn]);
682 static int read_wav(uint16_t *buf, int channel, int offset, int bufsize)
684 static FILE *wavfp = NULL;
687 if (! wav_file[channel]) {
688 fprintf(stderr, _("Undefined channel %d\n"), channel);
692 if (offset >= wav_file_size[channel])
693 return 0; /* finished */
698 wavfp = fopen(wav_file[channel], "r");
701 if (fseek(wavfp, sizeof(struct wave_header), SEEK_SET) < 0)
704 if (offset + bufsize > wav_file_size[channel])
705 bufsize = wav_file_size[channel] - offset;
707 for (size = 0; size < bufsize; size += 2) {
709 for (chn = 0; chn < channels; chn++) {
710 if (chn == channel) {
711 if (fread(buf, 2, 1, wavfp) != 1)
724 * Transfer method - write only
727 static int write_buffer(snd_pcm_t *handle, uint8_t *ptr, int cptr)
733 err = snd_pcm_writei(handle, ptr, cptr);
739 fprintf(stderr, _("Write error: %d,%s\n"), err, snd_strerror(err));
740 if (xrun_recovery(handle, err) < 0) {
741 fprintf(stderr, _("xrun_recovery failed: %d,%s\n"), err, snd_strerror(err));
744 break; /* skip one period */
747 ptr += snd_pcm_frames_to_bytes(handle, err);
753 static int write_loop(snd_pcm_t *handle, int channel, int periods, uint8_t *frames)
760 if (test_type == TEST_WAV) {
761 int bufsize = snd_pcm_frames_to_bytes(handle, period_size);
763 while ((err = read_wav((uint16_t *)frames, channel, n, bufsize)) > 0) {
765 if ((err = write_buffer(handle, frames,
766 snd_pcm_bytes_to_frames(handle, err * channels))) < 0)
769 if (buffer_size > n) {
770 snd_pcm_drain(handle);
771 snd_pcm_prepare(handle);
780 for(n = 0; n < periods; n++) {
781 if (test_type == TEST_PINK_NOISE)
782 generate_pink_noise(frames, channel, period_size);
783 else if (test_type == TEST_PATTERN)
784 generate_pattern(frames, channel, period_size, &pattern);
786 generate_sine(frames, channel, period_size, &phase);
788 if ((err = write_buffer(handle, frames, period_size)) < 0)
791 if (buffer_size > n * period_size) {
792 snd_pcm_drain(handle);
793 snd_pcm_prepare(handle);
798 static void help(void)
803 _("Usage: speaker-test [OPTION]... \n"
805 "-D,--device playback device\n"
806 "-r,--rate stream rate in Hz\n"
807 "-c,--channels count of channels in stream\n"
808 "-f,--frequency sine wave frequency in Hz\n"
809 "-F,--format sample format\n"
810 "-b,--buffer ring buffer size in us\n"
811 "-p,--period period size in us\n"
812 "-P,--nperiods number of periods\n"
813 "-t,--test pink=use pink noise, sine=use sine wave, wav=WAV file\n"
814 "-l,--nloops specify number of loops to test, 0 = infinite\n"
815 "-s,--speaker single speaker test. Values 1=Left, 2=right, etc\n"
816 "-w,--wavfile Use the given WAV file as a test sound\n"
817 "-W,--wavdir Specify the directory containing WAV files\n"
819 printf(_("Recognized sample formats are:"));
820 for (fmt = supported_formats; *fmt >= 0; fmt++) {
821 const char *s = snd_pcm_format_name(*fmt);
829 int main(int argc, char *argv[]) {
832 snd_pcm_hw_params_t *hwparams;
833 snd_pcm_sw_params_t *swparams;
837 double time1,time2,time3;
838 unsigned int n, nloops;
839 struct timeval tv1,tv2;
841 static const struct option long_option[] = {
842 {"help", 0, NULL, 'h'},
843 {"device", 1, NULL, 'D'},
844 {"rate", 1, NULL, 'r'},
845 {"channels", 1, NULL, 'c'},
846 {"frequency", 1, NULL, 'f'},
847 {"format", 1, NULL, 'F'},
848 {"buffer", 1, NULL, 'b'},
849 {"period", 1, NULL, 'p'},
850 {"nperiods", 1, NULL, 'P'},
851 {"test", 1, NULL, 't'},
852 {"nloops", 1, NULL, 'l'},
853 {"speaker", 1, NULL, 's'},
854 {"wavfile", 1, NULL, 'w'},
855 {"wavdir", 1, NULL, 'W'},
856 {"debug", 0, NULL, 'd'},
861 setlocale(LC_ALL, "");
865 snd_pcm_hw_params_alloca(&hwparams);
866 snd_pcm_sw_params_alloca(&swparams);
871 printf("\nspeaker-test %s\n\n", SND_UTIL_VERSION_STR);
875 if ((c = getopt_long(argc, argv, "hD:r:c:f:F:b:p:P:t:l:s:w:W:d", long_option, NULL)) < 0)
883 device = strdup(optarg);
886 format = snd_pcm_format_value(optarg);
887 for (fmt = supported_formats; *fmt >= 0; fmt++)
891 fprintf(stderr, "Format %s is not supported...\n", snd_pcm_format_name(format));
897 rate = rate < 4000 ? 4000 : rate;
898 rate = rate > 196000 ? 196000 : rate;
901 channels = atoi(optarg);
902 channels = channels < 1 ? 1 : channels;
903 channels = channels > 1024 ? 1024 : channels;
907 freq = freq < 30.0 ? 30.0 : freq;
908 freq = freq > 5000.0 ? 5000.0 : freq;
911 buffer_time = atoi(optarg);
912 buffer_time = buffer_time > 1000000 ? 1000000 : buffer_time;
915 period_time = atoi(optarg);
916 period_time = period_time > 1000000 ? 1000000 : period_time;
919 nperiods = atoi(optarg);
920 if (nperiods < 2 || nperiods > 1024) {
921 fprintf(stderr, _("Invalid number of periods %d\n"), nperiods);
927 test_type = TEST_PINK_NOISE;
928 else if (*optarg == 's')
929 test_type = TEST_SINE;
930 else if (*optarg == 'w')
931 test_type = TEST_WAV;
932 else if (*optarg == 't')
933 test_type = TEST_PATTERN;
934 else if (isdigit(*optarg)) {
935 test_type = atoi(optarg);
936 if (test_type < TEST_PINK_NOISE || test_type > TEST_PATTERN) {
937 fprintf(stderr, _("Invalid test type %s\n"), optarg);
941 fprintf(stderr, _("Invalid test type %s\n"), optarg);
946 nloops = atoi(optarg);
949 speaker = atoi(optarg);
950 speaker = speaker < 1 ? 0 : speaker;
951 speaker = speaker > channels ? 0 : speaker;
953 fprintf(stderr, _("Invalid parameter for -s option.\n"));
958 given_test_wav_file = optarg;
961 wav_file_dir = optarg;
967 fprintf(stderr, _("Unknown option '%c'\n"), c);
978 if (test_type == TEST_WAV)
979 format = SND_PCM_FORMAT_S16_LE; /* fixed format */
981 printf(_("Playback device is %s\n"), device);
982 printf(_("Stream parameters are %iHz, %s, %i channels\n"), rate, snd_pcm_format_name(format), channels);
984 case TEST_PINK_NOISE:
985 printf(_("Using 16 octaves of pink noise\n"));
988 printf(_("Sine wave rate is %.4fHz\n"), freq);
991 printf(_("WAV file(s)\n"));
996 if ((err = snd_pcm_open(&handle, device, SND_PCM_STREAM_PLAYBACK, 0)) < 0) {
997 printf(_("Playback open error: %d,%s\n"), err,snd_strerror(err));
1001 if ((err = set_hwparams(handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
1002 printf(_("Setting of hwparams failed: %s\n"), snd_strerror(err));
1003 snd_pcm_close(handle);
1006 if ((err = set_swparams(handle, swparams)) < 0) {
1007 printf(_("Setting of swparams failed: %s\n"), snd_strerror(err));
1008 snd_pcm_close(handle);
1013 err = snd_output_stdio_attach(&log, stderr, 0);
1015 snd_pcm_dump(handle, log);
1016 snd_output_close(log);
1020 frames = malloc(snd_pcm_frames_to_bytes(handle, period_size));
1021 if (test_type == TEST_PINK_NOISE)
1022 initialize_pink_noise(&pink, 16);
1024 if (frames == NULL) {
1025 fprintf(stderr, _("No enough memory\n"));
1030 if (test_type == TEST_WAV) {
1031 for (chn = 0; chn < channels; chn++) {
1032 if (setup_wav_file(chn) < 0)
1037 for (n = 0; ! nloops || n < nloops; n++) {
1039 gettimeofday(&tv1, NULL);
1040 for(chn = 0; chn < channels; chn++) {
1042 if (channels == 4) {
1043 channel=channels4[chn];
1045 if (channels == 6) {
1046 channel=channels6[chn];
1048 if (channels == 8) {
1049 channel=channels8[chn];
1051 printf(" %d - %s\n", channel, gettext(channel_name[channel]));
1053 err = write_loop(handle, channel, ((rate*3)/period_size), frames);
1056 fprintf(stderr, _("Transfer failed: %s\n"), snd_strerror(err));
1058 snd_pcm_close(handle);
1062 gettimeofday(&tv2, NULL);
1063 time1 = (double)tv1.tv_sec + ((double)tv1.tv_usec / 1000000.0);
1064 time2 = (double)tv2.tv_sec + ((double)tv2.tv_usec / 1000000.0);
1065 time3 = time2 - time1;
1066 printf(_("Time per period = %lf\n"), time3 );
1069 if (test_type == TEST_WAV) {
1070 if (setup_wav_file(speaker - 1) < 0)
1074 printf(" - %s\n", gettext(channel_name[speaker-1]));
1075 err = write_loop(handle, speaker-1, ((rate*5)/period_size), frames);
1078 fprintf(stderr, _("Transfer failed: %s\n"), snd_strerror(err));
1084 snd_pcm_close(handle);