Home | History | Annotate | Download | only in android
      1 /* Copyright (C) 2010 The Android Open Source Project
      2 **
      3 ** This software is licensed under the terms of the GNU General Public
      4 ** License version 2, as published by the Free Software Foundation, and
      5 ** may be copied, distributed, and modified under those terms.
      6 **
      7 ** This program is distributed in the hope that it will be useful,
      8 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
      9 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     10 ** GNU General Public License for more details.
     11 */
     12 #include "audio/audio.h"
     13 #include "android/utils/debug.h"
     14 
     15 /* This source file contains a small test audio virtual device that
     16  * can be used to check that the emulator properly plays sound on
     17  * the host system without having to boot a full system.
     18  */
     19 
     20 #define SAMPLE_SIZE  16384
     21 
     22 typedef struct {
     23     QEMUSoundCard  card;
     24     SWVoiceOut    *voice;
     25     int            pos;
     26     short          sample[SAMPLE_SIZE];
     27 } TestAudio;
     28 
     29 static void
     30 testAudio_audio_callback(void* opaque, int free)
     31 {
     32     TestAudio* ta = opaque;
     33 
     34     //printf("%s: pos=%d free=%d\n", __FUNCTION__, ta->pos, free);
     35 
     36     while (free > 0) {
     37         int  avail = SAMPLE_SIZE - ta->pos;
     38         if (avail > free)
     39             avail = free;
     40 
     41         AUD_write(ta->voice, ta->sample + ta->pos, avail);
     42         ta->pos += avail;
     43         if (ta->pos >= SAMPLE_SIZE)
     44             ta->pos = 0;
     45 
     46         free -= avail;
     47     }
     48 }
     49 
     50 static int
     51 testAudio_init( TestAudio* ta )
     52 {
     53     struct audsettings as;
     54 
     55     AUD_register_card("test_audio", &ta->card);
     56 
     57     as.freq       = 16000;
     58     as.nchannels  = 1;
     59     as.fmt        = AUD_FMT_S16;
     60     as.endianness = AUDIO_HOST_ENDIANNESS;
     61 
     62     ta->voice = AUD_open_out(
     63         &ta->card,
     64         ta->voice,
     65         "test_audio",
     66         ta,
     67         testAudio_audio_callback,
     68         &as);
     69 
     70     if (!ta->voice) {
     71         dprint("Cannot open test audio!");
     72         return -1;
     73     }
     74     ta->pos = 0;
     75 
     76     /* Initialize samples */
     77     int nn;
     78     for (nn = 0; nn < SAMPLE_SIZE; nn++) {
     79         ta->sample[nn] = (short)(((nn % (SAMPLE_SIZE/4))*65536/(SAMPLE_SIZE/4)) & 0xffff);
     80     }
     81 
     82     AUD_set_active_out(ta->voice, 1);
     83     return 0;
     84 }
     85 
     86 static TestAudio*  testAudio;
     87 
     88 int
     89 android_audio_test_start_out(void)
     90 {
     91     if (!testAudio) {
     92         testAudio = malloc(sizeof(*testAudio));
     93         if (testAudio_init(testAudio) < 0) {
     94             free(testAudio);
     95             testAudio = NULL;
     96             fprintf(stderr, "Could not start audio test!\n");
     97             return -1;
     98         } else {
     99             printf("Audio test started!\n");
    100         }
    101     }
    102     return 0;
    103 }
    104