1 /* Simple oss testsuite
3 * Copyright (C) 2009 Maarten Lankhorst <m.b.lankhorst@gmail.com>
5 * This file is released under the GPLv2.
9 #include <sys/soundcard.h>
11 #include <sys/ioctl.h>
22 #define MIXERDEV "/dev/mixer"
23 #define DSPDEV "/dev/dsp"
27 static int errors
, success
;
28 static int report_success
= 1;
30 #define ok(a, b, c...) do { \
32 fprintf(stderr, "%s@%d test failed (%s): " b "\n", __func__, __LINE__, #a, ##c); \
36 printf("%s@%d test succeeded (%s)\n", __func__, __LINE__, #a); \
40 static int mixerfd
, dspfd
;
42 static int reopen(int blocking
)
49 dspfd
= open(DSPDEV
, O_RDWR
|blocking
);
53 static void test_ro(int fd
)
57 struct audio_buf_info abi
;
58 memset(buf
, 0, sizeof(buf
));
60 ret
= read(fd
, buf
, sizeof(buf
));
61 ok(ret
>= 0, "%s", strerror(errno
));
63 ret
= write(fd
, buf
, sizeof(buf
));
64 ok(ret
< 0, "read %d bytes", ret
);
66 ret
= ioctl(fd
, SNDCTL_DSP_GETISPACE
, &abi
);
67 ok(ret
>= 0, "%s", strerror(errno
));
69 ret
= ioctl(fd
, SNDCTL_DSP_GETOSPACE
, &abi
);
70 ok(ret
< 0, "%s", strerror(errno
));
72 ok(errno
== EINVAL
, "Invalid errno: %s", strerror(errno
));
75 static void test_wo(int fd
)
79 struct audio_buf_info abi
;
80 memset(buf
, 0, sizeof(buf
));
82 ret
= read(fd
, buf
, sizeof(buf
));
83 ok(ret
< 0, "read %d bytes", ret
);
85 ret
= write(fd
, buf
, sizeof(buf
));
86 ok(ret
>= 0, "%s", strerror(errno
));
88 ret
= ioctl(fd
, SNDCTL_DSP_GETISPACE
, &abi
);
89 ok(ret
< 0, "%s", strerror(errno
));
91 ok(errno
== EINVAL
, "Invalid errno: %s", strerror(errno
));
93 ret
= ioctl(fd
, SNDCTL_DSP_GETOSPACE
, &abi
);
94 ok(ret
>= 0, "%s", strerror(errno
));
97 static void test_rw(int fd
)
101 struct audio_buf_info abi
;
102 memset(buf
, 0, sizeof(buf
));
104 ret
= read(fd
, buf
, sizeof(buf
));
105 ok(ret
>= 0, "%s", strerror(errno
));
107 ret
= write(fd
, buf
, sizeof(buf
));
108 ok(ret
>= 0, "%s", strerror(errno
));
110 ret
= ioctl(fd
, SNDCTL_DSP_GETISPACE
, &abi
);
111 ok(ret
>= 0, "%s", strerror(errno
));
113 ret
= ioctl(fd
, SNDCTL_DSP_GETOSPACE
, &abi
);
114 ok(ret
>= 0, "%s", strerror(errno
));
117 static void test_open(void)
119 int ro_fd
, rw_fd
, wo_fd
;
121 mixerfd
= open(MIXERDEV
, O_RDONLY
|O_NDELAY
);
122 ok(mixerfd
>= 0, "%s", strerror(errno
));
125 /* In order to make this work it has to be serialized
126 * alsa's kernel emulation can only have device open once
127 * so do some specific smokescreen tests here
128 * and then open dsp for testing
130 ro_fd
= open(DSPDEV
, O_RDONLY
);
131 ok(ro_fd
>= 0, "%s", strerror(errno
));
138 wo_fd
= open(DSPDEV
, O_WRONLY
);
139 ok(wo_fd
>= 0, "%s", strerror(errno
));
146 rw_fd
= open(DSPDEV
, O_RDWR
);
147 ok(rw_fd
>= 0, "%s", strerror(errno
));
155 static void test_mixer(void)
158 struct mixer_info info
;
159 memset(&info
, 0, sizeof(info
));
161 ret
= ioctl(mixerfd
, SOUND_MIXER_INFO
, &info
);
162 ok(ret
>= 0, "%s", strerror(errno
));
164 printf("Mixer id: %s\n", info
.id
);
165 printf("Name: %s\n", info
.name
);
169 static void test_trigger(int fd
)
173 ret
= ioctl(fd
, SNDCTL_DSP_GETTRIGGER
, &i
);
174 ok(ret
== 0, "Returned error %s", strerror(errno
));
175 ok(i
== (PCM_ENABLE_INPUT
|PCM_ENABLE_OUTPUT
), "i is set to %d", i
);
178 ret
= ioctl(fd
, SNDCTL_DSP_SETTRIGGER
, &i
);
179 ok(ret
== 0, "Returned error %s", strerror(errno
));
180 ok(i
== 0, "Wrong i returned");
182 i
= PCM_ENABLE_INPUT
|PCM_ENABLE_OUTPUT
;
183 ret
= ioctl(fd
, SNDCTL_DSP_SETTRIGGER
, &i
);
184 ok(ret
== 0, "Returned error %s", strerror(errno
));
185 ok(i
== (PCM_ENABLE_INPUT
|PCM_ENABLE_OUTPUT
), "i has value %d", i
);
187 ret
= ioctl(fd
, SNDCTL_DSP_POST
, NULL
);
188 ok(ret
== 0, "Returned error %s", strerror(errno
));
191 static void test_mmap(int fd
)
197 area
= mmap(NULL
, 8192, PROT_READ
|PROT_WRITE
, MAP_SHARED
, fd
, 0);
198 ok(area
!= MAP_FAILED
, "Failed to map: %s\n", strerror(errno
));
200 if (area
== MAP_FAILED
)
203 ret
= write(fd
, &buf
, sizeof(buf
));
204 ok(ret
== -1, "write after mmap returned %i\n", ret
);
206 ok(errno
== ENXIO
, "Error returned is %s\n", strerror(errno
));
211 static void test_notify(int fd
)
213 struct audio_buf_info bi
;
216 struct pollfd pfd
= { fd
, POLLOUT
};
219 ioctl(fd
, SNDCTL_DSP_GETOSPACE
, &bi
);
221 bytes
= calloc(1, bi
.fragsize
);
223 ok(0, "Fragsize: %i, bytes: %i\n", bi
.fragsize
, bi
.bytes
);
224 while (written
+ bi
.fragsize
- 1 < bi
.bytes
)
226 ret
= write(fd
, bytes
, bi
.fragsize
);
227 ok(ret
== bi
.fragsize
, "Returned: %i instead of %i\n",
235 ret
= poll(&pfd
, 1, -1);
236 ok(ret
> 0, "Poll returned %i\n", ret
);
239 ret
= write(fd
, bytes
, bi
.fragsize
);
240 if (ret
< 0) ret
= -errno
;
241 ok(ret
== bi
.fragsize
, "Returned: %i instead of %i\n",
263 printf("Tests: %d errors %d success\n", errors
, success
);
264 return errors
> 127 ? 127 : errors
;