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
testAudio_audio_callback(void * opaque,int free)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
testAudio_init(TestAudio * ta)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
android_audio_test_start_out(void)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