"Fossies" - the Fresh Open Source Software Archive 
Member "alsa-oss-1.1.8/test/osstest.c" (7 Jan 2019, 9436 Bytes) of package /linux/misc/alsa-oss-1.1.8.tar.bz2:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <unistd.h>
4 #include <fcntl.h>
5 #include <string.h>
6 #include <getopt.h>
7 #include <sys/types.h>
8 #include <sys/mman.h>
9 #include <sys/soundcard.h>
10 #include <sys/time.h>
11 #include <sys/poll.h>
12 #include <oss-redir.h>
13
14 //static char data[500000];
15 static int verbose;
16 static char *device = "/dev/dsp";
17 static int format = AFMT_S16_LE;
18 static int rate = 48000;
19 static int channels = 2;
20 static int omode = O_RDWR;
21 static int frag = 0xffff000c; /* Max # periods of 2^13=8k bytes */
22 static int fd;
23 static audio_buf_info ospace;
24 static audio_buf_info ispace;
25 static int bufsize;
26 static int fragsize;
27 static char *wbuf = NULL, *rbuf = NULL;
28 static int loop = 40;
29
30 static void help(void)
31 {
32 printf(
33 "Usage: mmap_test [OPTION]...\n"
34 "-h,--help help\n"
35 "-D,--device playback device\n"
36 "-r,--rate stream rate in Hz\n"
37 "-c,--channels count of channels in stream\n"
38 //"-f,--frequency sine wave frequency in Hz\n"
39 "-F,--frag OSS fragment settings (SNDCTL_DSP_SETFRAGMENT)\n"
40 "-M,--omode open mode (read/write/duplex)\n"
41 "-m,--method transfer method (rw, mmap_and_select, mmap_and_poll)\n"
42 "-L,--loop set loop count\n"
43 "-v,--verbose show more info\n"
44 "\n");
45 }
46
47 static void set_params(int do_mmap)
48 {
49 int caps;
50
51 if (oss_pcm_ioctl(fd, SNDCTL_DSP_SETFMT, &format) < 0) {
52 perror("SNDCTL_DSP_SETFMT\n");
53 exit(EXIT_FAILURE);
54 }
55 printf("Format set to %d\n", format);
56
57 if (oss_pcm_ioctl(fd, SNDCTL_DSP_SPEED, &rate) < 0) {
58 perror("SNDCTL_DSP_SPEED\n");
59 exit(EXIT_FAILURE);
60 }
61 printf("Rate set to %d\n", rate);
62
63 if (oss_pcm_ioctl(fd, SNDCTL_DSP_CHANNELS, &channels) < 0) {
64 perror("SNDCTL_DSP_CHANNELS\n");
65 exit(EXIT_FAILURE);
66 }
67 printf("Channels set to %d\n", channels);
68
69 if (oss_pcm_ioctl(fd, SNDCTL_DSP_GETCAPS, &caps) < 0) {
70 perror("/dev/dsp");
71 fprintf(stderr, "Sorry but your sound driver is too old\n");
72 exit(EXIT_FAILURE);
73 }
74 if (do_mmap &&
75 (!(caps & DSP_CAP_TRIGGER) ||
76 !(caps & DSP_CAP_MMAP)))
77 {
78 fprintf(stderr, "Sorry but your soundcard can't do this\n");
79 exit(EXIT_FAILURE);
80 }
81 if (oss_pcm_ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &frag) < 0)
82 perror("SNDCTL_DSP_SETFRAGMENT");
83 bufsize = fragsize = -1;
84 if (omode == O_RDWR || omode == O_WRONLY) {
85 if (oss_pcm_ioctl(fd, SNDCTL_DSP_GETOSPACE, &ospace) < 0) {
86 perror("SNDCTL_DSP_GETOSPACE");
87 exit(EXIT_FAILURE);
88 }
89 bufsize = ospace.fragstotal * ospace.fragsize;
90 fragsize = ospace.fragsize;
91 printf("ospace.fragstotal = %i\n", ospace.fragstotal);
92 printf("ospace.fragsize = %i\n", ospace.fragsize);
93 printf("ospace.periods = %i\n", ospace.fragments);
94 printf("ospace.bytes = %i\n", ospace.bytes);
95 if (do_mmap) {
96 if ((wbuf=mmap(NULL, bufsize, PROT_WRITE, MAP_FILE|MAP_SHARED, fd, 0))==MAP_FAILED) {
97 perror("mmap (write)");
98 exit(-1);
99 }
100 printf("mmap (out) returned %p\n", wbuf);
101 }
102 }
103 if (omode == O_RDWR || omode == O_RDONLY) {
104 if (oss_pcm_ioctl(fd, SNDCTL_DSP_GETISPACE, &ispace) < 0) {
105 perror("SNDCTL_DSP_GETISPACE");
106 if (omode == O_RDWR) {
107 omode = O_WRONLY;
108 fprintf(stderr, "Falling to write only mode\n");
109 } else {
110 exit(EXIT_FAILURE);
111 }
112 }
113 if (omode != O_WRONLY) {
114 if (bufsize < 0) {
115 bufsize = ispace.fragstotal * ispace.fragsize;
116 fragsize = ispace.fragsize;
117 }
118 printf("ispace.fragstotal = %i\n", ispace.fragstotal);
119 printf("ispace.fragsize = %i\n", ispace.fragsize);
120 printf("ispace.periods = %i\n", ispace.fragments);
121 printf("ispace.bytes = %i\n", ispace.bytes);
122 if (do_mmap) {
123 if ((rbuf=mmap(NULL, bufsize, PROT_READ, MAP_FILE|MAP_SHARED, fd, 0))==MAP_FAILED) {
124 perror("mmap (read)");
125 exit(-1);
126 }
127 printf("mmap (in) returned %p\n", rbuf);
128 }
129 }
130 }
131 }
132
133 static void set_trigger(void)
134 {
135 int tmp;
136
137 tmp = 0;
138 if (oss_pcm_ioctl(fd, SNDCTL_DSP_SETTRIGGER, &tmp) < 0) {
139 perror("SNDCTL_DSP_SETTRIGGER");
140 exit(EXIT_FAILURE);
141 }
142 printf("Trigger set to %08x\n", tmp);
143
144 if (omode == O_RDWR)
145 tmp = PCM_ENABLE_OUTPUT|PCM_ENABLE_INPUT;
146 else if (omode == O_RDONLY)
147 tmp = PCM_ENABLE_INPUT;
148 else if (omode == O_WRONLY)
149 tmp = PCM_ENABLE_OUTPUT;
150 if (oss_pcm_ioctl(fd, SNDCTL_DSP_SETTRIGGER, &tmp) < 0) {
151 perror("SNDCTL_DSP_SETTRIGGER");
152 exit(EXIT_FAILURE);
153 }
154 printf("Trigger set to %08x\n", tmp);
155 }
156
157 static void rw_loop(void)
158 {
159 int idx, first = 1;
160
161 for (idx=0; idx<loop; idx++) {
162 char buf[1000];
163 if (omode != O_RDONLY) {
164 ssize_t res;
165 if (first) {
166 res = oss_pcm_write(fd, buf, sizeof(buf));
167 if (verbose)
168 printf("write: (%i) -> %i\n", sizeof(buf), (int)res);
169 }
170 res = oss_pcm_write(fd, buf, sizeof(buf));
171 if (verbose)
172 printf("write: (%i) -> %i\n", sizeof(buf), (int)res);
173 first = 0;
174 }
175 if (omode != O_WRONLY) {
176 ssize_t res = oss_pcm_read(fd, buf, sizeof(buf));
177 if (verbose)
178 printf("read: (%i) -> %i\n", sizeof(buf), (int)res);
179 }
180 }
181 }
182
183 static void rw_and_select_loop(void)
184 {
185 }
186
187 static void rw_and_poll_loop(void)
188 {
189 }
190
191 static void mmap_loop(void)
192 {
193 }
194
195 static void mmap_and_select_loop(void)
196 {
197 int nfrag_in = 0, nfrag_out = 0, idx;
198 struct timeval tim;
199 fd_set writeset, readset;
200
201 for (idx=0; idx<loop; idx++) {
202 struct count_info count_in, count_out;
203 int res, maxfd;
204
205 FD_ZERO(&writeset);
206 FD_ZERO(&readset);
207 maxfd = oss_pcm_select_prepare(fd, omode, &readset, &writeset, NULL);
208
209 tim.tv_sec = 10;
210 tim.tv_usec = 0;
211
212 res = select(maxfd + 1, &readset, &writeset, NULL, &tim);
213 if (res < 0)
214 perror("select\n");
215 if (verbose) {
216 printf("Select returned: %03d\n", res);
217 fflush(stdout);
218 }
219 if (omode != O_WRONLY) {
220 if (oss_pcm_ioctl(fd, SNDCTL_DSP_GETIPTR, &count_in) < 0) {
221 perror("GETOPTR");
222 exit(EXIT_FAILURE);
223 }
224 nfrag_in += count_in.blocks;
225 if (verbose) {
226 printf("GETIPTR: Total: %09d, Period: %03d, Ptr: %06d\n", count_in.bytes, nfrag_in, count_in.ptr);
227 fflush(stdout);
228 }
229 }
230 if (omode != O_RDONLY) {
231 if (oss_pcm_ioctl(fd, SNDCTL_DSP_GETOPTR, &count_out) < 0) {
232 perror("GETOPTR");
233 exit(EXIT_FAILURE);
234 }
235 nfrag_out += count_out.blocks;
236 if (verbose) {
237 printf("GETOPTR: Total: %09d, Period: %03d, Ptr: %06d\n", count_out.bytes, nfrag_out, count_out.ptr);
238 fflush(stdout);
239 }
240 }
241 }
242 }
243
244 static void mmap_and_poll_loop(void)
245 {
246 int nfrag_in = 0, nfrag_out = 0, idx;
247 int fd_count;
248
249 fd_count = oss_pcm_poll_fds(fd);
250
251 for (idx=0; idx<loop; idx++) {
252 struct pollfd ufds[fd_count];
253 struct count_info count_in, count_out;
254 int res;
255
256 oss_pcm_poll_prepare(fd, omode, ufds);
257
258 res = poll(ufds, fd_count, 10000);
259 if (res < 0)
260 perror("poll\n");
261 if (verbose) {
262 printf("Poll returned: %03d\n", res);
263 fflush(stdout);
264 }
265 if (omode != O_WRONLY) {
266 if (oss_pcm_ioctl(fd, SNDCTL_DSP_GETIPTR, &count_in) < 0) {
267 perror("GETOPTR");
268 exit(EXIT_FAILURE);
269 }
270 nfrag_in += count_in.blocks;
271 if (verbose) {
272 printf("GETIPTR: Total: %09d, Period: %03d, Ptr: %06d\n", count_in.bytes, nfrag_in, count_in.ptr);
273 fflush(stdout);
274 }
275 }
276 if (omode != O_RDONLY) {
277 if (oss_pcm_ioctl(fd, SNDCTL_DSP_GETOPTR, &count_out) < 0) {
278 perror("GETOPTR");
279 exit(EXIT_FAILURE);
280 }
281 nfrag_out += count_out.blocks;
282 if (verbose) {
283 printf("GETOPTR: Total: %09d, Period: %03d, Ptr: %06d\n", count_out.bytes, nfrag_out, count_out.ptr);
284 fflush(stdout);
285 }
286 }
287 }
288 }
289
290 struct transfer_method {
291 const char *name;
292 int do_mmap;
293 void (*transfer_loop)(void);
294 };
295
296 static struct transfer_method transfer_methods[] = {
297 { "rw", 0, rw_loop },
298 { "rw_and_select", 0, rw_and_select_loop },
299 { "rw_and_poll", 0, rw_and_poll_loop },
300 { "mmap", 1, mmap_loop },
301 { "mmap_and_select", 1, mmap_and_select_loop },
302 { "mmap_and_poll", 1, mmap_and_poll_loop },
303 { NULL, 0, NULL }
304 };
305
306 int main(int argc, char *argv[])
307 {
308 int morehelp = 0;
309 int method = 0;
310 struct option long_option[] =
311 {
312 {"help", 0, NULL, 'h'},
313 {"device", 1, NULL, 'D'},
314 {"verbose", 1, NULL, 'v'},
315 {"omode", 1, NULL, 'M'},
316 {"mode", 1, NULL, 'm'},
317 {"rate", 1, NULL, 'r'},
318 {"channels", 1, NULL, 'c'},
319 {"frag", 1, NULL, 'F'},
320 {"loop", 1, NULL, 'L'},
321 {NULL, 0, NULL, 0},
322 };
323
324 morehelp = 0;
325 while (1) {
326 int c;
327 if ((c = getopt_long(argc, argv, "hD:M:m:r:c:F:L:v", long_option, NULL)) < 0)
328 break;
329 switch (c) {
330 case 'h':
331 morehelp++;
332 break;
333 case 'D':
334 device = strdup(optarg);
335 break;
336 case 'M':
337 if (!strcmp(optarg, "read"))
338 omode = O_RDONLY;
339 else if (!strcmp(optarg, "write"))
340 omode = O_WRONLY;
341 else
342 omode = O_RDWR;
343 break;
344 case 'm':
345 for (method = 0; transfer_methods[method].name; method++)
346 if (!strcasecmp(transfer_methods[method].name, optarg))
347 break;
348 if (transfer_methods[method].name == NULL)
349 method = 0;
350 break;
351 case 'r':
352 rate = atoi(optarg);
353 break;
354 case 'c':
355 channels = atoi(optarg);
356 break;
357 case 'F':
358 frag = atoi(optarg);
359 break;
360 case 'L':
361 loop = atoi(optarg);
362 break;
363 case 'v':
364 verbose = 1;
365 break;
366 }
367 }
368
369 if (morehelp) {
370 help();
371 return 0;
372 }
373
374 printf("Using transfer method %s\n", transfer_methods[method].name);
375
376 if ((fd=oss_pcm_open(device, O_RDWR, 0))==-1) {
377 perror(device);
378 exit(-1);
379 }
380
381 printf("Device %s opened sucessfully\n", device);
382
383 set_params(transfer_methods[method].do_mmap);
384 if (transfer_methods[method].do_mmap)
385 set_trigger();
386
387 transfer_methods[method].transfer_loop();
388
389 close(fd);
390
391 exit(0);
392 }