source: roaraudio/roard/hwmixer_oss.c @ 4373:9ccbfd7d8a44

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

wrote very basic OSS driver

File size: 4.5 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  if ( dev == NULL ) {
54   dev = "/dev/mixer";
55  }
56
57  if ( dev == NULL ) {
58   roar_mm_free(vio);
59   roar_mm_free(subdev);
60   return -1;
61  }
62
63  if ( roar_vio_dstr_init_defaults(&def, ROAR_VIO_DEF_TYPE_FILE, O_RDWR, 0644) == -1 ) {
64   roar_mm_free(vio);
65   roar_mm_free(subdev);
66   return -1;
67  }
68
69  if ( roar_vio_open_dstr(vio, dev, &def, 1) == -1 ) {
70   roar_mm_free(vio);
71   roar_mm_free(subdev);
72   return -1;
73  }
74 } else {
75  if ( roar_vio_open_fh(vio, fh) == -1 ) {
76   roar_mm_free(vio);
77   roar_mm_free(subdev);
78   return -1;
79  }
80 }
81
82 stream->baseud = vio;
83 stream->ud     = subdev;
84
85 ctl.cmd  = SOUND_MIXER_READ_DEVMASK;
86 ctl.argp = &devmask;
87
88 if ( roar_vio_ctl(vio, ROAR_VIO_CTL_SYSIO_IOCTL, &ctl) == -1 ) {
89  roar_vio_close(vio);
90  roar_mm_free(vio);
91  roar_mm_free(subdev);
92  return -1;
93 }
94
95 ctl.cmd  = SOUND_MIXER_READ_STEREODEVS;
96 ctl.argp = &sdevmask;
97
98 if ( roar_vio_ctl(vio, ROAR_VIO_CTL_SYSIO_IOCTL, &ctl) == -1 ) {
99  sdevmask = 0;
100 }
101
102 memset(subdev, 0, sizeof(struct subdev));
103
104 if ( devmask & SOUND_MASK_VOLUME ) {
105  subdev->bit       = SOUND_MASK_VOLUME;
106  subdev->channels  = sdevmask & SOUND_MASK_VOLUME ? 2 : 1;
107  subdev->cmd_read  = SOUND_MIXER_READ_VOLUME;
108  subdev->cmd_write = SOUND_MIXER_WRITE_VOLUME;
109 } else {
110  roar_vio_close(vio);
111  roar_mm_free(vio);
112  roar_mm_free(subdev);
113  return -1;
114 }
115
116 if (streams_get(stream->basestream, &ss) != -1) {
117  ROAR_STREAM(ss)->info.channels = 2;
118 } else {
119  ROAR_WARN("hwmixer_dstr_open(*): can not get object for basestream %i", stream->basestream);
120 }
121
122#ifdef TEST_HWMIXER_SUBSTREAMS
123 stream = hwmixer_substream_new(stream);
124 if ( stream == NULL ) {
125  ROAR_WARN("hwmixer_dstr_open(*): can not create substream");
126 } else {
127  if (streams_get(stream->stream, &ss) != -1) {
128   ROAR_STREAM(ss)->info.channels = 2;
129  } else {
130   ROAR_WARN("hwmixer_dstr_open(*): can not get object for stream %i", stream->stream);
131  }
132 }
133#endif
134
135 return 0;
136}
137
138int hwmixer_oss_close(struct hwmixer_stream * stream) {
139 // are we a substream? if yes we do not clean up anything.
140 // streams_delete() will do all our work.
141
142 roar_mm_free(stream->ud);
143
144 if ( stream->stream != stream->basestream )
145  return 0;
146
147 roar_vio_close(stream->baseud);
148 roar_mm_free(stream->baseud);
149 return 0;
150}
151
152int hwmixer_oss_set_vol(struct hwmixer_stream * stream, int channels, int mode, struct roar_mixer_settings * settings) {
153 struct roar_vio_calls * vio = stream->baseud;
154 struct roar_vio_sysio_ioctl ctl;
155 struct subdev         * subdev = stream->ud;
156 int i;
157 int l, r;
158
159 if ( channels == 0 )
160  return 0;
161
162 if ( channels == 1 ) {
163  l = r = settings->mixer[0];
164 } else {
165  l = settings->mixer[0];
166  r = settings->mixer[1];
167 }
168
169 if ( subdev->channels == 1 ) {
170  l = r = (l + r) / 2;
171 }
172
173 l = (l * OSS_VOLUME_SCALE) / settings->scale;
174 r = (r * OSS_VOLUME_SCALE) / settings->scale;
175
176 i = (l & 0xFF) | ((r & 0xFF) << 8);
177
178 ctl.cmd = subdev->cmd_write;
179 ctl.argp = &i;
180
181 return roar_vio_ctl(vio, ROAR_VIO_CTL_SYSIO_IOCTL, &ctl);
182}
183
184//ll
Note: See TracBrowser for help on using the repository browser.