Add -audio-test-out option to the core.

This option can be used to quickly check audio output (without
having to boot a full AVD and launch a sound-playing application).

Usage:
   emulator <other-options> -qemu -audio-test-out
   qemu-android <other-options> -audio-test-out

This simply generates an ugly saw signal, but that's enough for us.

Change-Id: I060300b4000b9705d181c6262de8d4d13c749e69
diff --git a/Makefile.android b/Makefile.android
index 7849775..b13cd47 100644
--- a/Makefile.android
+++ b/Makefile.android
@@ -735,6 +735,8 @@
 CORE_SOURCES += $(CORE_MIGRATION_SOURCES) $(CORE_MISC_SOURCES)
 CORE_SOURCES += $(CORE_UPSTREAM_SOURCES)
 
+CORE_SOURCES += android/audio-test.c
+
 ##############################################################################
 # lists of source files used to build the emulator UI
 #
diff --git a/android/audio-test.c b/android/audio-test.c
new file mode 100644
index 0000000..e10b987
--- /dev/null
+++ b/android/audio-test.c
@@ -0,0 +1,103 @@
+/* Copyright (C) 2010 The Android Open Source Project
+**
+** This software is licensed under the terms of the GNU General Public
+** License version 2, as published by the Free Software Foundation, and
+** may be copied, distributed, and modified under those terms.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU General Public License for more details.
+*/
+#include "audio/audio.h"
+#include "android/utils/debug.h"
+
+/* This source file contains a small test audio virtual device that
+ * can be used to check that the emulator properly plays sound on
+ * the host system without having to boot a full system.
+ */
+
+#define SAMPLE_SIZE  16384
+
+typedef struct {
+    QEMUSoundCard  card;
+    SWVoiceOut    *voice;
+    int            pos;
+    short          sample[SAMPLE_SIZE];
+} TestAudio;
+
+static void
+testAudio_audio_callback(void* opaque, int free)
+{
+    TestAudio* ta = opaque;
+
+    //printf("%s: pos=%d free=%d\n", __FUNCTION__, ta->pos, free);
+
+    while (free > 0) {
+        int  avail = SAMPLE_SIZE - ta->pos;
+        if (avail > free)
+            avail = free;
+
+        AUD_write(ta->voice, ta->sample + ta->pos, avail);
+        ta->pos += avail;
+        if (ta->pos >= SAMPLE_SIZE)
+            ta->pos = 0;
+
+        free -= avail;
+    }
+}
+
+static int
+testAudio_init( TestAudio* ta )
+{
+    struct audsettings as;
+
+    AUD_register_card("test_audio", &ta->card);
+
+    as.freq       = 16000;
+    as.nchannels  = 1;
+    as.fmt        = AUD_FMT_S16;
+    as.endianness = AUDIO_HOST_ENDIANNESS;
+
+    ta->voice = AUD_open_out(
+        &ta->card,
+        ta->voice,
+        "test_audio",
+        ta,
+        testAudio_audio_callback,
+        &as);
+
+    if (!ta->voice) {
+        dprint("Cannot open test audio!");
+        return -1;
+    }
+    ta->pos = 0;
+
+    /* Initialize samples */
+    int nn;
+    for (nn = 0; nn < SAMPLE_SIZE; nn++) {
+        ta->sample[nn] = (short)(((nn % (SAMPLE_SIZE/4))*65536/(SAMPLE_SIZE/4)) & 0xffff);
+    }
+
+    AUD_set_active_out(ta->voice, 1);
+    return 0;
+}
+
+static TestAudio*  testAudio;
+
+int
+android_audio_test_start_out(void)
+{
+    if (!testAudio) {
+        testAudio = malloc(sizeof(*testAudio));
+        if (testAudio_init(testAudio) < 0) {
+            free(testAudio);
+            testAudio = NULL;
+            fprintf(stderr, "Could not start audio test!\n");
+            return -1;
+        } else {
+            printf("Audio test started!\n");
+        }
+    }
+    return 0;
+}
diff --git a/android/audio-test.h b/android/audio-test.h
new file mode 100644
index 0000000..8113aae
--- /dev/null
+++ b/android/audio-test.h
@@ -0,0 +1,22 @@
+/* Copyright (C) 2010 The Android Open Source Project
+**
+** This software is licensed under the terms of the GNU General Public
+** License version 2, as published by the Free Software Foundation, and
+** may be copied, distributed, and modified under those terms.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU General Public License for more details.
+*/
+#ifndef ANDROID_AUDIO_TEST_H
+#define ANDROID_AUDIO_TEST_H
+
+/* Start the audio test output, this will register a virtual sound
+ * device that sends a saw signal to the audio sub-system. This is
+ * used to test that the audio backend works without having to boot
+ * a full system and launch a music application.
+ */
+extern int android_audio_test_start_out(void);
+
+#endif /* ANDROID_AUDIO_TEST_H */
diff --git a/hw/goldfish_audio.c b/hw/goldfish_audio.c
index 37e4c09..434522c 100644
--- a/hw/goldfish_audio.c
+++ b/hw/goldfish_audio.c
@@ -582,7 +582,7 @@
     if (android_hw->hw_audioOutput) {
         s->voice = AUD_open_out (
             &s->card,
-            s->voice,
+            NULL,
             "goldfish_audio",
             s,
             goldfish_audio_callback,
diff --git a/qemu-options.hx b/qemu-options.hx
index bd5934b..db3dfbb 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -1598,7 +1598,7 @@
 
 #endif /* CONFIG_TRACE */
 
-#if 1 /* ANDROID */
+#ifdef CONFIG_ANDROID
 
 DEF("savevm-on-exit", HAS_ARG, QEMU_OPTION_savevm_on_exit, \
     "savevm-on-exit [tag|id]\n" \
@@ -1688,4 +1688,7 @@
 DEF("ui-settings", HAS_ARG, QEMU_OPTION_ui_settings, \
     "-ui-settings <string> opaque string containing persitent UI settings\n")
 
-#endif
+DEF("audio-test-out", 0, QEMU_OPTION_audio_test_out, \
+   "-audio-test-out Test audio output\n")
+
+#endif /* ANDROID */
diff --git a/vl-android.c b/vl-android.c
index 57be79c..3fb50ea 100644
--- a/vl-android.c
+++ b/vl-android.c
@@ -191,6 +191,7 @@
 #include "android/hw-lcd.h"
 #include "android/boot-properties.h"
 #include "android/core-init-utils.h"
+#include "android/audio-test.h"
 
 #ifdef CONFIG_STANDALONE_CORE
 /* Verbose value used by the standalone emulator core (without UI) */
@@ -4641,6 +4642,10 @@
                 android_op_ui_settings = (char*)optarg;
                 break;
 
+            case QEMU_OPTION_audio_test_out:
+                android_audio_test_start_out();
+                break;
+
 #ifdef CONFIG_MEMCHECK
             case QEMU_OPTION_android_memcheck:
                 android_op_memcheck = (char*)optarg;