source: roaraudio/roard/hwmixer.c @ 4378:df6cda763dce

Last change on this file since 4378:df6cda763dce was 4378:df6cda763dce, checked in by phi, 14 years ago

implemented support to read mixer values from hwmixer

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