18b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*
28b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * QEMU "simple" Windows audio driver
38b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *
48b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Copyright (c) 2007 The Android Open Source Project
58b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *
68b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Permission is hereby granted, free of charge, to any person obtaining a copy
78b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * of this software and associated documentation files (the "Software"), to deal
88b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * in the Software without restriction, including without limitation the rights
98b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * copies of the Software, and to permit persons to whom the Software is
118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * furnished to do so, subject to the following conditions:
128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *
138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * The above copyright notice and this permission notice shall be included in
148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * all copies or substantial portions of the Software.
158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *
168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * THE SOFTWARE.
238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */
248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define WIN32_LEAN_AND_MEAN
258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <windows.h>
268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <mmsystem.h>
278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define AUDIO_CAP "winaudio"
298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "audio_int.h"
308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* define DEBUG to 1 to dump audio debugging info at runtime to stderr */
328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define  DEBUG  0
338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if 1
358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#  define  D_ACTIVE    1
368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#  define  D_ACTIVE  DEBUG
388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if DEBUG
418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#  define  D(...)   do{ if (D_ACTIVE) printf(__VA_ARGS__); } while(0)
428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#  define  D(...)   ((void)0)
448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic struct {
478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int nb_samples;
488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} conf = {
498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    1024
508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project};
518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if DEBUG
538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint64_t  start_time;
548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint64_t  last_time;
558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define  NUM_OUT_BUFFERS  8  /* must be at least 2 */
588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/** COMMON UTILITIES
608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project **/
618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if DEBUG
638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void
648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectdump_mmerror( const char*  func, MMRESULT  error )
658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    const char*  reason = NULL;
678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    fprintf(stderr, "%s returned error: ", func);
698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    switch (error) {
708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            case MMSYSERR_ALLOCATED:   reason="specified resource is already allocated"; break;
718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            case MMSYSERR_BADDEVICEID: reason="bad device id"; break;
728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            case MMSYSERR_NODRIVER:    reason="no driver is present"; break;
738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            case MMSYSERR_NOMEM:       reason="unable to allocate or lock memory"; break;
748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            case WAVERR_BADFORMAT:     reason="unsupported waveform-audio format"; break;
758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            case WAVERR_SYNC:          reason="device is synchronous"; break;
768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            default:
778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    fprintf(stderr, "unknown(%d)\n", error);
788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (reason)
808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            fprintf(stderr, "%s\n", reason);
818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#  define  dump_mmerror(func,error)  ((void)0)
848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/** AUDIO OUT
888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project **/
898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef struct WinAudioOut {
918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    HWVoiceOut        hw;
928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    HWAVEOUT          waveout;
938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int               silence;
948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    CRITICAL_SECTION  lock;
958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned char*    buffer_bytes;
968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    WAVEHDR           buffers[ NUM_OUT_BUFFERS ];
978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int               write_index;   /* starting first writable buffer      */
988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int               write_count;   /* available writable buffers count    */
998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int               write_pos;     /* position in current writable buffer */
1008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int               write_size;    /* size in bytes of each buffer        */
1018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} WinAudioOut;
1028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* The Win32 callback that is called when a buffer has finished playing */
1048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void CALLBACK
1058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectwinaudio_out_buffer_done (HWAVEOUT hwo, UINT uMsg, DWORD_PTR dwInstance,
1068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project			              DWORD dwParam1, DWORD dwParam2)
1078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    WinAudioOut*  s = (WinAudioOut*) dwInstance;
1098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* Only service "buffer done playing" messages */
1118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( uMsg != WOM_DONE )
1128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return;
1138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* Signal that we are done playing a buffer */
1158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    EnterCriticalSection( &s->lock );
1168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (s->write_count < NUM_OUT_BUFFERS)
1178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        s->write_count += 1;
1188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    LeaveCriticalSection( &s->lock );
1198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
1228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectwinaudio_out_write (SWVoiceOut *sw, void *buf, int len)
1238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return audio_pcm_sw_write (sw, buf, len);
1258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void
1288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectwinaudio_out_fini (HWVoiceOut *hw)
1298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    WinAudioOut*  s = (WinAudioOut*) hw;
1318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int           i;
1328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (s->waveout) {
1348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        waveOutReset(s->waveout);
1358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        s->waveout = 0;
1368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
1378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for ( i=0; i<NUM_OUT_BUFFERS; ++i ) {
1398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( s->buffers[i].dwUser != 0xFFFF ) {
1408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            waveOutUnprepareHeader(
1418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                s->waveout, &s->buffers[i], sizeof(s->buffers[i]) );
1428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                s->buffers[i].dwUser = 0xFFFF;
1438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
1448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
1458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (s->buffer_bytes != NULL) {
147aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner        g_free(s->buffer_bytes);
1488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        s->buffer_bytes = NULL;
1498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
1508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (s->waveout) {
1528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        waveOutClose(s->waveout);
1538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        s->waveout = NULL;
1548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
1558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
1595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerwinaudio_out_init (HWVoiceOut *hw, struct audsettings *as)
1608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    WinAudioOut*   s = (WinAudioOut*) hw;
1628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    MMRESULT       result;
1638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    WAVEFORMATEX   format;
1648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int            shift, i, samples_size;
1658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->waveout = NULL;
1678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    InitializeCriticalSection( &s->lock );
1688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for (i = 0; i < NUM_OUT_BUFFERS; i++) {
1698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            s->buffers[i].dwUser = 0xFFFF;
1708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
1718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->buffer_bytes = NULL;
1728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* compute desired wave output format */
1748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    format.wFormatTag      = WAVE_FORMAT_PCM;
1758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    format.nChannels       = as->nchannels;
1768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    format.nSamplesPerSec  = as->freq;
1778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    format.nAvgBytesPerSec = as->freq*as->nchannels;
1788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->silence = 0;
1808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    switch (as->fmt) {
1828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case AUD_FMT_S8:   shift = 0; break;
1838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case AUD_FMT_U8:   shift = 0; s->silence = 0x80; break;
1848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case AUD_FMT_S16:  shift = 1; break;
1858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case AUD_FMT_U16:  shift = 1; s->silence = 0x8000; break;
1868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        default:
1878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            fprintf(stderr, "qemu: winaudio: Bad output audio format: %d\n",
1888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    as->fmt);
1898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                return -1;
1908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
1918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    format.nAvgBytesPerSec = (format.nSamplesPerSec & format.nChannels) << shift;
1938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    format.nBlockAlign     = format.nChannels << shift;
1948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    format.wBitsPerSample  = 8 << shift;
1958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    format.cbSize          = 0;
1968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* open the wave out device */
1988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    result = waveOutOpen( &s->waveout, WAVE_MAPPER, &format,
1998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                  (DWORD_PTR)winaudio_out_buffer_done, (DWORD_PTR) hw,
2008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                              CALLBACK_FUNCTION);
2018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( result != MMSYSERR_NOERROR ) {
2028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        dump_mmerror( "qemu: winaudio: waveOutOpen()", result);
2038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return -1;
2048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
2058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    samples_size    = format.nBlockAlign * conf.nb_samples;
207aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner    s->buffer_bytes = g_malloc( NUM_OUT_BUFFERS * samples_size );
2088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (s->buffer_bytes == NULL) {
2098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            waveOutClose( s->waveout );
2108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            s->waveout = NULL;
2118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            fprintf(stderr, "not enough memory for Windows audio buffers\n");
2128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return -1;
2138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
2148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for (i = 0; i < NUM_OUT_BUFFERS; i++) {
2168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        memset( &s->buffers[i], 0, sizeof(s->buffers[i]) );
2178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        s->buffers[i].lpData         = (LPSTR)(s->buffer_bytes + i*samples_size);
2188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        s->buffers[i].dwBufferLength = samples_size;
2198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        s->buffers[i].dwFlags        = WHDR_DONE;
2208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        result = waveOutPrepareHeader( s->waveout, &s->buffers[i],
2228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                               sizeof(s->buffers[i]) );
2238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( result != MMSYSERR_NOERROR ) {
2248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            dump_mmerror("waveOutPrepareHeader()", result);
2258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return -1;
2268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
2278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
2288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if DEBUG
2308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* Check the sound device we retrieved */
2318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    {
2328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        WAVEOUTCAPS caps;
2338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        result = waveOutGetDevCaps((UINT) s->waveout, &caps, sizeof(caps));
2358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( result != MMSYSERR_NOERROR ) {
2368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            dump_mmerror("waveOutGetDevCaps()", result);
2378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else
2388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            printf("Audio out device: %s\n", caps.szPname);
2398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
2408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
2418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    audio_pcm_init_info (&hw->info, as);
2438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    hw->samples = conf.nb_samples*2;
2448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->write_index = 0;
2468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->write_count = NUM_OUT_BUFFERS;
2478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->write_pos   = 0;
2488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->write_size  = samples_size;
2498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
2508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
2545d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turnerwinaudio_out_run (HWVoiceOut *hw, int live)
2558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    WinAudioOut*  s      = (WinAudioOut*) hw;
2578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int           played = 0;
2588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int           has_buffer;
2598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (!live) {
2618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0;
2628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
2638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    EnterCriticalSection( &s->lock );
2658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    has_buffer = (s->write_count > 0);
2668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    LeaveCriticalSection( &s->lock );
2678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (has_buffer) {
2698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        while (live > 0) {
2708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            WAVEHDR*      wav_buffer  = s->buffers + s->write_index;
2718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int           wav_bytes   = (s->write_size - s->write_pos);
2728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int           wav_samples = audio_MIN(wav_bytes >> hw->info.shift, live);
2738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int           hw_samples  = audio_MIN(hw->samples - hw->rpos, live);
2745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            struct st_sample*  src         = hw->mix_buf + hw->rpos;
2758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            uint8_t*      dst         = (uint8_t*)wav_buffer->lpData + s->write_pos;
2768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (wav_samples > hw_samples) {
2788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    wav_samples = hw_samples;
2798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
2808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            wav_bytes = wav_samples << hw->info.shift;
2828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            //D("run_out: buffer:%d pos:%d size:%d wsamples:%d wbytes:%d live:%d rpos:%d hwsamples:%d\n", s->write_index,
2848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            //   s->write_pos, s->write_size, wav_samples, wav_bytes, live, hw->rpos, hw->samples);
2858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            hw->clip (dst, src, wav_samples);
2868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            hw->rpos += wav_samples;
2878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (hw->rpos >= hw->samples)
2888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    hw->rpos -= hw->samples;
2898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            live         -= wav_samples;
2918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            played       += wav_samples;
2928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            s->write_pos += wav_bytes;
2938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (s->write_pos == s->write_size) {
2948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if xxDEBUG
295dcda949f769a11b197f4784fe299a448d87e6e14David 'Digit' Turner                int64_t  now  = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - start_time;
2968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                int64_t  diff = now - last_time;
2978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                D("run_out: (%7.3f:%7d):waveOutWrite buffer:%d\n",
2998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                   now/1e9, (now-last_time)/1e9, s->write_index);
3008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                last_time = now;
3018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
3028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                waveOutWrite( s->waveout, wav_buffer, sizeof(*wav_buffer) );
3038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                s->write_pos    = 0;
3048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                s->write_index += 1;
3058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (s->write_index == NUM_OUT_BUFFERS)
3068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    s->write_index = 0;
3078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                EnterCriticalSection( &s->lock );
3098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (--s->write_count == 0) {
3108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        live = 0;
3118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
3128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                LeaveCriticalSection( &s->lock );
3138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
3148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
3158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
3178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return played;
3188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
3218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectwinaudio_out_ctl (HWVoiceOut *hw, int cmd, ...)
3228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    WinAudioOut*  s = (WinAudioOut*) hw;
3248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    switch (cmd) {
3268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case VOICE_ENABLE:
3278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        waveOutRestart( s->waveout );
3288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
3298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case VOICE_DISABLE:
3318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        waveOutPause( s->waveout );
3328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
3338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
3348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
3358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/** AUDIO IN
3388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project **/
3398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define  NUM_IN_BUFFERS  2
3418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef struct WinAudioIn {
3438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    HWVoiceIn         hw;
3448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    HWAVEIN           wavein;
3458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    CRITICAL_SECTION  lock;
3468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned char*    buffer_bytes;
3478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    WAVEHDR           buffers[ NUM_IN_BUFFERS ];
3488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int               read_index;
3498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int               read_count;
3508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int               read_pos;
3518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int               read_size;
3528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} WinAudioIn;
3538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* The Win32 callback that is called when a buffer has finished playing */
3558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void CALLBACK
3568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectwinaudio_in_buffer_done (HWAVEIN hwi, UINT uMsg, DWORD_PTR dwInstance,
3578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                         DWORD dwParam1, DWORD dwParam2)
3588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    WinAudioIn*  s = (WinAudioIn*) dwInstance;
3608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* Only service "buffer done playing" messages */
3628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( uMsg != WIM_DATA )
3638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return;
3648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* Signal that we are done playing a buffer */
3668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    EnterCriticalSection( &s->lock );
3678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (s->read_count < NUM_IN_BUFFERS)
3688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        s->read_count += 1;
3698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        //D(".%c",s->read_count + '0'); fflush(stdout);
3708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    LeaveCriticalSection( &s->lock );
3718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void
3748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectwinaudio_in_fini (HWVoiceIn *hw)
3758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    WinAudioIn*  s = (WinAudioIn*) hw;
3778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int           i;
3788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (s->wavein) {
3808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        waveInReset(s->wavein);
3818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            s->wavein = 0;
3828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
3838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
384aef4c4e21a71298668e28659008381a62b8545cdVladimir Chtchetkine    for ( i=0; i<NUM_IN_BUFFERS; ++i ) {
3858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( s->buffers[i].dwUser != 0xFFFF ) {
3868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            waveInUnprepareHeader(
3878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                s->wavein, &s->buffers[i], sizeof(s->buffers[i]) );
3888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                s->buffers[i].dwUser = 0xFFFF;
3898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
3908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
3918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (s->buffer_bytes != NULL) {
393aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner        g_free(s->buffer_bytes);
3948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        s->buffer_bytes = NULL;
3958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
3968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (s->wavein) {
3988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        waveInClose(s->wavein);
3998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        s->wavein = NULL;
4008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
4018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
4028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
4055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerwinaudio_in_init (HWVoiceIn *hw, struct audsettings *as)
4068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
4078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    WinAudioIn*   s = (WinAudioIn*) hw;
4088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    MMRESULT       result;
4098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    WAVEFORMATEX   format;
4108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int            shift, i, samples_size;
4118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->wavein = NULL;
4138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    InitializeCriticalSection( &s->lock );
414aef4c4e21a71298668e28659008381a62b8545cdVladimir Chtchetkine    for (i = 0; i < NUM_IN_BUFFERS; i++) {
4158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            s->buffers[i].dwUser = 0xFFFF;
4168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
4178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->buffer_bytes = NULL;
4188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* compute desired wave input format */
4208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    format.wFormatTag      = WAVE_FORMAT_PCM;
4218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    format.nChannels       = as->nchannels;
4228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    format.nSamplesPerSec  = as->freq;
4238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    format.nAvgBytesPerSec = as->freq*as->nchannels;
4248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    switch (as->fmt) {
4268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case AUD_FMT_S8:   shift = 0; break;
4278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case AUD_FMT_U8:   shift = 0; break;
4288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case AUD_FMT_S16:  shift = 1; break;
4298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case AUD_FMT_U16:  shift = 1; break;
4308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        default:
4318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            fprintf(stderr, "qemu: winaudio: Bad input audio format: %d\n",
4328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    as->fmt);
4338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                return -1;
4348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
4358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    format.nAvgBytesPerSec = (format.nSamplesPerSec * format.nChannels) << shift;
4378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    format.nBlockAlign     = format.nChannels << shift;
4388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    format.wBitsPerSample  = 8 << shift;
4398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    format.cbSize          = 0;
4408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* open the wave in device */
4428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    result = waveInOpen( &s->wavein, WAVE_MAPPER, &format,
4438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                         (DWORD_PTR)winaudio_in_buffer_done, (DWORD_PTR) hw,
4448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                         CALLBACK_FUNCTION);
4458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( result != MMSYSERR_NOERROR ) {
4468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        dump_mmerror( "qemu: winaudio: waveInOpen()", result);
4478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return -1;
4488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
4498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    samples_size    = format.nBlockAlign * conf.nb_samples;
451aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner    s->buffer_bytes = g_malloc( NUM_IN_BUFFERS * samples_size );
4528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (s->buffer_bytes == NULL) {
4538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            waveInClose( s->wavein );
4548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            s->wavein = NULL;
4558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            fprintf(stderr, "not enough memory for Windows audio buffers\n");
4568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return -1;
4578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
4588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for (i = 0; i < NUM_IN_BUFFERS; i++) {
4608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        memset( &s->buffers[i], 0, sizeof(s->buffers[i]) );
4618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        s->buffers[i].lpData         = (LPSTR)(s->buffer_bytes + i*samples_size);
4628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        s->buffers[i].dwBufferLength = samples_size;
4638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        s->buffers[i].dwFlags        = WHDR_DONE;
4648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        result = waveInPrepareHeader( s->wavein, &s->buffers[i],
4668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                               sizeof(s->buffers[i]) );
4678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( result != MMSYSERR_NOERROR ) {
4688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                dump_mmerror("waveInPrepareHeader()", result);
4698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                return -1;
4708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
4718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        result = waveInAddBuffer( s->wavein, &s->buffers[i],
4738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                              sizeof(s->buffers[i]) );
4748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( result != MMSYSERR_NOERROR ) {
4758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            dump_mmerror("waveInAddBuffer()", result);
4768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return -1;
4778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
4788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
4798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if DEBUG
4818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* Check the sound device we retrieved */
4828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    {
4838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        WAVEINCAPS caps;
4848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        result = waveInGetDevCaps((UINT) s->wavein, &caps, sizeof(caps));
4868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( result != MMSYSERR_NOERROR ) {
4878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            dump_mmerror("waveInGetDevCaps()", result);
4888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else
4898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            printf("Audio in device: %s\n", caps.szPname);
4908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
4918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
4928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    audio_pcm_init_info (&hw->info, as);
4948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    hw->samples = conf.nb_samples*2;
4958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->read_index = 0;
4978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->read_count = 0;
4988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->read_pos   = 0;
4998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->read_size  = samples_size;
5008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
5018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
5028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* report the number of captured samples to the audio subsystem */
5058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
5068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectwinaudio_in_run (HWVoiceIn *hw)
5078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
5088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    WinAudioIn*  s        = (WinAudioIn*) hw;
5098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int          captured = 0;
5108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int          has_buffer;
5118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int          live = hw->samples - hw->total_samples_captured;
5128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (!live) {
5148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if 0
5158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        static int  counter;
5168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (++counter == 100) {
5178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            D("0"); fflush(stdout);
5188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            counter = 0;
5198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
5208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
5218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return 0;
5228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
5238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    EnterCriticalSection( &s->lock );
5258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    has_buffer = (s->read_count > 0);
5268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    LeaveCriticalSection( &s->lock );
5278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (has_buffer > 0) {
5298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        while (live > 0) {
5308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            WAVEHDR*      wav_buffer  = s->buffers + s->read_index;
5318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int           wav_bytes   = (s->read_size - s->read_pos);
5328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int           wav_samples = audio_MIN(wav_bytes >> hw->info.shift, live);
5338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int           hw_samples  = audio_MIN(hw->samples - hw->wpos, live);
5345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            struct st_sample*  dst    = hw->conv_buf + hw->wpos;
5358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            uint8_t*      src         = (uint8_t*)wav_buffer->lpData + s->read_pos;
5368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (wav_samples > hw_samples) {
5388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                wav_samples = hw_samples;
5398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
5408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            wav_bytes = wav_samples << hw->info.shift;
5428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            D("%s: buffer:%d pos:%d size:%d wsamples:%d wbytes:%d live:%d wpos:%d hwsamples:%d\n",
5448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               __FUNCTION__, s->read_index, s->read_pos, s->read_size, wav_samples, wav_bytes, live,
5458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               hw->wpos, hw->samples);
5468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            hw->conv(dst, src, wav_samples, &nominal_volume);
5488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            hw->wpos += wav_samples;
5508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (hw->wpos >= hw->samples)
5518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                hw->wpos -= hw->samples;
5528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            live        -= wav_samples;
5548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            captured    += wav_samples;
5558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            s->read_pos += wav_bytes;
5568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (s->read_pos == s->read_size) {
5578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                s->read_pos    = 0;
5588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                s->read_index += 1;
5598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (s->read_index == NUM_IN_BUFFERS)
5608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    s->read_index = 0;
5618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                waveInAddBuffer( s->wavein, wav_buffer, sizeof(*wav_buffer) );
5638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                EnterCriticalSection( &s->lock );
5658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (--s->read_count == 0) {
5668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    live = 0;
5678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
5688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                LeaveCriticalSection( &s->lock );
5698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
5708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
5718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
5728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return  captured;
5738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
5748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
5778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectwinaudio_in_read (SWVoiceIn *sw, void *buf, int len)
5788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
5798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int  ret = audio_pcm_sw_read (sw, buf, len);
5808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (ret > 0)
5818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        D("%s: (%d) returned %d\n", __FUNCTION__, len, ret);
5828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return ret;
5838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
5848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
5878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectwinaudio_in_ctl (HWVoiceIn *hw, int cmd, ...)
5888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
5898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	WinAudioIn*  s = (WinAudioIn*) hw;
5908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    switch (cmd) {
5928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case VOICE_ENABLE:
5938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        D("%s: enable audio in\n", __FUNCTION__);
5948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        waveInStart( s->wavein );
5958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
5968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case VOICE_DISABLE:
5988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        D("%s: disable audio in\n", __FUNCTION__);
5998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        waveInStop( s->wavein );
6008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
6018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
6028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
6038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
6048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/** AUDIO STATE
6068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project **/
6078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef struct WinAudioState {
6098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int  dummy;
6108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} WinAudioState;
6118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic WinAudioState  g_winaudio;
6138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void*
6158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectwinaudio_init(void)
6168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
6178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    WinAudioState*  s = &g_winaudio;
6188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if DEBUG
620dcda949f769a11b197f4784fe299a448d87e6e14David 'Digit' Turner    start_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
6218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    last_time  = 0;
6228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
6238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return s;
6258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
6268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void
6298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectwinaudio_fini (void *opaque)
6308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
6318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
6328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic struct audio_option winaudio_options[] = {
6348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    {"SAMPLES", AUD_OPT_INT, &conf.nb_samples,
6358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     "Size of Windows audio buffer in samples", NULL, 0},
6368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    {NULL, 0, NULL, NULL, NULL, 0}
6378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project};
6388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic struct audio_pcm_ops winaudio_pcm_ops = {
6408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    winaudio_out_init,
6418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    winaudio_out_fini,
6428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    winaudio_out_run,
6438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    winaudio_out_write,
6448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    winaudio_out_ctl,
6458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    winaudio_in_init,
6478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    winaudio_in_fini,
6488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    winaudio_in_run,
6498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    winaudio_in_read,
6508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    winaudio_in_ctl
6518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project};
6528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstruct audio_driver win_audio_driver = {
6548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    INIT_FIELD (name           = ) "winaudio",
6558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    INIT_FIELD (descr          = ) "Windows wave audio",
6568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    INIT_FIELD (options        = ) winaudio_options,
6578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    INIT_FIELD (init           = ) winaudio_init,
6588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    INIT_FIELD (fini           = ) winaudio_fini,
6598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    INIT_FIELD (pcm_ops        = ) &winaudio_pcm_ops,
6608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    INIT_FIELD (can_be_default = ) 1,
6618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    INIT_FIELD (max_voices_out = ) 1,
6628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    INIT_FIELD (max_voices_in  = ) 1,
6638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    INIT_FIELD (voice_size_out = ) sizeof (WinAudioOut),
6648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    INIT_FIELD (voice_size_in  = ) sizeof (WinAudioIn)
6658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project};
666