source: roaraudio/libroareio/driver_oss.c @ 3517:1a3218a3fc5b

Last change on this file since 3517:1a3218a3fc5b was 3517:1a3218a3fc5b, checked in by phi, 14 years ago

updated license headers, FSF moved office

File size: 3.7 KB
Line 
1//driver_oss.c:
2
3/*
4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009
5 *
6 *  This file is part of roarclients a part of RoarAudio,
7 *  a cross-platform sound system for both, home and professional use.
8 *  See README for details.
9 *
10 *  This file is free software; you can redistribute it and/or modify
11 *  it under the terms of the GNU General Public License version 3
12 *  as published by the Free Software Foundation.
13 *
14 *  RoarAudio 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.
18 *
19 *  You should have received a copy of the GNU General Public License
20 *  along with this software; see the file COPYING.  If not, write to
21 *  the Free Software Foundation, 51 Franklin Street, Fifth Floor,
22 *  Boston, MA 02110-1301, USA.
23 *
24 */
25
26#include <roaraudio.h>
27#include "driver.h"
28
29#if defined(ROAR_HAVE_OSS_BSD) || defined(ROAR_HAVE_OSS)
30
31#if defined(__OpenBSD__) || defined(__NetBSD__)
32#include <soundcard.h>
33#else
34#include <sys/soundcard.h>
35#endif
36#include <sys/ioctl.h>
37
38#ifdef SNDCTL_DSP_SETFRAGMENT
39static void roar_cdriver_oss_try_buf_setups(int fh) {
40 int blocksizes[] = {11, 12, 13};
41 int blocks[]     = {4, 5, 6, 3, 7, 2, 8};
42 int bs, b;
43 int tmp;
44
45 for (bs = 0; bs < sizeof(blocksizes)/sizeof(int); bs++) {
46  for (b = 0; b  < sizeof(blocks)    /sizeof(int); b++ ) {
47   tmp = blocksizes[bs] | (blocks[b] << 16);
48   if ( ioctl(fh, SNDCTL_DSP_SETFRAGMENT, &tmp) == 0 )
49    return;
50  }
51 }
52}
53#endif
54
55#define _err() roar_vio_close(calls); return -1
56
57int roar_cdriver_oss(struct roar_vio_calls * calls, char * name, char * dev, struct roar_audio_info * info, int dir) {
58 int fh;
59 int tmp, ctmp;
60
61 ROAR_DBG("roar_cdriver_oss(*) = ?");
62
63#ifdef ROAR_DEFAULT_OSS_DEV
64 if ( dev == NULL )
65  dev = ROAR_DEFAULT_OSS_DEV;
66#endif
67
68 if ( dev == NULL )
69  return -1;
70
71 ROAR_DBG("roar_cdriver_oss(*) = ?");
72
73 switch (dir) {
74  case ROAR_DIR_PLAY:
75  case ROAR_DIR_MONITOR:
76  case ROAR_DIR_OUTPUT:
77    tmp = O_WRONLY;
78   break;
79  case ROAR_DIR_BIDIR:
80    tmp = O_RDWR;
81   break;
82  case ROAR_DIR_RECORD:
83    tmp = O_RDONLY;
84   break;
85  default:
86    return -1;
87 }
88
89 ROAR_DBG("roar_cdriver_oss(*) = ?");
90
91 if ( roar_vio_open_file(calls, dev, tmp, 0644) == -1 )
92  return -1;
93
94 if ( roar_vio_ctl(calls, ROAR_VIO_CTL_GET_FH, &fh) == -1 ) {
95  _err();
96 }
97
98// channels:
99#ifdef SNDCTL_DSP_CHANNELS
100 tmp = info->channels;
101
102 if ( ioctl(fh, SNDCTL_DSP_CHANNELS, &tmp) == -1 ) {
103  _err();
104 }
105
106 if ( tmp != info->channels ) {
107  _err();
108 }
109#else
110 switch (info->channels) {
111  case  1: tmp = 0; break;
112  case  2: tmp = 1; break;
113  default: _err();
114 }
115
116 if ( ioctl(fh, SNDCTL_DSP_STEREO, &tmp) == -1 ) {
117  _err();
118 }
119#endif
120
121// codec/bits:
122 if ( info->codec != ROAR_CODEC_ALAW && info->codec != ROAR_CODEC_MULAW && info->bits != 16 ) {
123  // other modes are currently not supported
124  _err();
125 }
126
127 switch (info->codec) {
128  case ROAR_CODEC_PCM_S_LE:
129    tmp = AFMT_S16_LE;
130   break;
131  case ROAR_CODEC_PCM_S_BE:
132    tmp = AFMT_S16_BE;
133   break;
134  case ROAR_CODEC_PCM_U_LE:
135    tmp = AFMT_U16_LE;
136   break;
137  case ROAR_CODEC_PCM_U_BE:
138    tmp = AFMT_U16_BE;
139   break;
140  case ROAR_CODEC_ALAW:
141    tmp = AFMT_A_LAW;
142   break;
143  case ROAR_CODEC_MULAW:
144    tmp = AFMT_MU_LAW;
145   break;
146  default:
147    _err();
148 }
149
150 ctmp = tmp;
151#ifdef SNDCTL_DSP_SETFMT
152 if ( ioctl(fh, SNDCTL_DSP_SETFMT, &tmp) == -1 ) {
153#else
154 if ( ioctl(fh, SNDCTL_DSP_SAMPLESIZE, &tmp) == -1 ) {
155#endif
156  _err();
157 }
158
159 if ( tmp != ctmp ) {
160  _err();
161 }
162
163// rate:
164 tmp = info->rate;
165
166 if ( ioctl(fh, SNDCTL_DSP_SPEED, &tmp) == -1 ) {
167  _err();
168 }
169
170 if ( tmp != info->rate ) {
171  _err();
172 }
173
174#ifdef SNDCTL_DSP_SETFRAGMENT
175 roar_cdriver_oss_try_buf_setups(fh);
176#endif
177
178 return 0;
179}
180
181#endif
182
183//ll
Note: See TracBrowser for help on using the repository browser.