1 /* 2 * Copyright 2007 The Android Open Source Project 3 * 4 * Audio output device. 5 */ 6 #include "Common.h" 7 8 #include <stdio.h> 9 #include <stdlib.h> 10 #include <string.h> 11 #include <alsa/asoundlib.h> 12 13 #include <fcntl.h> 14 #include <sys/ioctl.h> 15 #include <linux/input.h> 16 17 18 /* 19 * Input event device state. 20 */ 21 typedef struct AudioState { 22 snd_pcm_t *handle; 23 } AudioState; 24 25 /* 26 * Set some stuff up. 27 */ 28 static int configureInitialState(const char* pathName, AudioState* audioState) 29 { 30 #if BUILD_SIM_WITHOUT_AUDIO 31 return 0; 32 #else 33 audioState->handle = NULL; 34 35 snd_pcm_open(&audioState->handle, "default", SND_PCM_STREAM_PLAYBACK, 0); 36 37 if (audioState->handle) { 38 snd_pcm_hw_params_t *params; 39 snd_pcm_hw_params_malloc(¶ms); 40 snd_pcm_hw_params_any(audioState->handle, params); 41 snd_pcm_hw_params_set_access(audioState->handle, params, SND_PCM_ACCESS_RW_INTERLEAVED); 42 snd_pcm_hw_params_set_format(audioState->handle, params, SND_PCM_FORMAT_S16_LE); 43 unsigned int rate = 44100; 44 snd_pcm_hw_params_set_rate_near(audioState->handle, params, &rate, NULL); 45 snd_pcm_hw_params_set_channels(audioState->handle, params, 2); 46 snd_pcm_hw_params(audioState->handle, params); 47 snd_pcm_hw_params_free(params); 48 } else { 49 wsLog("Couldn't open audio hardware, faking it\n"); 50 } 51 52 return 0; 53 #endif 54 } 55 56 /* 57 * Write audio data. 58 */ 59 static ssize_t writeAudio(FakeDev* dev, int fd, const void* buf, size_t count) 60 { 61 #if BUILD_SIM_WITHOUT_AUDIO 62 return 0; 63 #else 64 AudioState *state = (AudioState*)dev->state; 65 if (state->handle != NULL) { 66 snd_pcm_writei(state->handle, buf, count / 4); 67 return count; 68 } 69 70 // fake timing 71 usleep(count * 10000 / (441 * 4)); 72 return count; 73 #endif 74 } 75 76 /* 77 * Handle event ioctls. 78 */ 79 static int ioctlAudio(FakeDev* dev, int fd, int request, void* argp) 80 { 81 return -1; 82 } 83 84 /* 85 * Free up our state before closing down the fake descriptor. 86 */ 87 static int closeAudio(FakeDev* dev, int fd) 88 { 89 #if BUILD_SIM_WITHOUT_AUDIO 90 return 0; 91 #else 92 AudioState *state = (AudioState*)dev->state; 93 snd_pcm_close(state->handle); 94 free(state); 95 dev->state = NULL; 96 return 0; 97 #endif 98 } 99 100 /* 101 * Open an audio output device. 102 */ 103 FakeDev* wsOpenDevAudio(const char* pathName, int flags) 104 { 105 FakeDev* newDev = wsCreateFakeDev(pathName); 106 if (newDev != NULL) { 107 newDev->write = writeAudio; 108 newDev->ioctl = ioctlAudio; 109 newDev->close = closeAudio; 110 111 AudioState* eventState = calloc(1, sizeof(AudioState)); 112 113 if (configureInitialState(pathName, eventState) != 0) { 114 free(eventState); 115 return NULL; 116 } 117 newDev->state = eventState; 118 } 119 120 return newDev; 121 } 122