Home | History | Annotate | Download | only in wrapsim
      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(&params);
     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