blob: 752ee6534bb98358f42b257202e2c7f7580cc757 [file] [log] [blame]
The Android Open Source Project52d4c302009-03-03 19:29:09 -08001/*
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 <esd.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 */
21typedef struct AudioState {
22 int fd;
23 int sourceId;
24 int esdVol;
25 int streamType;
26} AudioState;
27
28/*
29 * Set some stuff up.
30 */
31static int configureInitialState(const char* pathName, AudioState* audioState)
32{
33#if BUILD_SIM_WITHOUT_AUDIO
34 return 0;
35#else
36 esd_player_info_t *pi;
37 audioState->fd = -1;
38 audioState->sourceId = -1;
39 audioState->esdVol = -1;
40 audioState->streamType = 0;
41
42 int format = ESD_BITS16 | ESD_STEREO | ESD_STREAM | ESD_PLAY;
43 char namestring[] = "Android Audio XXXXXXXX";
44 sprintf(namestring,"Android Audio %08x", (unsigned int)audioState);
45 int esd_fd = esd_play_stream_fallback(format, 44100, NULL, namestring);
46 if (esd_fd > 0) {
47 // find the source_id for this stream
48 int mix = esd_open_sound(NULL);
49 if (mix > 0) {
50 esd_info_t *info = esd_get_all_info(mix);
51
52 if (info) {
53 for(pi = info->player_list; pi; pi = pi->next) {
54 if(strcmp(pi->name, namestring) == 0) {
55 audioState->sourceId = pi->source_id;
56 break;
57 }
58 }
59 esd_free_all_info(info);
60 }
61 esd_close(mix);
62 }
63 audioState->fd = esd_fd;
64 return 0;
65 }
66 printf("Couldn't open audio device. Faking it.\n");
67 return 0;
68#endif
69}
70
71/*
72 * Return the next available input event.
73 *
74 * We just pass this through to the real "write", since "fd" is real.
75 */
76static ssize_t writeAudio(FakeDev* dev, int fd, const void* buf, size_t count)
77{
78#if BUILD_SIM_WITHOUT_AUDIO
79 return 0;
80#else
81 AudioState *state = (AudioState*)dev->state;
82 if (state->fd >= 0)
83 return _ws_write(state->fd, buf, count);
84
85 // fake timing
86 usleep(count * 10000 / 441 * 4);
87 return count;
88#endif
89}
90
91/*
92 * Handle event ioctls.
93 */
94static int ioctlAudio(FakeDev* dev, int fd, int request, void* argp)
95{
96 return -1;
97}
98
99/*
100 * Free up our state before closing down the fake descriptor.
101 */
102static int closeAudio(FakeDev* dev, int fd)
103{
104#if BUILD_SIM_WITHOUT_AUDIO
105 return 0;
106#else
107 AudioState *state = (AudioState*)dev->state;
108 close(state->fd);
109 free(state);
110 dev->state = NULL;
111 return 0;
112#endif
113}
114
115/*
116 * Open an audio output device.
117 */
118FakeDev* wsOpenDevAudio(const char* pathName, int flags)
119{
120 FakeDev* newDev = wsCreateFakeDev(pathName);
121 if (newDev != NULL) {
122 newDev->write = writeAudio;
123 newDev->ioctl = ioctlAudio;
124 newDev->close = closeAudio;
125
126 AudioState* eventState = calloc(1, sizeof(AudioState));
127
128 if (configureInitialState(pathName, eventState) != 0) {
129 free(eventState);
130 return NULL;
131 }
132 newDev->state = eventState;
133 }
134
135 return newDev;
136}