1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
|
/*
* Purpose: A simple demonstration of
* Copyright (C) 4Front Technologies, 2007. All rights reserved.
*
* Description:
* This program is seriously broken. It's only purpose is to fail so that
* the !nlink SNDCTL_DSP_GETERROR} ioctl call can be tested. Otherwise this
* program is based on the {!nlink singen.c} program.
*
* However this program demonstrates how SNDCTL_DSP_GETERROR can be used in
* applications.
*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <soundcard.h>
int fd_out;
static int
open_audio_device (char *name, int mode)
{
int tmp, fd;
int sample_rate;
if ((fd = open (name, mode, 0)) == -1)
{
perror (name);
exit (-1);
}
/*
* Setup the device. Note that it's important to set the
* sample format, number of channels and sample rate exactly in this order.
* Some devices depend on the order.
*/
/*
* Set the sample format
*/
tmp = AFMT_S16_NE; /* Native 16 bits */
if (ioctl (fd, SNDCTL_DSP_SETFMT, &tmp) == -1)
{
perror ("SNDCTL_DSP_SETFMT");
exit (-1);
}
if (tmp != AFMT_S16_NE)
{
fprintf (stderr,
"The device doesn't support the 16 bit sample format.\n");
exit (-1);
}
/*
* Set the number of channels
*/
tmp = 1;
if (ioctl (fd, SNDCTL_DSP_CHANNELS, &tmp) == -1)
{
perror ("SNDCTL_DSP_CHANNELS");
exit (-1);
}
if (tmp != 1)
{
fprintf (stderr, "The device doesn't support mono mode.\n");
exit (-1);
}
/*
* Set the sample rate
*/
sample_rate = 48000;
if (ioctl (fd, SNDCTL_DSP_SPEED, &sample_rate) == -1)
{
perror ("SNDCTL_DSP_SPEED");
exit (-1);
}
/*
* No need for error checking because we will automatically adjust the
* signal based on the actual sample rate. However most application must
* check the value of sample_rate and compare it to the requested rate.
*
* Small differences between the rates (10% or less) are normal and the
* applications should usually tolerate them. However larger differences may
* cause annoying pitch problems (Mickey Mouse).
*/
return fd;
}
int
main (int argc, char *argv[])
{
char *name_out = "/dev/dsp";
int tmp;
audio_errinfo ei;
audio_buf_info bi;
if (argc > 1)
name_out = argv[1];
fd_out = open_audio_device (name_out, O_WRONLY);
/*
* Cause an intentional error by using wrong parameter to SNDCTL_DSP_STEREO
* which expects 0 or 1. Don't do error checking in this case because
* we would like to see two errors reported.
*/
tmp = 2;
ioctl (fd_out, SNDCTL_DSP_STEREO, &tmp);
/*
* Cause an intentional failure by calling {!nlink SNDCTL_DSP_GETISPACE}
* which is not permitted on write-only devices.
*/
if (ioctl (fd_out, SNDCTL_DSP_GETISPACE, &bi) == -1)
{
perror ("SNDCTL_DSP_GETISPACE"); /* Report the "primary" error first */
/*
* Next show the explanation to the user.
*/
fprintf (stderr,
"Audio error: Cannot obtain recorded byte count from the device.\n");
fprintf (stderr, "\n");
/*
* Next call {!nlink SNDCTL_DSP_GETERROR} to see if there is
* any additional info available.
*/
if (ioctl (fd_out, SNDCTL_DSP_GETERROR, &ei) != -1)
{
if (ei.play_errorcount > 0 && ei.play_lasterror != 0)
fprintf (stderr, "%d OSS play event(s), last=%05d:%d\n",
ei.play_errorcount, ei.play_lasterror,
ei.play_errorparm);
if (ei.rec_errorcount > 0 && ei.rec_lasterror != 0)
fprintf (stderr, "%d OSS rec event(s), last=%05d:%d\n",
ei.rec_errorcount, ei.rec_lasterror, ei.rec_errorparm);
}
}
else
fprintf (stderr, "SNDCTL_DSP_GETISPACE didn't fail as expected.\n");
exit (0);
}
|