source: roaraudio/roard/hwmixer_oss.c @ 4380:9e0d335e4c4e

Last change on this file since 4380:9e0d335e4c4e was 4380:9e0d335e4c4e, checked in by phi, 14 years ago

some cleanup

File size: 5.2 KB
Line 
1//hwmixer_oss.c:
2
3/*
4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010
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, 51 Franklin Street, Fifth Floor,
22 *  Boston, MA 02110-1301, USA.
23 *
24 */
25
26#include "roard.h"
27
28#define OSS_VOLUME_SCALE 100
29
30struct subdev {
31 int bit;
32 int channels;
33 long long int cmd_read, cmd_write;
34};
35
36int hwmixer_oss_open(struct hwmixer_stream * stream, char * drv, char * dev, int fh, char * basename, struct roar_keyval * subnames, size_t subnamelen) {
37 struct roar_vio_calls * vio = roar_mm_malloc(sizeof(struct roar_vio_calls));
38 struct roar_vio_defaults def;
39 struct roar_stream_server * ss;
40 struct roar_vio_sysio_ioctl ctl;
41 int devmask, sdevmask;
42 struct subdev * subdev = roar_mm_malloc(sizeof(struct subdev));
43
44 if ( vio == NULL || subdev == NULL ) {
45  if ( vio != NULL )
46   roar_mm_free(vio);
47  if ( subdev != NULL )
48   roar_mm_free(subdev);
49  return -1;
50 }
51
52 if ( fh == -1 ) {
53#ifdef ROAR_DEFAULT_OSS_MIX_DEV
54  if ( dev == NULL ) {
55   dev = ROAR_DEFAULT_OSS_MIX_DEV;
56  }
57#endif
58
59  if ( dev == NULL ) {
60   roar_mm_free(vio);
61   roar_mm_free(subdev);
62   return -1;
63  }
64
65  if ( roar_vio_dstr_init_defaults(&def, ROAR_VIO_DEF_TYPE_FILE, O_RDWR, 0644) == -1 ) {
66   roar_mm_free(vio);
67   roar_mm_free(subdev);
68   return -1;
69  }
70
71  if ( roar_vio_open_dstr(vio, dev, &def, 1) == -1 ) {
72   roar_mm_free(vio);
73   roar_mm_free(subdev);
74   return -1;
75  }
76 } else {
77  if ( roar_vio_open_fh(vio, fh) == -1 ) {
78   roar_mm_free(vio);
79   roar_mm_free(subdev);
80   return -1;
81  }
82 }
83
84 stream->baseud = vio;
85 stream->ud     = subdev;
86
87 ctl.cmd  = SOUND_MIXER_READ_DEVMASK;
88 ctl.argp = &devmask;
89
90 if ( roar_vio_ctl(vio, ROAR_VIO_CTL_SYSIO_IOCTL, &ctl) == -1 ) {
91  roar_vio_close(vio);
92  roar_mm_free(vio);
93  roar_mm_free(subdev);
94  return -1;
95 }
96
97 ctl.cmd  = SOUND_MIXER_READ_STEREODEVS;
98 ctl.argp = &sdevmask;
99
100 if ( roar_vio_ctl(vio, ROAR_VIO_CTL_SYSIO_IOCTL, &ctl) == -1 ) {
101  sdevmask = 0;
102 }
103
104 memset(subdev, 0, sizeof(struct subdev));
105
106 if ( devmask & SOUND_MASK_VOLUME ) {
107  subdev->bit       = SOUND_MASK_VOLUME;
108  subdev->channels  = sdevmask & SOUND_MASK_VOLUME ? 2 : 1;
109  subdev->cmd_read  = SOUND_MIXER_READ_VOLUME;
110  subdev->cmd_write = SOUND_MIXER_WRITE_VOLUME;
111 } else {
112  roar_vio_close(vio);
113  roar_mm_free(vio);
114  roar_mm_free(subdev);
115  return -1;
116 }
117
118 if (streams_get(stream->basestream, &ss) != -1) {
119  ROAR_STREAM(ss)->info.channels = 2;
120 } else {
121  ROAR_WARN("hwmixer_dstr_open(*): can not get object for basestream %i", stream->basestream);
122 }
123
124#ifdef TEST_HWMIXER_SUBSTREAMS
125 stream = hwmixer_substream_new(stream);
126 if ( stream == NULL ) {
127  ROAR_WARN("hwmixer_dstr_open(*): can not create substream");
128 } else {
129  if (streams_get(stream->stream, &ss) != -1) {
130   ROAR_STREAM(ss)->info.channels = 2;
131  } else {
132   ROAR_WARN("hwmixer_dstr_open(*): can not get object for stream %i", stream->stream);
133  }
134 }
135#endif
136
137 return 0;
138}
139
140int hwmixer_oss_close(struct hwmixer_stream * stream) {
141 // are we a substream? if yes we do not clean up anything.
142 // streams_delete() will do all our work.
143
144 roar_mm_free(stream->ud);
145
146 if ( stream->stream != stream->basestream )
147  return 0;
148
149 roar_vio_close(stream->baseud);
150 roar_mm_free(stream->baseud);
151 return 0;
152}
153
154int hwmixer_oss_set_vol(struct hwmixer_stream * stream, int channels, int mode, struct roar_mixer_settings * settings) {
155 struct roar_vio_calls * vio = stream->baseud;
156 struct roar_vio_sysio_ioctl ctl;
157 struct subdev         * subdev = stream->ud;
158 int i;
159 int l, r;
160
161 if ( channels == 0 )
162  return 0;
163
164 if ( channels == 1 ) {
165  l = r = settings->mixer[0];
166 } else {
167  l = settings->mixer[0];
168  r = settings->mixer[1];
169 }
170
171 if ( subdev->channels == 1 ) {
172  l = r = (l + r) / 2;
173 }
174
175 l = (l * OSS_VOLUME_SCALE) / settings->scale;
176 r = (r * OSS_VOLUME_SCALE) / settings->scale;
177
178 i = (l & 0xFF) | ((r & 0xFF) << 8);
179
180 ctl.cmd = subdev->cmd_write;
181 ctl.argp = &i;
182
183 return roar_vio_ctl(vio, ROAR_VIO_CTL_SYSIO_IOCTL, &ctl);
184}
185
186int hwmixer_oss_get_vol(struct hwmixer_stream * stream, int channels, int mode, struct roar_mixer_settings * settings) {
187 struct roar_vio_calls * vio = stream->baseud;
188 struct roar_vio_sysio_ioctl ctl;
189 struct subdev         * subdev = stream->ud;
190 int i;
191 int l, r;
192
193 ctl.cmd = subdev->cmd_read;
194 ctl.argp = &i;
195
196 if ( roar_vio_ctl(vio, ROAR_VIO_CTL_SYSIO_IOCTL, &ctl) == -1 )
197  return -1;
198
199 l =  i       & 0xFF;
200 r = (i >> 8) & 0xFF;
201
202 if ( subdev->channels == 1 )
203  r = l;
204
205 settings->scale    = OSS_VOLUME_SCALE;
206
207 if ( channels == 1 ) {
208  settings->mixer[0] = (l + r) / 2;
209 } else if ( channels == 2 ) {
210  settings->mixer[0] = l;
211  settings->mixer[1] = r;
212 } else {
213  return -1;
214 }
215
216 return 0;
217}
218
219//ll
Note: See TracBrowser for help on using the repository browser.