source: roaraudio/roard/driver_oss.c @ 946:8967abcd6cb1

Last change on this file since 946:8967abcd6cb1 was 946:8967abcd6cb1, checked in by phi, 15 years ago

use SNDCTL_DSP_SETFMT if avalible

File size: 5.2 KB
Line 
1//driver_oss.c:
2
3/*
4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008
5 *
6 *  This file is part of roard 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, 675 Mass Ave, Cambridge, MA 02139, USA.
22 *
23 */
24
25#include "roard.h"
26#if defined(ROAR_HAVE_OSS_BSD) || defined(ROAR_HAVE_OSS)
27
28#define er() close(fh); return -1
29
30int driver_oss_open(struct roar_vio_calls * inst, char * device, struct roar_audio_info * info, int fh) {
31 int tmp;
32 int ctmp;
33 char * es;
34
35#ifdef ROAR_DEFAULT_OSS_DEV
36 if ( device == NULL )
37  device = ROAR_DEFAULT_OSS_DEV;
38#endif
39
40 if ( device == NULL ) {
41  ROAR_ERR("driver_oss_open(*): no default device found, you need to specify one manuelly");
42  return -1;
43 }
44
45 roar_vio_init_calls(inst);
46
47 if (  fh == -1 ) {
48  if ( (fh = open(device, O_WRONLY, 0644)) == -1 ) {
49   ROAR_ERR("driver_oss_open(*): Can not open OSS device: %s: %s", device, strerror(errno));
50   return -1;
51  }
52 }
53
54 roar_vio_set_fh(inst, fh);
55
56
57
58#ifdef SNDCTL_DSP_CHANNELS
59 tmp = info->channels;
60
61 if ( ioctl(fh, SNDCTL_DSP_CHANNELS, &tmp) == -1 ) {
62  ROAR_ERR("driver_oss_open(*): can not set number of channels");
63  er();
64 }
65
66 if ( tmp != info->channels ) {
67   ROAR_ERR("driver_oss_open(*): can not set requested numer of channels, OSS suggested %i channels, to use this restart with -oO channels=%i or set codec manuelly via -oO channels=num", tmp, tmp);
68  er();
69 }
70#else
71 switch (info->channels) {
72  case  1: tmp = 0; break;
73  case  2: tmp = 1; break;
74  default: er();
75 }
76
77 if ( ioctl(fh, SNDCTL_DSP_STEREO, &tmp) == -1 ) {
78  ROAR_ERR("driver_oss_open(*): can not set number of channels");
79  er();
80 }
81#endif
82
83 switch (info->codec) {
84  case ROAR_CODEC_PCM_S_LE:
85    switch (info->bits) {
86     case  8: tmp = AFMT_S8;     break;
87     case 16: tmp = AFMT_S16_LE; break;
88//     case 24: tmp = AFMT_S24_PACKED; break;
89#ifdef AFMT_S32_LE
90     case 32: tmp = AFMT_S32_LE; break;
91#endif
92     default: er();
93    }
94   break;
95  case ROAR_CODEC_PCM_S_BE:
96    switch (info->bits) {
97     case  8: tmp = AFMT_S8;     break;
98     case 16: tmp = AFMT_S16_BE; break;
99//     case 24: tmp = AFMT_S24_PACKED; break;
100#ifdef AFMT_S32_BE
101     case 32: tmp = AFMT_S32_BE; break;
102#endif
103     default: er();
104    }
105   break;
106  case ROAR_CODEC_PCM_U_LE:
107    switch (info->bits) {
108     case  8: tmp = AFMT_U8;     break;
109     case 16: tmp = AFMT_U16_LE; break;
110     default: er();
111    }
112   break;
113  case ROAR_CODEC_PCM_U_BE:
114    switch (info->bits) {
115     case  8: tmp = AFMT_U8;     break;
116     case 16: tmp = AFMT_U16_BE; break;
117     default: er();
118    }
119  case ROAR_CODEC_ALAW:
120    tmp = AFMT_A_LAW;
121   break;
122  case ROAR_CODEC_MULAW:
123    tmp = AFMT_MU_LAW;
124   break;
125#ifdef AFMT_VORBIS
126  case ROAR_CODEC_OGG_VORBIS:
127    tmp = AFMT_VORBIS;
128   break;
129#endif
130  default:
131    er();
132   break;
133 }
134
135 ctmp = tmp;
136#ifdef SNDCTL_DSP_SETFMT
137 if ( ioctl(fh, SNDCTL_DSP_SETFMT, &tmp) == -1 ) {
138#else
139 if ( ioctl(fh, SNDCTL_DSP_SAMPLESIZE, &tmp) == -1 ) {
140#endif
141  ROAR_ERR("driver_oss_open(*): can not set sample format");
142  er();
143 }
144
145 if ( tmp != ctmp ) {
146  es = NULL;
147  switch (tmp) {
148   case AFMT_S8    : es = "bits=8,codec=pcm";       break;
149   case AFMT_U8    : es = "bits=8,codec=pcm_u_le";  break;
150   case AFMT_S16_LE: es = "bits=16,codec=pcm_s_le"; break;
151   case AFMT_S16_BE: es = "bits=16,codec=pcm_s_be"; break;
152   case AFMT_U16_LE: es = "bits=16,codec=pcm_u_le"; break;
153   case AFMT_U16_BE: es = "bits=16,codec=pcm_u_be"; break;
154#ifdef AFMT_S32_LE
155   case AFMT_S32_LE: es = "bits=32,codec=pcm_s_le"; break;
156#endif
157#ifdef AFMT_S32_BE
158   case AFMT_S32_BE: es = "bits=32,codec=pcm_s_be"; break;
159#endif
160   case AFMT_A_LAW : es = "codec=alaw";             break;
161   case AFMT_MU_LAW: es = "codec=mulaw";            break;
162#ifdef AFMT_VORBIS
163   case AFMT_VORBIS: es = "codec=ogg_vorbis";       break;
164#endif
165  }
166
167  if ( es != NULL ) {
168   ROAR_ERR("driver_oss_open(*): can not set requested codec, OSS retruned another codec then requested, to use this restart with -oO %s or set codec manuelly via -oO codec=somecodec", es);
169  } else {
170   ROAR_ERR("driver_oss_open(*): can not set requested codec, set codec manuelly via -oO codec=somecodec");
171  }
172  er();
173 }
174
175 tmp = info->rate;
176
177 if ( ioctl(fh, SNDCTL_DSP_SPEED, &tmp) == -1 ) {
178  ROAR_ERR("driver_oss_open(*): can not set sample rate");
179  er();
180 }
181
182 if ( tmp < info->rate * 0.98 || tmp > info->rate * 1.02 ) {
183  ROAR_ERR("driver_oss_open(*): sample rate out of acceptable accuracy");
184  er();
185 }
186
187 ROAR_DBG("driver_oss_open(*): OSS devices opened :)");
188
189 return 0;
190}
191
192int driver_oss_close(DRIVER_USERDATA_T   inst) {
193 return close(roar_vio_get_fh((struct roar_vio_calls *)inst));
194}
195
196
197#endif
198//ll
Note: See TracBrowser for help on using the repository browser.