source: roaraudio/roard/hwmixer.c @ 4752:42cd1d189fa2

Last change on this file since 4752:42cd1d189fa2 was 4752:42cd1d189fa2, checked in by phi, 13 years ago

corrected c&p error

File size: 6.8 KB
Line 
1//hwmixer.c:
2
3/*
4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2011
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#ifndef ROAR_WITHOUT_DCOMP_MIXER
29
30#define FLAG_NONE     0x0000
31#define FLAG_FHSEC    0x0001
32
33struct hwmixer {
34 const char * name;
35 const char * desc;
36 const char * devs;
37 int flags;
38 int (*open)(struct hwmixer_stream * stream, char * drv, char * dev, int fh, char * basename, struct roar_keyval * subnames, size_t subnamelen);
39 int (*close)(struct hwmixer_stream * stream);
40 int (*set_vol)(struct hwmixer_stream * stream, int channels, int mode, struct roar_mixer_settings * settings);
41 int (*get_vol)(struct hwmixer_stream * stream, int channels, int mode, struct roar_mixer_settings * settings);
42};
43
44static int __true (void) { return 0; }
45
46struct hwmixer g_hwmixers[] = {
47#if defined(ROAR_HAVE_OSS_BSD) || defined(ROAR_HAVE_OSS)
48 {"oss",  "OSS Mixer",     "/dev/mixer*", FLAG_FHSEC, hwmixer_oss_open, hwmixer_oss_close, hwmixer_oss_set_vol, hwmixer_oss_get_vol},
49#endif
50 {"dstr", "Write to DSTR", "/some/file",  FLAG_FHSEC,  hwmixer_dstr_open, hwmixer_dstr_close, hwmixer_dstr_set_vol, NULL},
51 {"null", "Null Mixer",    NULL,          FLAG_NONE,  (int (*)(struct hwmixer_stream * stream, char * drv, char * dev, int fh, char * basename, struct roar_keyval * subnames, size_t subnamelen))__true, (int (*)(struct hwmixer_stream * stream))__true, (int (*)(struct hwmixer_stream * stream, int channels, int mode, struct roar_mixer_settings * settings))__true, (int (*)(struct hwmixer_stream * stream, int channels, int mode, struct roar_mixer_settings * settings))__true},
52 {NULL,   NULL, NULL, FLAG_NONE, NULL, NULL, NULL, NULL}
53};
54
55void print_hwmixerlist (void) {
56 struct hwmixer * mixer;
57 int i;
58
59 printf("  Source   Flag Subsys - Description (devices)\n");
60 printf("------------------------------------------------------\n");
61
62 for (i = 0; (mixer = &(g_hwmixers[i]))->name != NULL; i++) {
63  printf("  %-9s %c   Mixer  - %s (devices: %s)\n",
64         mixer->name,
65         mixer->flags & FLAG_FHSEC ? 's' : ' ',
66         mixer->desc,
67         mixer->devs == NULL ? "(none)" : mixer->devs
68        );
69 }
70}
71
72void hwmixer_setup_info(struct hwmixer_stream * mstream) {
73 struct roar_stream_server * ss;
74
75 streams_get(mstream->stream, &ss);
76
77 memset(&(ROAR_STREAM(ss)->info), 0, sizeof(ROAR_STREAM(ss)->info));
78
79 streams_set_dir(mstream->stream, ROAR_DIR_MIXING, 1);
80
81 streams_set_flag(mstream->stream, ROAR_FLAG_HWMIXER);
82}
83
84int hwmixer_open(int basestream, char * drv, char * dev, int fh, char * basename, char * subnames) {
85 struct roar_stream_server * ss;
86 struct roar_keyval * subnamekv = NULL;
87 struct hwmixer * mixer = NULL;
88 struct hwmixer_stream * stream;
89 ssize_t subnamekvlen = 0;
90 int i;
91 int ret;
92
93 for (i = 0; g_hwmixers[i].name != NULL; i++) {
94  if ( !strcmp(g_hwmixers[i].name, drv) ) {
95   mixer = &(g_hwmixers[i]);
96   break;
97  }
98 }
99
100 if ( mixer == NULL ) {
101  ROAR_WARN("hwmixer_open(basestream=%i, drv='%s', dev='%s', fh=%i, basename='%s', subnames='%s'): Driver not found.", basestream, drv, dev, fh, basename, subnames);
102  return -1;
103 }
104
105 if ( mixer->open == NULL ) {
106  return -1;
107 }
108
109 if ( fh != -1 && !(mixer->flags & FLAG_FHSEC) ) {
110  return -1;
111 }
112
113 stream = roar_mm_malloc(sizeof(struct hwmixer_stream));
114 if ( stream == NULL )
115  return -1;
116
117 memset(stream, 0, sizeof(struct hwmixer_stream));
118
119 stream->hwmixer    = mixer;
120 stream->basestream = basestream;
121 stream->stream     = basestream;
122 stream->baseud     = NULL;
123 stream->ud         = NULL;
124
125 if ( basename == NULL ) {
126  streams_set_name(basestream, "Hardware Mixer");
127 } else {
128  streams_set_name(basestream, basename);
129 }
130
131 hwmixer_setup_info(stream);
132
133 if ( subnames != NULL ) {
134  subnamekvlen = roar_keyval_split(&subnamekv, subnames, ",;", "=:", 0);
135 }
136
137 ret = mixer->open(stream, drv, dev, fh, basename, subnamekv, subnamekvlen);
138
139 if ( subnamekv != NULL )
140  roar_mm_free(subnamekv);
141
142 if ( ret == -1 ) {
143  roar_mm_free(stream);
144  return -1;
145 }
146
147 streams_set_mixerstream(basestream, stream);
148
149 // try to get in sync with HW mixer.
150 // if possible read hw mixer state.
151 // if not possible write to force a sync value.
152 if ( streams_get(basestream, &ss) == 0 ) {
153  if ( mixer->get_vol != NULL ) {
154   hwmixer_get_volume(basestream, ss, stream, &(ss->mixer));
155  } else {
156   hwmixer_set_volume(basestream, ss, stream, &(ss->mixer));
157  }
158 }
159
160 return 0;
161}
162
163int hwmixer_close(int stream) {
164 struct hwmixer_stream * mstream = streams_get_mixerstream(stream);
165
166 if ( mstream == NULL )
167  return 0;
168
169 if ( mstream->hwmixer->close != NULL )
170  mstream->hwmixer->close(mstream);
171
172 roar_mm_free(mstream);
173
174 return 0;
175}
176
177int hwmixer_set_volume(int id, struct roar_stream_server * ss, struct hwmixer_stream * mstream, struct roar_mixer_settings *
178settings) {
179 if ( mstream->hwmixer->set_vol != NULL )
180  return mstream->hwmixer->set_vol(mstream, ROAR_STREAM(ss)->info.channels, HWMIXER_MODE_SET, settings);
181
182 return 0;
183}
184
185int hwmixer_get_volume(int id, struct roar_stream_server * ss, struct hwmixer_stream * mstream, struct roar_mixer_settings *
186settings) {
187 if ( mstream->hwmixer->get_vol != NULL )
188  return mstream->hwmixer->get_vol(mstream, ROAR_STREAM(ss)->info.channels, HWMIXER_MODE_ASK, settings);
189
190 return 0;
191}
192
193struct hwmixer_stream * hwmixer_substream_new(struct hwmixer_stream * parent) {
194 struct roar_stream_server * ss;
195 struct hwmixer_stream * stream;
196 int id;
197
198 ROAR_DBG("hwmixer_substream_new(parent=%p) = ?", parent);
199
200 if ( parent == NULL )
201  return NULL;
202
203 ROAR_DBG("hwmixer_substream_new(parent=%p) = ?", parent);
204
205 stream = roar_mm_malloc(sizeof(struct hwmixer_stream));
206 if ( stream == NULL )
207  return NULL;
208
209 ROAR_DBG("hwmixer_substream_new(parent=%p) = ?", parent);
210
211 if ( (id = streams_new_virtual(parent->basestream, &ss)) == -1 ) {
212  roar_mm_free(stream);
213  return NULL;
214 }
215
216 memset(stream, 0, sizeof(struct hwmixer_stream));
217
218 stream->hwmixer    = parent->hwmixer;
219 stream->basestream = parent->basestream;
220 stream->stream     = id;
221 stream->baseud     = parent->baseud;
222 stream->ud         = NULL;
223
224 hwmixer_setup_info(stream);
225
226 streams_set_mixerstream(id, stream);
227
228 ROAR_DBG("hwmixer_substream_new(parent=%p) = %p", parent, stream);
229
230 return stream;
231}
232
233#endif
234
235//ll
Note: See TracBrowser for help on using the repository browser.