source: roaraudio/libroareio/driver_oss.c @ 5878:3b92b0d6ef9b

Last change on this file since 5878:3b92b0d6ef9b was 5823:f9f70dbaa376, checked in by phi, 11 years ago

updated copyright

File size: 4.2 KB
Line 
1//driver_oss.c:
2
3/*
4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2013
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(struct roar_vio_calls * calls) {
40 struct roar_vio_sysio_ioctl ctl;
41 int blocksizes[] = {11, 12, 13};
42 int blocks[]     = {4, 5, 6, 3, 7, 2, 8};
43 size_t bs, b;
44 int tmp;
45
46 ctl.cmd  = SNDCTL_DSP_SETFRAGMENT;
47 ctl.argp = &tmp;
48
49 for (bs = 0; bs < sizeof(blocksizes)/sizeof(int); bs++) {
50  for (b = 0; b  < sizeof(blocks)    /sizeof(int); b++ ) {
51   tmp = blocksizes[bs] | (blocks[b] << 16);
52   if ( roar_vio_ctl(calls, ROAR_VIO_CTL_SYSIO_IOCTL, &ctl) == 0 )
53    return;
54  }
55 }
56}
57#endif
58
59#define _err() roar_vio_close(calls); return -1
60
61int roar_cdriver_oss(struct roar_vio_calls * calls, const char * name, const char * dev, struct roar_audio_info * info, int dir) {
62 struct roar_vio_defaults def;
63 struct roar_vio_sysio_ioctl ctl;
64 int tmp, ctmp;
65
66 (void)name;
67
68 // preinit ctl struct, we always pass ints in tmp.
69 ctl.argp = &tmp;
70
71 ROAR_DBG("roar_cdriver_oss(*) = ?");
72
73#ifdef ROAR_DEFAULT_OSS_DEV
74 if ( dev == NULL )
75  dev = ROAR_DEFAULT_OSS_DEV;
76#endif
77
78 if ( dev == NULL )
79  return -1;
80
81 ROAR_DBG("roar_cdriver_oss(*) = ?");
82
83 switch (dir) {
84  case ROAR_DIR_PLAY:
85  case ROAR_DIR_MONITOR:
86  case ROAR_DIR_OUTPUT:
87    tmp = O_WRONLY;
88   break;
89  case ROAR_DIR_BIDIR:
90  case ROAR_DIR_RECPLAY:
91    tmp = O_RDWR;
92   break;
93  case ROAR_DIR_RECORD:
94    tmp = O_RDONLY;
95   break;
96  default:
97    return -1;
98 }
99
100 ROAR_DBG("roar_cdriver_oss(*) = ?");
101
102 if ( roar_vio_dstr_init_defaults(&def, ROAR_VIO_DEF_TYPE_NONE, tmp, 0644) == -1 )
103   return -1;
104
105 if ( roar_vio_open_dstr(calls, dev, &def, 1) == -1 )
106   return -1;
107
108// channels:
109#ifdef SNDCTL_DSP_CHANNELS
110 tmp = info->channels;
111
112 ctl.cmd  = SNDCTL_DSP_CHANNELS;
113
114 if ( roar_vio_ctl(calls, ROAR_VIO_CTL_SYSIO_IOCTL, &ctl) == -1 ) {
115  _err();
116 }
117
118 if ( tmp != (int)info->channels ) {
119  _err();
120 }
121#else
122 switch (info->channels) {
123  case  1: tmp = 0; break;
124  case  2: tmp = 1; break;
125  default: _err();
126 }
127
128 ctl.cmd = SNDCTL_DSP_STEREO;
129
130 if ( roar_vio_ctl(calls, ROAR_VIO_CTL_SYSIO_IOCTL, &ctl) == -1 ) {
131  _err();
132 }
133#endif
134
135// codec/bits:
136 if ( info->codec != ROAR_CODEC_ALAW && info->codec != ROAR_CODEC_MULAW && info->bits != 16 ) {
137  // other modes are currently not supported
138  _err();
139 }
140
141 switch (info->codec) {
142  case ROAR_CODEC_PCM_S_LE:
143    tmp = AFMT_S16_LE;
144   break;
145  case ROAR_CODEC_PCM_S_BE:
146    tmp = AFMT_S16_BE;
147   break;
148  case ROAR_CODEC_PCM_U_LE:
149    tmp = AFMT_U16_LE;
150   break;
151  case ROAR_CODEC_PCM_U_BE:
152    tmp = AFMT_U16_BE;
153   break;
154  case ROAR_CODEC_ALAW:
155    tmp = AFMT_A_LAW;
156   break;
157  case ROAR_CODEC_MULAW:
158    tmp = AFMT_MU_LAW;
159   break;
160  default:
161    _err();
162 }
163
164 ctmp = tmp;
165#ifdef SNDCTL_DSP_SETFMT
166 ctl.cmd = SNDCTL_DSP_SETFMT;
167#else
168 ctl.cmd = SNDCTL_DSP_SAMPLESIZE;
169#endif
170
171 if ( roar_vio_ctl(calls, ROAR_VIO_CTL_SYSIO_IOCTL, &ctl) == -1 ) {
172  _err();
173 }
174
175 if ( tmp != ctmp ) {
176  _err();
177 }
178
179// rate:
180 tmp = info->rate;
181
182 ctl.cmd = SNDCTL_DSP_SPEED;
183 if ( roar_vio_ctl(calls, ROAR_VIO_CTL_SYSIO_IOCTL, &ctl) == -1 ) {
184  _err();
185 }
186
187 if ( tmp != (int)info->rate ) {
188  _err();
189 }
190
191#ifdef SNDCTL_DSP_SETFRAGMENT
192 roar_cdriver_oss_try_buf_setups(calls);
193#endif
194
195 return 0;
196}
197
198#endif
199
200//ll
Note: See TracBrowser for help on using the repository browser.