media/libcubeb/src/cubeb.c

Fri, 16 Jan 2015 04:50:19 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Fri, 16 Jan 2015 04:50:19 +0100
branch
TOR_BUG_9701
changeset 13
44a2da4a2ab2
permissions
-rw-r--r--

Replace accessor implementation with direct member state manipulation, by
request https://trac.torproject.org/projects/tor/ticket/9701#comment:32

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

mercurial