88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore/*
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore * CDDL HEADER START
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore *
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore * The contents of this file are subject to the terms of the
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore * Common Development and Distribution License (the "License").
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore * You may not use this file except in compliance with the License.
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore *
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore * or http://www.opensolaris.org/os/licensing.
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore * See the License for the specific language governing permissions
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore * and limitations under the License.
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore *
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore * When distributing Covered Code, include this CDDL HEADER in each
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore * If applicable, add the following below this CDDL HEADER, with the
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore * fields enclosed by brackets "[]" replaced with your own identifying
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore * information: Portions Copyright [yyyy] [name of copyright owner]
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore *
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore * CDDL HEADER END
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore */
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore/*
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore * Copyright (C) 4Front Technologies 1996-2008.
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore *
a33ad26ef1f3b7a3fcf2fad564e6bd3798fdcbaeZhao Edgar Liu - Sun Microsystems * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore */
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore/*
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore * This program is a general purpose test facility for audio output.
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore * It does not test record.
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore *
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore * The wavedata.c and wavedata.h files contain the actual samples compressed
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore * using the MS ADPCM algorithm.
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore */
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore#include <stdio.h>
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore#include <stdlib.h>
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore#include <unistd.h>
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore#include <fcntl.h>
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore#include <string.h>
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore#include <errno.h>
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore#include <unistd.h>
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore#include <sys/time.h>
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore#include <sys/ioctl.h>
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore#include <sys/utsname.h>
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore#include <sys/soundcard.h>
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore#include <inttypes.h>
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore#include <locale.h>
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore#if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore#define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore#endif
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore#define _(s) gettext(s)
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore/*
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore * Channel selectors
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore */
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore#define CH_LEFT (1 << 0)
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore#define CH_RIGHT (1 << 1)
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore#define CH_LREAR4 (1 << 2) /* quadraphonic */
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore#define CH_RREAR4 (1 << 3) /* quadraphonic */
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore#define CH_CENTER (1 << 2)
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore#define CH_LFE (1 << 3)
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore#define CH_LSURR (1 << 4)
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore#define CH_RSURR (1 << 5)
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore#define CH_LREAR (1 << 6)
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore#define CH_RREAR (1 << 7)
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore#define CH_STEREO (CH_LEFT|CH_RIGHT)
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore#define CH_4 (CH_STEREO | CH_LREAR4 | CH_RREAR4)
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore#define CH_5 (CH_STEREO | CH_CENTER | CH_LSURR | CH_RSURR)
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore#define CH_7 (CH_5 | CH_LREAR | CH_RREAR)
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amoretypedef struct chancfg {
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore int mask;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore const char *name;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore unsigned flags;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore int16_t *data;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore int len;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore} chancfg_t;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amoretypedef struct testcfg {
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore int nchan;
a33ad26ef1f3b7a3fcf2fad564e6bd3798fdcbaeZhao Edgar Liu - Sun Microsystems uint32_t rate;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore chancfg_t *tests[16];
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore} testcfg_t;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore#define CFLAG_LFE 0x1 /* lfe channel - not full range */
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore/*
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore * TRANSLATION_NOTE : The following strings are displayed during progress.
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore * Its important for alignment that they have the same displayed length.
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore */
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore#define NM_LEFT "\t<left> ................"
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore#define NM_RIGHT "\t<right> ..............."
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore#define NM_LREAR "\t<left rear> ..........."
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore#define NM_RREAR "\t<right rear> .........."
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore#define NM_LSIDE "\t<left side> ..........."
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore#define NM_RSIDE "\t<right side> .........."
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore#define NM_CENTER "\t<center> .............."
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore#define NM_LFE "\t<lfe> ................."
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore#define NM_STEREO "\t<stereo> .............."
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore#define NM_40 "\t<4.0 surround> ........"
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore#define NM_50 "\t<5.0 surround> ........"
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore#define NM_70 "\t<7.0 surround> ........"
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amorechancfg_t ch_left = { CH_LEFT, NM_LEFT, 0 };
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amorechancfg_t ch_right = { CH_RIGHT, NM_RIGHT, 0 };
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amorechancfg_t ch_stereo = { CH_STEREO, NM_STEREO, 0 };
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amorechancfg_t ch_center = { CH_CENTER, NM_CENTER, 0 };
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amorechancfg_t ch_lfe = { CH_LFE, NM_LFE, CFLAG_LFE };
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amorechancfg_t ch_lsurr_4 = { (1 << 2), NM_LREAR, 0 };
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amorechancfg_t ch_rsurr_4 = { (1 << 3), NM_RREAR, 0 };
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amorechancfg_t ch_4 = { CH_4, NM_40, 0 };
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amorechancfg_t ch_lsurr_5 = { CH_LSURR, NM_LREAR, 0 };
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amorechancfg_t ch_rsurr_5 = { CH_RSURR, NM_RREAR, 0 };
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amorechancfg_t ch_5 = { CH_5, NM_50, 0 };
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amorechancfg_t ch_lsurr_7 = { CH_LSURR, NM_LSIDE, 0 };
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amorechancfg_t ch_rsurr_7 = { CH_RSURR, NM_RSIDE, 0 };
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amorechancfg_t ch_lrear_7 = { CH_LREAR, NM_LREAR, 0 };
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amorechancfg_t ch_rrear_7 = { CH_RREAR, NM_RREAR, 0 };
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amorechancfg_t ch_7 = { CH_7, NM_70, 0 };
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amoretestcfg_t test_stereo = {
a33ad26ef1f3b7a3fcf2fad564e6bd3798fdcbaeZhao Edgar Liu - Sun Microsystems 2, 48000, { &ch_left, &ch_right, &ch_stereo, NULL }
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore};
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amoretestcfg_t test_quad = {
a33ad26ef1f3b7a3fcf2fad564e6bd3798fdcbaeZhao Edgar Liu - Sun Microsystems 4, 48000, { &ch_left, &ch_right, &ch_stereo,
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore &ch_lsurr_4, &ch_rsurr_4, &ch_4, NULL }
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore};
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amoretestcfg_t test_51 = {
a33ad26ef1f3b7a3fcf2fad564e6bd3798fdcbaeZhao Edgar Liu - Sun Microsystems 6, 48000, { &ch_left, &ch_right, &ch_stereo,
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore &ch_lsurr_5, &ch_rsurr_5, &ch_center, &ch_lfe, &ch_5, NULL }
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore};
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amoretestcfg_t test_71 = {
a33ad26ef1f3b7a3fcf2fad564e6bd3798fdcbaeZhao Edgar Liu - Sun Microsystems 8, 48000, { &ch_left, &ch_right, &ch_stereo,
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore &ch_lsurr_7, &ch_rsurr_7, &ch_lrear_7, &ch_rrear_7,
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore &ch_center, &ch_lfe, &ch_7, NULL }
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore};
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore/*
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore * uncompress_wave() is defined in wavedata.c. It expands the audio
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore * samples stored in wavedata.h and returns the lenghth of the
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore * uncompressed version in bytes.
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore *
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore * The uncompressed wave data format is 16 bit (native) stereo
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore * recorded at 48000 Hz.
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore */
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amoreextern int uncompress_wave(short *outbuf);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amorestatic int data_len;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore#define MAXDEVICE 64
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amoreextern void describe_error(int);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore#define SAMPLE_RATE 48000
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore/*
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore * Operating mode flags (set from the command line).
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore */
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore#define TF_LOOP 0x00000010 /* Loop until interrupted */
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amorestatic int mixerfd;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amorestatic int num_devices_tested = 0;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amorestatic short *sample_buf;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amorevoid
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amoreprepare(testcfg_t *tcfg)
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore{
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore int nsamples;
a33ad26ef1f3b7a3fcf2fad564e6bd3798fdcbaeZhao Edgar Liu - Sun Microsystems int i, j;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore chancfg_t *ccfg;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore if ((sample_buf = malloc(2000000)) == NULL) {
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore perror("malloc");
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore exit(-1);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore }
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore data_len = uncompress_wave(sample_buf);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore nsamples = (data_len / sizeof (int16_t)) / 2;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore for (i = 0; (ccfg = tcfg->tests[i]) != NULL; i++) {
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore int16_t *src, *dst;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore int ch;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore int samp;
a33ad26ef1f3b7a3fcf2fad564e6bd3798fdcbaeZhao Edgar Liu - Sun Microsystems int rate_multiple;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore src = sample_buf;
a33ad26ef1f3b7a3fcf2fad564e6bd3798fdcbaeZhao Edgar Liu - Sun Microsystems rate_multiple = tcfg->rate / 48000;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore if (ccfg->flags != CFLAG_LFE) {
a33ad26ef1f3b7a3fcf2fad564e6bd3798fdcbaeZhao Edgar Liu - Sun Microsystems ccfg->len = nsamples * tcfg->nchan *
a33ad26ef1f3b7a3fcf2fad564e6bd3798fdcbaeZhao Edgar Liu - Sun Microsystems sizeof (int16_t) * rate_multiple;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore ccfg->data = malloc(ccfg->len);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore if ((dst = ccfg->data) == NULL) {
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore perror("malloc");
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore exit(-1);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore }
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore for (samp = 0; samp < nsamples; samp++) {
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore for (ch = 0; ch < tcfg->nchan; ch++) {
a33ad26ef1f3b7a3fcf2fad564e6bd3798fdcbaeZhao Edgar Liu - Sun Microsystems for (j = 0; j < rate_multiple; j++) {
a33ad26ef1f3b7a3fcf2fad564e6bd3798fdcbaeZhao Edgar Liu - Sun Microsystems *dst = ((1U << ch) & ccfg->mask)
a33ad26ef1f3b7a3fcf2fad564e6bd3798fdcbaeZhao Edgar Liu - Sun Microsystems ? *src : 0;
a33ad26ef1f3b7a3fcf2fad564e6bd3798fdcbaeZhao Edgar Liu - Sun Microsystems dst++;
a33ad26ef1f3b7a3fcf2fad564e6bd3798fdcbaeZhao Edgar Liu - Sun Microsystems }
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore }
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore src += 2;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore }
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore } else {
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore /* Skip LFE for now */
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore ccfg->len = 0;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore }
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore }
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore}
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore/*
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore * The testdsp() routine checks the capabilities of a given audio device number
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore * (parameter n) and decides if the test sound needs to be played.
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore */
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore/*ARGSUSED*/
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amoreint
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amoretestdsp(int hd, int flags, testcfg_t *tcfg)
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore{
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore float ratio;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore struct timeval t1, t2;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore unsigned long t;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore int sample_rate;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore int delay;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore long long total_bytes = 0;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore unsigned int tmp, caps;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore int i;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore chancfg_t *ccfg;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore caps = 0;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore if (ioctl(hd, SNDCTL_DSP_GETCAPS, &caps) == -1) {
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore perror("SNDCTL_DSP_GETCAPS");
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore return (-1);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore }
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore /*
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore * Setup the sample format. Since OSS will support AFMT_S16_NE
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore * regardless of the device we do not need to support any
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore * other formats.
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore */
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore tmp = AFMT_S16_NE;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore if (ioctl(hd, SNDCTL_DSP_SETFMT, &tmp) == -1 || tmp != AFMT_S16_NE) {
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore (void) printf(_("Device doesn't support native 16-bit PCM\n"));
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore return (-1);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore }
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore /*
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore * Setup the device for channels. Once again we can simply
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore * assume that stereo will always work before OSS takes care
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore * of this by emulation if necessary.
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore */
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore tmp = tcfg->nchan;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore if (ioctl(hd, SNDCTL_DSP_CHANNELS, &tmp) == -1 || tmp != tcfg->nchan) {
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore (void) printf(_("The device doesn't support %d channels\n"),
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore tcfg->nchan);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore return (-2);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore }
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore /*
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore * Set up the sample rate.
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore */
a33ad26ef1f3b7a3fcf2fad564e6bd3798fdcbaeZhao Edgar Liu - Sun Microsystems tmp = tcfg->rate;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore if (ioctl(hd, SNDCTL_DSP_SPEED, &tmp) == -1) {
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore perror("SNDCTL_DSP_SPEED");
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore return (-3);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore }
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore sample_rate = tmp;
a33ad26ef1f3b7a3fcf2fad564e6bd3798fdcbaeZhao Edgar Liu - Sun Microsystems if (sample_rate != tcfg->rate) {
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore (void) printf(_("The device doesn't support %d Hz\n"),
a33ad26ef1f3b7a3fcf2fad564e6bd3798fdcbaeZhao Edgar Liu - Sun Microsystems tcfg->rate);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore return (-3);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore }
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore (void) printf("\n");
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore /*
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore * This program will measure the real sampling rate by
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore * computing the total time required to play the sample.
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore *
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore * This is not terribly presice with short test sounds but it
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore * can be used to detect if the sampling rate badly
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore * wrong. Errors of few percents is more likely to be caused
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore * by poor accuracy of the system clock rather than problems
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore * with the sampling rate.
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore */
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore (void) gettimeofday(&t1, NULL);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore for (i = 0; (ccfg = tcfg->tests[i]) != NULL; i++) {
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore (void) fputs(_(ccfg->name), stdout);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore (void) fflush(stdout);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore if (ccfg->flags & CFLAG_LFE) {
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore (void) printf(_("SKIPPED\n"));
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore continue;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore }
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore if (write(hd, ccfg->data, ccfg->len) < 0) {
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore (void) printf(_("ERROR: %s\n"),
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore strerror(errno));
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore return (-3);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore }
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore (void) printf(_("OK\n"));
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore total_bytes += ccfg->len;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore }
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore (void) gettimeofday(&t2, NULL);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore delay = 0;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore (void) ioctl(hd, SNDCTL_DSP_GETODELAY, &delay); /* Ignore errors */
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore /*
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore * Perform the time computations using milliseconds.
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore */
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore t = t2.tv_sec - t1.tv_sec;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore t *= 1000;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore t += t2.tv_usec / 1000;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore t -= t1.tv_usec / 1000;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore total_bytes -= delay;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore total_bytes *= 1000;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore total_bytes /= t;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore total_bytes /= (tcfg->nchan * sizeof (int16_t));
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore ratio = ((float)total_bytes / (float)sample_rate) * 100.0;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore (void) printf(_("\t<measured sample rate %8.2f Hz (%4.2f%%)>\n"),
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore (float)sample_rate * ratio / 100.0, ratio - 100.0);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore num_devices_tested++;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore return (1);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore}
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amorestatic int
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amorefind_num_devices(void)
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore{
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore oss_sysinfo info;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore struct utsname un;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore /*
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore * Find out the number of available audio devices by calling
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore * SNDCTL_SYSINFO.
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore */
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore if (ioctl(mixerfd, SNDCTL_SYSINFO, &info) == -1) {
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore if (errno == ENXIO) {
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore (void) fprintf(stderr,
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore _("No supported sound hardware detected.\n"));
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore exit(-1);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore } else {
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore perror("SNDCTL_SYSINFO");
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore (void) printf(_("Cannot get system information.\n"));
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore exit(-1);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore }
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore }
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore (void) printf(_("Sound subsystem and version: %s %s (0x%08X)\n"),
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore info.product, info.version, info.versionnum);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore if (uname(&un) != -1)
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore (void) printf(_("Platform: %s %s %s %s\n"),
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore un.sysname, un.release, un.version, un.machine);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore return (info.numaudios);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore}
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore/*
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore * The test_device() routine checks certain information about the device
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore * and calls testdsp() to play the test sound.
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore */
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amoreint
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amoretest_device(char *dn, int flags, testcfg_t *tcfg)
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore{
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore oss_audioinfo ainfo;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore int code;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore int fd;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore fd = open(dn, O_WRONLY, 0);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore if (fd == -1) {
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore int err = errno;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore perror(dn);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore errno = err;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore describe_error(errno);
68c47f65208790c466e5e484f2293d3baed71c6aGarrett D'Amore return (-1);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore }
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore ainfo.dev = -1;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore if (ioctl(fd, SNDCTL_AUDIOINFO, &ainfo) == -1) {
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore perror("SNDCTL_AUDIOINFO");
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore (void) close(fd);
68c47f65208790c466e5e484f2293d3baed71c6aGarrett D'Amore return (-1);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore }
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore (void) printf(_("\n*** Scanning sound adapter #%d ***\n"),
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore ainfo.card_number);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore (void) printf(_("%s (audio engine %d): %s\n"), ainfo.devnode, ainfo.dev,
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore ainfo.name);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore if (!ainfo.enabled) {
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore (void) printf(_(" - Device not present - Skipping\n"));
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore (void) close(fd);
68c47f65208790c466e5e484f2293d3baed71c6aGarrett D'Amore return (0);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore }
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore if (!(ainfo.caps & PCM_CAP_OUTPUT)) {
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore (void) printf(_(" - Skipping input only device\n"));
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore (void) close(fd);
68c47f65208790c466e5e484f2293d3baed71c6aGarrett D'Amore return (0);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore }
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore (void) printf(_(" - Performing audio playback test... "));
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore (void) fflush(stdout);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore code = testdsp(fd, flags, tcfg);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore (void) close(fd);
68c47f65208790c466e5e484f2293d3baed71c6aGarrett D'Amore if (code < 0) {
68c47f65208790c466e5e484f2293d3baed71c6aGarrett D'Amore return (code);
68c47f65208790c466e5e484f2293d3baed71c6aGarrett D'Amore }
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore return (code == 1);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore}
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amorevoid
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amoredescribe_error(int err)
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore{
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore switch (err) {
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore case ENODEV:
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore (void) fprintf(stderr,
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore _("The device file was found in /dev but\n"
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore "the driver was not loaded.\n"));
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore break;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore case ENXIO:
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore (void) fprintf(stderr,
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore _("There are no sound devices available.\n"
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore "The most likely reason is that the device you have\n"
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore "is malfunctioning or it's not supported.\n"
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore "It's also possible that you are trying to use the wrong "
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore "device file.\n"));
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore break;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore case ENOSPC:
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore (void) fprintf(stderr,
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore _("Your system cannot allocate memory for the device\n"
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore "buffers. Reboot your machine and try again.\n"));
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore break;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore case ENOENT:
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore (void) fprintf(stderr,
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore _("The device file is missing from /dev.\n"));
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore break;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore case EBUSY:
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore (void) fprintf(stderr,
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore _("The device is busy. There is some other application\n"
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore "using it.\n"));
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore break;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore default:
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore break;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore }
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore}
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amoreint
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amoremain(int argc, char *argv[])
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore{
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore int t, i;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore int maxdev;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore int flags = 0;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore int status = 0;
68c47f65208790c466e5e484f2293d3baed71c6aGarrett D'Amore int errors = 0;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore int numdev;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore extern int optind;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore testcfg_t *tcfg;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore (void) setlocale(LC_ALL, "");
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore (void) textdomain(TEXT_DOMAIN);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore tcfg = &test_stereo;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore /*
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore * Simple command line switch handling.
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore */
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
a33ad26ef1f3b7a3fcf2fad564e6bd3798fdcbaeZhao Edgar Liu - Sun Microsystems while ((i = getopt(argc, argv, "l2457r:")) != EOF) {
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore switch (i) {
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore case 'l':
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore flags |= TF_LOOP;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore break;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore case '2':
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore tcfg = &test_stereo;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore break;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore case '4':
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore tcfg = &test_quad;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore break;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore case '5':
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore tcfg = &test_51;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore break;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore case '7':
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore tcfg = &test_71;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore break;
a33ad26ef1f3b7a3fcf2fad564e6bd3798fdcbaeZhao Edgar Liu - Sun Microsystems case 'r':
a33ad26ef1f3b7a3fcf2fad564e6bd3798fdcbaeZhao Edgar Liu - Sun Microsystems tcfg->rate = atoi(optarg);
a33ad26ef1f3b7a3fcf2fad564e6bd3798fdcbaeZhao Edgar Liu - Sun Microsystems break;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore default:
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore (void) printf(_("Usage: %s [options...] [device]\n"
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore " -2 Stereo test\n"
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore " -4 Quadraphonic 4.0 test\n"
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore " -5 Surround 5.1 test\n"
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore " -7 Surround 7.1 test\n"
a33ad26ef1f3b7a3fcf2fad564e6bd3798fdcbaeZhao Edgar Liu - Sun Microsystems " -r Sample Rate (48000|96000|192000)\n"
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore " -l Loop test\n"), argv[0]);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore exit(-1);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore }
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore }
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore /*
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore * Open the mixer device used for calling SNDCTL_SYSINFO and
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore * SNDCTL_AUDIOINFO.
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore */
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore if ((mixerfd = open("/dev/mixer", O_RDWR, 0)) == -1) {
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore int err = errno;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore perror("/dev/mixer");
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore errno = err;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore describe_error(errno);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore exit(-1);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore }
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore prepare(tcfg); /* Prepare the wave data */
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore /*
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore * Enumerate all devices and play the test sounds.
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore */
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore maxdev = find_num_devices();
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore if (maxdev < 1) {
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore (void) printf(_("\n*** No audio hardware available ***\n"));
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore exit(-1);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore }
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore numdev = (argc - optind);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore do {
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore char *dn;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore oss_audioinfo ainfo;
68c47f65208790c466e5e484f2293d3baed71c6aGarrett D'Amore int rv;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
68c47f65208790c466e5e484f2293d3baed71c6aGarrett D'Amore status = 0;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore if (numdev > 0) {
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore for (t = 0; t < numdev; t++) {
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore dn = argv[optind + t];
68c47f65208790c466e5e484f2293d3baed71c6aGarrett D'Amore rv = test_device(dn, flags, tcfg);
68c47f65208790c466e5e484f2293d3baed71c6aGarrett D'Amore if (rv < 0) {
68c47f65208790c466e5e484f2293d3baed71c6aGarrett D'Amore errors++;
68c47f65208790c466e5e484f2293d3baed71c6aGarrett D'Amore } else if (rv) {
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore status++;
68c47f65208790c466e5e484f2293d3baed71c6aGarrett D'Amore }
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore }
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore } else {
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore for (t = 0; t < maxdev; t++) {
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore ainfo.dev = t;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore if (ioctl(mixerfd, SNDCTL_AUDIOINFO,
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore &ainfo) == -1) {
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore perror("SNDCTL_AUDIOINFO");
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore status++;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore continue;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore }
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore dn = ainfo.devnode;
68c47f65208790c466e5e484f2293d3baed71c6aGarrett D'Amore rv = test_device(dn, flags, tcfg);
68c47f65208790c466e5e484f2293d3baed71c6aGarrett D'Amore if (rv < 0) {
68c47f65208790c466e5e484f2293d3baed71c6aGarrett D'Amore errors++;
68c47f65208790c466e5e484f2293d3baed71c6aGarrett D'Amore } else if (rv) {
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore status++;
68c47f65208790c466e5e484f2293d3baed71c6aGarrett D'Amore }
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore }
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore }
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
68c47f65208790c466e5e484f2293d3baed71c6aGarrett D'Amore if (errors == 0)
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore (void) printf(_("\n*** All tests completed OK ***\n"));
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore else
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore (void) printf(_("\n*** Errors were detected ***\n"));
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
68c47f65208790c466e5e484f2293d3baed71c6aGarrett D'Amore } while (status && (flags & TF_LOOP));
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore (void) close(mixerfd);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore return (status);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore}