David 'Digit' Turner | ca29fbb | 2011-01-02 13:17:22 +0100 | [diff] [blame] | 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 | } |