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