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