media/libcubeb/src/cubeb.c

branch
TOR_BUG_9701
changeset 10
ac0c01689b40
equal deleted inserted replaced
-1:000000000000 0:4c589327bf14
1 /*
2 * Copyright © 2013 Mozilla Foundation
3 *
4 * This program is made available under an ISC-style license. See the
5 * accompanying file LICENSE for details.
6 */
7 #include <stddef.h>
8 #if defined(HAVE_CONFIG_H)
9 #include "config.h"
10 #endif
11 #include "cubeb/cubeb.h"
12 #include "cubeb-internal.h"
13
14 #define NELEMS(x) ((int) (sizeof(x) / sizeof(x[0])))
15
16 struct cubeb {
17 struct cubeb_ops * ops;
18 };
19
20 struct cubeb_stream {
21 struct cubeb * context;
22 };
23
24 #if defined(USE_PULSE)
25 int pulse_init(cubeb ** context, char const * context_name);
26 #endif
27 #if defined(USE_JACK)
28 int jack_init (cubeb ** context, char const * context_name);
29 #endif
30 #if defined(USE_ALSA)
31 int alsa_init(cubeb ** context, char const * context_name);
32 #endif
33 #if defined(USE_AUDIOQUEUE)
34 int audioqueue_init(cubeb ** context, char const * context_name);
35 #endif
36 #if defined(USE_AUDIOUNIT)
37 int audiounit_init(cubeb ** context, char const * context_name);
38 #endif
39 #if defined(USE_DIRECTSOUND)
40 int directsound_init(cubeb ** context, char const * context_name);
41 #endif
42 #if defined(USE_WINMM)
43 int winmm_init(cubeb ** context, char const * context_name);
44 #endif
45 #if defined(USE_WASAPI)
46 int wasapi_init(cubeb ** context, char const * context_name);
47 #endif
48 #if defined(USE_SNDIO)
49 int sndio_init(cubeb ** context, char const * context_name);
50 #endif
51 #if defined(USE_OPENSL)
52 int opensl_init(cubeb ** context, char const * context_name);
53 #endif
54 #if defined(USE_AUDIOTRACK)
55 int audiotrack_init(cubeb ** context, char const * context_name);
56 #endif
57
58 int
59 validate_stream_params(cubeb_stream_params stream_params)
60 {
61 if (stream_params.rate < 1000 || stream_params.rate > 192000 ||
62 stream_params.channels < 1 || stream_params.channels > 8) {
63 return CUBEB_ERROR_INVALID_FORMAT;
64 }
65
66 switch (stream_params.format) {
67 case CUBEB_SAMPLE_S16LE:
68 case CUBEB_SAMPLE_S16BE:
69 case CUBEB_SAMPLE_FLOAT32LE:
70 case CUBEB_SAMPLE_FLOAT32BE:
71 return CUBEB_OK;
72 }
73
74 return CUBEB_ERROR_INVALID_FORMAT;
75 }
76
77 int
78 validate_latency(int latency)
79 {
80 if (latency < 1 || latency > 2000) {
81 return CUBEB_ERROR_INVALID_PARAMETER;
82 }
83 return CUBEB_OK;
84 }
85
86 int
87 cubeb_init(cubeb ** context, char const * context_name)
88 {
89 int (* init[])(cubeb **, char const *) = {
90 #if defined(USE_PULSE)
91 pulse_init,
92 #endif
93 #if defined(USE_JACK)
94 jack_init,
95 #endif
96 #if defined(USE_ALSA)
97 alsa_init,
98 #endif
99 #if defined(USE_AUDIOUNIT)
100 audiounit_init,
101 #endif
102 #if defined(USE_AUDIOQUEUE)
103 audioqueue_init,
104 #endif
105 #if defined(USE_WASAPI)
106 wasapi_init,
107 #endif
108 #if defined(USE_WINMM)
109 winmm_init,
110 #endif
111 #if defined(USE_DIRECTSOUND)
112 directsound_init,
113 #endif
114 #if defined(USE_SNDIO)
115 sndio_init,
116 #endif
117 #if defined(USE_OPENSL)
118 opensl_init,
119 #endif
120 #if defined(USE_AUDIOTRACK)
121 audiotrack_init,
122 #endif
123 };
124 int i;
125
126 if (!context) {
127 return CUBEB_ERROR_INVALID_PARAMETER;
128 }
129
130 for (i = 0; i < NELEMS(init); ++i) {
131 if (init[i](context, context_name) == CUBEB_OK) {
132 return CUBEB_OK;
133 }
134 }
135
136 return CUBEB_ERROR;
137 }
138
139 char const *
140 cubeb_get_backend_id(cubeb * context)
141 {
142 if (!context) {
143 return NULL;
144 }
145
146 return context->ops->get_backend_id(context);
147 }
148
149 int
150 cubeb_get_max_channel_count(cubeb * context, uint32_t * max_channels)
151 {
152 if (!context || !max_channels) {
153 return CUBEB_ERROR_INVALID_PARAMETER;
154 }
155
156 return context->ops->get_max_channel_count(context, max_channels);
157 }
158
159 int
160 cubeb_get_min_latency(cubeb * context, cubeb_stream_params params, uint32_t * latency_ms)
161 {
162 if (!context || !latency_ms) {
163 return CUBEB_ERROR_INVALID_PARAMETER;
164 }
165 return context->ops->get_min_latency(context, params, latency_ms);
166 }
167
168 int
169 cubeb_get_preferred_sample_rate(cubeb * context, uint32_t * rate)
170 {
171 if (!context || !rate) {
172 return CUBEB_ERROR_INVALID_PARAMETER;
173 }
174 return context->ops->get_preferred_sample_rate(context, rate);
175 }
176
177 void
178 cubeb_destroy(cubeb * context)
179 {
180 if (!context) {
181 return;
182 }
183
184 context->ops->destroy(context);
185 }
186
187 int
188 cubeb_stream_init(cubeb * context, cubeb_stream ** stream, char const * stream_name,
189 cubeb_stream_params stream_params, unsigned int latency,
190 cubeb_data_callback data_callback,
191 cubeb_state_callback state_callback,
192 void * user_ptr)
193 {
194 int r;
195
196 if (!context || !stream) {
197 return CUBEB_ERROR_INVALID_PARAMETER;
198 }
199
200 if ((r = validate_stream_params(stream_params)) != CUBEB_OK ||
201 (r = validate_latency(latency)) != CUBEB_OK) {
202 return r;
203 }
204
205 return context->ops->stream_init(context, stream, stream_name,
206 stream_params, latency,
207 data_callback,
208 state_callback,
209 user_ptr);
210 }
211
212 void
213 cubeb_stream_destroy(cubeb_stream * stream)
214 {
215 if (!stream) {
216 return;
217 }
218
219 stream->context->ops->stream_destroy(stream);
220 }
221
222 int
223 cubeb_stream_start(cubeb_stream * stream)
224 {
225 if (!stream) {
226 return CUBEB_ERROR_INVALID_PARAMETER;
227 }
228
229 return stream->context->ops->stream_start(stream);
230 }
231
232 int
233 cubeb_stream_stop(cubeb_stream * stream)
234 {
235 if (!stream) {
236 return CUBEB_ERROR_INVALID_PARAMETER;
237 }
238
239 return stream->context->ops->stream_stop(stream);
240 }
241
242 int
243 cubeb_stream_get_position(cubeb_stream * stream, uint64_t * position)
244 {
245 if (!stream || !position) {
246 return CUBEB_ERROR_INVALID_PARAMETER;
247 }
248
249 return stream->context->ops->stream_get_position(stream, position);
250 }
251
252 int
253 cubeb_stream_get_latency(cubeb_stream * stream, uint32_t * latency)
254 {
255 if (!stream || !latency) {
256 return CUBEB_ERROR_INVALID_PARAMETER;
257 }
258
259 return stream->context->ops->stream_get_latency(stream, latency);
260 }

mercurial