1 /* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #define LOG_TAG "usb_audio_hw" 18 /*#define LOG_NDEBUG 0*/ 19 20 #include <errno.h> 21 #include <pthread.h> 22 #include <stdint.h> 23 #include <sys/time.h> 24 #include <stdlib.h> 25 26 #include <cutils/log.h> 27 #include <cutils/str_parms.h> 28 #include <cutils/properties.h> 29 30 #include <hardware/hardware.h> 31 #include <system/audio.h> 32 #include <hardware/audio.h> 33 34 #include <tinyalsa/asoundlib.h> 35 36 struct pcm_config pcm_config = { 37 .channels = 2, 38 .rate = 44100, 39 .period_size = 1024, 40 .period_count = 4, 41 .format = PCM_FORMAT_S16_LE, 42 }; 43 44 struct audio_device { 45 struct audio_hw_device hw_device; 46 47 pthread_mutex_t lock; /* see note below on mutex acquisition order */ 48 int card; 49 int device; 50 bool standby; 51 }; 52 53 struct stream_out { 54 struct audio_stream_out stream; 55 56 pthread_mutex_t lock; /* see note below on mutex acquisition order */ 57 struct pcm *pcm; 58 bool standby; 59 60 struct audio_device *dev; 61 }; 62 63 /** 64 * NOTE: when multiple mutexes have to be acquired, always respect the 65 * following order: hw device > out stream 66 */ 67 68 /* Helper functions */ 69 70 /* must be called with hw device and output stream mutexes locked */ 71 static int start_output_stream(struct stream_out *out) 72 { 73 struct audio_device *adev = out->dev; 74 int i; 75 76 if ((adev->card < 0) || (adev->device < 0)) 77 return -EINVAL; 78 79 out->pcm = pcm_open(adev->card, adev->device, PCM_OUT, &pcm_config); 80 81 if (out->pcm && !pcm_is_ready(out->pcm)) { 82 ALOGE("pcm_open() failed: %s", pcm_get_error(out->pcm)); 83 pcm_close(out->pcm); 84 return -ENOMEM; 85 } 86 87 return 0; 88 } 89 90 /* API functions */ 91 92 static uint32_t out_get_sample_rate(const struct audio_stream *stream) 93 { 94 return pcm_config.rate; 95 } 96 97 static int out_set_sample_rate(struct audio_stream *stream, uint32_t rate) 98 { 99 return 0; 100 } 101 102 static size_t out_get_buffer_size(const struct audio_stream *stream) 103 { 104 return pcm_config.period_size * 105 audio_stream_frame_size((struct audio_stream *)stream); 106 } 107 108 static uint32_t out_get_channels(const struct audio_stream *stream) 109 { 110 return AUDIO_CHANNEL_OUT_STEREO; 111 } 112 113 static audio_format_t out_get_format(const struct audio_stream *stream) 114 { 115 return AUDIO_FORMAT_PCM_16_BIT; 116 } 117 118 static int out_set_format(struct audio_stream *stream, audio_format_t format) 119 { 120 return 0; 121 } 122 123 static int out_standby(struct audio_stream *stream) 124 { 125 struct stream_out *out = (struct stream_out *)stream; 126 127 pthread_mutex_lock(&out->dev->lock); 128 pthread_mutex_lock(&out->lock); 129 130 if (!out->standby) { 131 pcm_close(out->pcm); 132 out->pcm = NULL; 133 out->standby = true; 134 } 135 136 pthread_mutex_unlock(&out->lock); 137 pthread_mutex_unlock(&out->dev->lock); 138 139 return 0; 140 } 141 142 static int out_dump(const struct audio_stream *stream, int fd) 143 { 144 return 0; 145 } 146 147 static int out_set_parameters(struct audio_stream *stream, const char *kvpairs) 148 { 149 struct stream_out *out = (struct stream_out *)stream; 150 struct audio_device *adev = out->dev; 151 struct str_parms *parms; 152 char value[32]; 153 int ret; 154 int routing = 0; 155 156 parms = str_parms_create_str(kvpairs); 157 pthread_mutex_lock(&adev->lock); 158 159 ret = str_parms_get_str(parms, "card", value, sizeof(value)); 160 if (ret >= 0) 161 adev->card = atoi(value); 162 163 ret = str_parms_get_str(parms, "device", value, sizeof(value)); 164 if (ret >= 0) 165 adev->device = atoi(value); 166 167 pthread_mutex_unlock(&adev->lock); 168 str_parms_destroy(parms); 169 170 return 0; 171 } 172 173 static char * out_get_parameters(const struct audio_stream *stream, const char *keys) 174 { 175 return strdup(""); 176 } 177 178 static uint32_t out_get_latency(const struct audio_stream_out *stream) 179 { 180 return (pcm_config.period_size * pcm_config.period_count * 1000) / 181 out_get_sample_rate(&stream->common); 182 } 183 184 static int out_set_volume(struct audio_stream_out *stream, float left, 185 float right) 186 { 187 return -ENOSYS; 188 } 189 190 static ssize_t out_write(struct audio_stream_out *stream, const void* buffer, 191 size_t bytes) 192 { 193 int ret; 194 struct stream_out *out = (struct stream_out *)stream; 195 196 pthread_mutex_lock(&out->dev->lock); 197 pthread_mutex_lock(&out->lock); 198 if (out->standby) { 199 ret = start_output_stream(out); 200 if (ret != 0) { 201 goto err; 202 } 203 out->standby = false; 204 } 205 206 pcm_write(out->pcm, (void *)buffer, bytes); 207 208 pthread_mutex_unlock(&out->lock); 209 pthread_mutex_unlock(&out->dev->lock); 210 211 return bytes; 212 213 err: 214 pthread_mutex_unlock(&out->lock); 215 pthread_mutex_unlock(&out->dev->lock); 216 if (ret != 0) { 217 usleep(bytes * 1000000 / audio_stream_frame_size(&stream->common) / 218 out_get_sample_rate(&stream->common)); 219 } 220 221 return bytes; 222 } 223 224 static int out_get_render_position(const struct audio_stream_out *stream, 225 uint32_t *dsp_frames) 226 { 227 return -EINVAL; 228 } 229 230 static int out_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect) 231 { 232 return 0; 233 } 234 235 static int out_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect) 236 { 237 return 0; 238 } 239 240 static int out_get_next_write_timestamp(const struct audio_stream_out *stream, 241 int64_t *timestamp) 242 { 243 return -EINVAL; 244 } 245 246 static int adev_open_output_stream(struct audio_hw_device *dev, 247 audio_io_handle_t handle, 248 audio_devices_t devices, 249 audio_output_flags_t flags, 250 struct audio_config *config, 251 struct audio_stream_out **stream_out) 252 { 253 struct audio_device *adev = (struct audio_device *)dev; 254 struct stream_out *out; 255 int ret; 256 257 out = (struct stream_out *)calloc(1, sizeof(struct stream_out)); 258 if (!out) 259 return -ENOMEM; 260 261 out->stream.common.get_sample_rate = out_get_sample_rate; 262 out->stream.common.set_sample_rate = out_set_sample_rate; 263 out->stream.common.get_buffer_size = out_get_buffer_size; 264 out->stream.common.get_channels = out_get_channels; 265 out->stream.common.get_format = out_get_format; 266 out->stream.common.set_format = out_set_format; 267 out->stream.common.standby = out_standby; 268 out->stream.common.dump = out_dump; 269 out->stream.common.set_parameters = out_set_parameters; 270 out->stream.common.get_parameters = out_get_parameters; 271 out->stream.common.add_audio_effect = out_add_audio_effect; 272 out->stream.common.remove_audio_effect = out_remove_audio_effect; 273 out->stream.get_latency = out_get_latency; 274 out->stream.set_volume = out_set_volume; 275 out->stream.write = out_write; 276 out->stream.get_render_position = out_get_render_position; 277 out->stream.get_next_write_timestamp = out_get_next_write_timestamp; 278 279 out->dev = adev; 280 281 config->format = out_get_format(&out->stream.common); 282 config->channel_mask = out_get_channels(&out->stream.common); 283 config->sample_rate = out_get_sample_rate(&out->stream.common); 284 285 out->standby = true; 286 287 adev->card = -1; 288 adev->device = -1; 289 290 *stream_out = &out->stream; 291 return 0; 292 293 err_open: 294 free(out); 295 *stream_out = NULL; 296 return ret; 297 } 298 299 static void adev_close_output_stream(struct audio_hw_device *dev, 300 struct audio_stream_out *stream) 301 { 302 struct stream_out *out = (struct stream_out *)stream; 303 304 out_standby(&stream->common); 305 free(stream); 306 } 307 308 static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs) 309 { 310 return 0; 311 } 312 313 static char * adev_get_parameters(const struct audio_hw_device *dev, 314 const char *keys) 315 { 316 return strdup(""); 317 } 318 319 static int adev_init_check(const struct audio_hw_device *dev) 320 { 321 return 0; 322 } 323 324 static int adev_set_voice_volume(struct audio_hw_device *dev, float volume) 325 { 326 return -ENOSYS; 327 } 328 329 static int adev_set_master_volume(struct audio_hw_device *dev, float volume) 330 { 331 return -ENOSYS; 332 } 333 334 static int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode) 335 { 336 return 0; 337 } 338 339 static int adev_set_mic_mute(struct audio_hw_device *dev, bool state) 340 { 341 return -ENOSYS; 342 } 343 344 static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state) 345 { 346 return -ENOSYS; 347 } 348 349 static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev, 350 const struct audio_config *config) 351 { 352 return 0; 353 } 354 355 static int adev_open_input_stream(struct audio_hw_device *dev, 356 audio_io_handle_t handle, 357 audio_devices_t devices, 358 struct audio_config *config, 359 struct audio_stream_in **stream_in) 360 { 361 return -ENOSYS; 362 } 363 364 static void adev_close_input_stream(struct audio_hw_device *dev, 365 struct audio_stream_in *stream) 366 { 367 } 368 369 static int adev_dump(const audio_hw_device_t *device, int fd) 370 { 371 return 0; 372 } 373 374 static int adev_close(hw_device_t *device) 375 { 376 struct audio_device *adev = (struct audio_device *)device; 377 378 free(device); 379 return 0; 380 } 381 382 static int adev_open(const hw_module_t* module, const char* name, 383 hw_device_t** device) 384 { 385 struct audio_device *adev; 386 int ret; 387 388 if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0) 389 return -EINVAL; 390 391 adev = calloc(1, sizeof(struct audio_device)); 392 if (!adev) 393 return -ENOMEM; 394 395 adev->hw_device.common.tag = HARDWARE_DEVICE_TAG; 396 adev->hw_device.common.version = AUDIO_DEVICE_API_VERSION_2_0; 397 adev->hw_device.common.module = (struct hw_module_t *) module; 398 adev->hw_device.common.close = adev_close; 399 400 adev->hw_device.init_check = adev_init_check; 401 adev->hw_device.set_voice_volume = adev_set_voice_volume; 402 adev->hw_device.set_master_volume = adev_set_master_volume; 403 adev->hw_device.set_mode = adev_set_mode; 404 adev->hw_device.set_mic_mute = adev_set_mic_mute; 405 adev->hw_device.get_mic_mute = adev_get_mic_mute; 406 adev->hw_device.set_parameters = adev_set_parameters; 407 adev->hw_device.get_parameters = adev_get_parameters; 408 adev->hw_device.get_input_buffer_size = adev_get_input_buffer_size; 409 adev->hw_device.open_output_stream = adev_open_output_stream; 410 adev->hw_device.close_output_stream = adev_close_output_stream; 411 adev->hw_device.open_input_stream = adev_open_input_stream; 412 adev->hw_device.close_input_stream = adev_close_input_stream; 413 adev->hw_device.dump = adev_dump; 414 415 *device = &adev->hw_device.common; 416 417 return 0; 418 } 419 420 static struct hw_module_methods_t hal_module_methods = { 421 .open = adev_open, 422 }; 423 424 struct audio_module HAL_MODULE_INFO_SYM = { 425 .common = { 426 .tag = HARDWARE_MODULE_TAG, 427 .module_api_version = AUDIO_MODULE_API_VERSION_0_1, 428 .hal_api_version = HARDWARE_HAL_API_VERSION, 429 .id = AUDIO_HARDWARE_MODULE_ID, 430 .name = "USB audio HW HAL", 431 .author = "The Android Open Source Project", 432 .methods = &hal_module_methods, 433 }, 434 }; 435