/* * Copyright 2007 The Android Open Source Project * * Audio output device. */ #include "Common.h" #include <stdio.h> #include <stdlib.h> #include <string.h> #include <esd.h> #include <fcntl.h> #include <sys/ioctl.h> #include <linux/input.h> /* * Input event device state. */ typedef struct AudioState { int fd; int sourceId; int esdVol; int streamType; } AudioState; /* * Set some stuff up. */ static int configureInitialState(const char* pathName, AudioState* audioState) { #if BUILD_SIM_WITHOUT_AUDIO return 0; #else esd_player_info_t *pi; audioState->fd = -1; audioState->sourceId = -1; audioState->esdVol = -1; audioState->streamType = 0; int format = ESD_BITS16 | ESD_STEREO | ESD_STREAM | ESD_PLAY; char namestring[] = "Android Audio XXXXXXXX"; sprintf(namestring,"Android Audio %08x", (unsigned int)audioState); int esd_fd = esd_play_stream_fallback(format, 44100, NULL, namestring); if (esd_fd > 0) { // find the source_id for this stream int mix = esd_open_sound(NULL); if (mix > 0) { esd_info_t *info = esd_get_all_info(mix); if (info) { for(pi = info->player_list; pi; pi = pi->next) { if(strcmp(pi->name, namestring) == 0) { audioState->sourceId = pi->source_id; break; } } esd_free_all_info(info); } esd_close(mix); } audioState->fd = esd_fd; return 0; } printf("Couldn't open audio device. Faking it.\n"); return 0; #endif } /* * Return the next available input event. * * We just pass this through to the real "write", since "fd" is real. */ static ssize_t writeAudio(FakeDev* dev, int fd, const void* buf, size_t count) { #if BUILD_SIM_WITHOUT_AUDIO return 0; #else AudioState *state = (AudioState*)dev->state; if (state->fd >= 0) return _ws_write(state->fd, buf, count); // fake timing usleep(count * 10000 / 441 * 4); return count; #endif } /* * Handle event ioctls. */ static int ioctlAudio(FakeDev* dev, int fd, int request, void* argp) { return -1; } /* * Free up our state before closing down the fake descriptor. */ static int closeAudio(FakeDev* dev, int fd) { #if BUILD_SIM_WITHOUT_AUDIO return 0; #else AudioState *state = (AudioState*)dev->state; close(state->fd); free(state); dev->state = NULL; return 0; #endif } /* * Open an audio output device. */ FakeDev* wsOpenDevAudio(const char* pathName, int flags) { FakeDev* newDev = wsCreateFakeDev(pathName); if (newDev != NULL) { newDev->write = writeAudio; newDev->ioctl = ioctlAudio; newDev->close = closeAudio; AudioState* eventState = calloc(1, sizeof(AudioState)); if (configureInitialState(pathName, eventState) != 0) { free(eventState); return NULL; } newDev->state = eventState; } return newDev; }