1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/media/libcubeb/src/cubeb.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,260 @@ 1.4 +/* 1.5 + * Copyright © 2013 Mozilla Foundation 1.6 + * 1.7 + * This program is made available under an ISC-style license. See the 1.8 + * accompanying file LICENSE for details. 1.9 + */ 1.10 +#include <stddef.h> 1.11 +#if defined(HAVE_CONFIG_H) 1.12 +#include "config.h" 1.13 +#endif 1.14 +#include "cubeb/cubeb.h" 1.15 +#include "cubeb-internal.h" 1.16 + 1.17 +#define NELEMS(x) ((int) (sizeof(x) / sizeof(x[0]))) 1.18 + 1.19 +struct cubeb { 1.20 + struct cubeb_ops * ops; 1.21 +}; 1.22 + 1.23 +struct cubeb_stream { 1.24 + struct cubeb * context; 1.25 +}; 1.26 + 1.27 +#if defined(USE_PULSE) 1.28 +int pulse_init(cubeb ** context, char const * context_name); 1.29 +#endif 1.30 +#if defined(USE_JACK) 1.31 +int jack_init (cubeb ** context, char const * context_name); 1.32 +#endif 1.33 +#if defined(USE_ALSA) 1.34 +int alsa_init(cubeb ** context, char const * context_name); 1.35 +#endif 1.36 +#if defined(USE_AUDIOQUEUE) 1.37 +int audioqueue_init(cubeb ** context, char const * context_name); 1.38 +#endif 1.39 +#if defined(USE_AUDIOUNIT) 1.40 +int audiounit_init(cubeb ** context, char const * context_name); 1.41 +#endif 1.42 +#if defined(USE_DIRECTSOUND) 1.43 +int directsound_init(cubeb ** context, char const * context_name); 1.44 +#endif 1.45 +#if defined(USE_WINMM) 1.46 +int winmm_init(cubeb ** context, char const * context_name); 1.47 +#endif 1.48 +#if defined(USE_WASAPI) 1.49 +int wasapi_init(cubeb ** context, char const * context_name); 1.50 +#endif 1.51 +#if defined(USE_SNDIO) 1.52 +int sndio_init(cubeb ** context, char const * context_name); 1.53 +#endif 1.54 +#if defined(USE_OPENSL) 1.55 +int opensl_init(cubeb ** context, char const * context_name); 1.56 +#endif 1.57 +#if defined(USE_AUDIOTRACK) 1.58 +int audiotrack_init(cubeb ** context, char const * context_name); 1.59 +#endif 1.60 + 1.61 +int 1.62 +validate_stream_params(cubeb_stream_params stream_params) 1.63 +{ 1.64 + if (stream_params.rate < 1000 || stream_params.rate > 192000 || 1.65 + stream_params.channels < 1 || stream_params.channels > 8) { 1.66 + return CUBEB_ERROR_INVALID_FORMAT; 1.67 + } 1.68 + 1.69 + switch (stream_params.format) { 1.70 + case CUBEB_SAMPLE_S16LE: 1.71 + case CUBEB_SAMPLE_S16BE: 1.72 + case CUBEB_SAMPLE_FLOAT32LE: 1.73 + case CUBEB_SAMPLE_FLOAT32BE: 1.74 + return CUBEB_OK; 1.75 + } 1.76 + 1.77 + return CUBEB_ERROR_INVALID_FORMAT; 1.78 +} 1.79 + 1.80 +int 1.81 +validate_latency(int latency) 1.82 +{ 1.83 + if (latency < 1 || latency > 2000) { 1.84 + return CUBEB_ERROR_INVALID_PARAMETER; 1.85 + } 1.86 + return CUBEB_OK; 1.87 +} 1.88 + 1.89 +int 1.90 +cubeb_init(cubeb ** context, char const * context_name) 1.91 +{ 1.92 + int (* init[])(cubeb **, char const *) = { 1.93 +#if defined(USE_PULSE) 1.94 + pulse_init, 1.95 +#endif 1.96 +#if defined(USE_JACK) 1.97 + jack_init, 1.98 +#endif 1.99 +#if defined(USE_ALSA) 1.100 + alsa_init, 1.101 +#endif 1.102 +#if defined(USE_AUDIOUNIT) 1.103 + audiounit_init, 1.104 +#endif 1.105 +#if defined(USE_AUDIOQUEUE) 1.106 + audioqueue_init, 1.107 +#endif 1.108 +#if defined(USE_WASAPI) 1.109 + wasapi_init, 1.110 +#endif 1.111 +#if defined(USE_WINMM) 1.112 + winmm_init, 1.113 +#endif 1.114 +#if defined(USE_DIRECTSOUND) 1.115 + directsound_init, 1.116 +#endif 1.117 +#if defined(USE_SNDIO) 1.118 + sndio_init, 1.119 +#endif 1.120 +#if defined(USE_OPENSL) 1.121 + opensl_init, 1.122 +#endif 1.123 +#if defined(USE_AUDIOTRACK) 1.124 + audiotrack_init, 1.125 +#endif 1.126 + }; 1.127 + int i; 1.128 + 1.129 + if (!context) { 1.130 + return CUBEB_ERROR_INVALID_PARAMETER; 1.131 + } 1.132 + 1.133 + for (i = 0; i < NELEMS(init); ++i) { 1.134 + if (init[i](context, context_name) == CUBEB_OK) { 1.135 + return CUBEB_OK; 1.136 + } 1.137 + } 1.138 + 1.139 + return CUBEB_ERROR; 1.140 +} 1.141 + 1.142 +char const * 1.143 +cubeb_get_backend_id(cubeb * context) 1.144 +{ 1.145 + if (!context) { 1.146 + return NULL; 1.147 + } 1.148 + 1.149 + return context->ops->get_backend_id(context); 1.150 +} 1.151 + 1.152 +int 1.153 +cubeb_get_max_channel_count(cubeb * context, uint32_t * max_channels) 1.154 +{ 1.155 + if (!context || !max_channels) { 1.156 + return CUBEB_ERROR_INVALID_PARAMETER; 1.157 + } 1.158 + 1.159 + return context->ops->get_max_channel_count(context, max_channels); 1.160 +} 1.161 + 1.162 +int 1.163 +cubeb_get_min_latency(cubeb * context, cubeb_stream_params params, uint32_t * latency_ms) 1.164 +{ 1.165 + if (!context || !latency_ms) { 1.166 + return CUBEB_ERROR_INVALID_PARAMETER; 1.167 + } 1.168 + return context->ops->get_min_latency(context, params, latency_ms); 1.169 +} 1.170 + 1.171 +int 1.172 +cubeb_get_preferred_sample_rate(cubeb * context, uint32_t * rate) 1.173 +{ 1.174 + if (!context || !rate) { 1.175 + return CUBEB_ERROR_INVALID_PARAMETER; 1.176 + } 1.177 + return context->ops->get_preferred_sample_rate(context, rate); 1.178 +} 1.179 + 1.180 +void 1.181 +cubeb_destroy(cubeb * context) 1.182 +{ 1.183 + if (!context) { 1.184 + return; 1.185 + } 1.186 + 1.187 + context->ops->destroy(context); 1.188 +} 1.189 + 1.190 +int 1.191 +cubeb_stream_init(cubeb * context, cubeb_stream ** stream, char const * stream_name, 1.192 + cubeb_stream_params stream_params, unsigned int latency, 1.193 + cubeb_data_callback data_callback, 1.194 + cubeb_state_callback state_callback, 1.195 + void * user_ptr) 1.196 +{ 1.197 + int r; 1.198 + 1.199 + if (!context || !stream) { 1.200 + return CUBEB_ERROR_INVALID_PARAMETER; 1.201 + } 1.202 + 1.203 + if ((r = validate_stream_params(stream_params)) != CUBEB_OK || 1.204 + (r = validate_latency(latency)) != CUBEB_OK) { 1.205 + return r; 1.206 + } 1.207 + 1.208 + return context->ops->stream_init(context, stream, stream_name, 1.209 + stream_params, latency, 1.210 + data_callback, 1.211 + state_callback, 1.212 + user_ptr); 1.213 +} 1.214 + 1.215 +void 1.216 +cubeb_stream_destroy(cubeb_stream * stream) 1.217 +{ 1.218 + if (!stream) { 1.219 + return; 1.220 + } 1.221 + 1.222 + stream->context->ops->stream_destroy(stream); 1.223 +} 1.224 + 1.225 +int 1.226 +cubeb_stream_start(cubeb_stream * stream) 1.227 +{ 1.228 + if (!stream) { 1.229 + return CUBEB_ERROR_INVALID_PARAMETER; 1.230 + } 1.231 + 1.232 + return stream->context->ops->stream_start(stream); 1.233 +} 1.234 + 1.235 +int 1.236 +cubeb_stream_stop(cubeb_stream * stream) 1.237 +{ 1.238 + if (!stream) { 1.239 + return CUBEB_ERROR_INVALID_PARAMETER; 1.240 + } 1.241 + 1.242 + return stream->context->ops->stream_stop(stream); 1.243 +} 1.244 + 1.245 +int 1.246 +cubeb_stream_get_position(cubeb_stream * stream, uint64_t * position) 1.247 +{ 1.248 + if (!stream || !position) { 1.249 + return CUBEB_ERROR_INVALID_PARAMETER; 1.250 + } 1.251 + 1.252 + return stream->context->ops->stream_get_position(stream, position); 1.253 +} 1.254 + 1.255 +int 1.256 +cubeb_stream_get_latency(cubeb_stream * stream, uint32_t * latency) 1.257 +{ 1.258 + if (!stream || !latency) { 1.259 + return CUBEB_ERROR_INVALID_PARAMETER; 1.260 + } 1.261 + 1.262 + return stream->context->ops->stream_get_latency(stream, latency); 1.263 +}