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