1 /* public domain */ 2 3 #include "qemu/osdep.h" 4 #include "qemu-common.h" 5 6 #define AUDIO_CAP "win-int" 7 #include <windows.h> 8 #include <mmreg.h> 9 #include <mmsystem.h> 10 11 #include "audio.h" 12 #include "audio_int.h" 13 #include "audio_win_int.h" 14 15 int waveformat_from_audio_settings (WAVEFORMATEX *wfx, 16 struct audsettings *as) 17 { 18 memset (wfx, 0, sizeof (*wfx)); 19 20 wfx->nChannels = as->nchannels; 21 wfx->nSamplesPerSec = as->freq; 22 wfx->nAvgBytesPerSec = as->freq << (as->nchannels == 2); 23 wfx->nBlockAlign = 1 << (as->nchannels == 2); 24 wfx->cbSize = 0; 25 26 switch (as->fmt) { 27 case AUDIO_FORMAT_S8: 28 case AUDIO_FORMAT_U8: 29 wfx->wFormatTag = WAVE_FORMAT_PCM; 30 wfx->wBitsPerSample = 8; 31 break; 32 33 case AUDIO_FORMAT_S16: 34 case AUDIO_FORMAT_U16: 35 wfx->wFormatTag = WAVE_FORMAT_PCM; 36 wfx->wBitsPerSample = 16; 37 wfx->nAvgBytesPerSec <<= 1; 38 wfx->nBlockAlign <<= 1; 39 break; 40 41 case AUDIO_FORMAT_S32: 42 case AUDIO_FORMAT_U32: 43 wfx->wFormatTag = WAVE_FORMAT_PCM; 44 wfx->wBitsPerSample = 32; 45 wfx->nAvgBytesPerSec <<= 2; 46 wfx->nBlockAlign <<= 2; 47 break; 48 49 case AUDIO_FORMAT_F32: 50 wfx->wFormatTag = WAVE_FORMAT_IEEE_FLOAT; 51 wfx->wBitsPerSample = 32; 52 wfx->nAvgBytesPerSec <<= 2; 53 wfx->nBlockAlign <<= 2; 54 break; 55 56 default: 57 dolog("Internal logic error: Bad audio format %d\n", as->fmt); 58 return -1; 59 } 60 61 return 0; 62 } 63 64 int waveformat_to_audio_settings (WAVEFORMATEX *wfx, 65 struct audsettings *as) 66 { 67 if (!wfx->nSamplesPerSec) { 68 dolog ("Invalid wave format, frequency is zero\n"); 69 return -1; 70 } 71 as->freq = wfx->nSamplesPerSec; 72 73 switch (wfx->nChannels) { 74 case 1: 75 as->nchannels = 1; 76 break; 77 78 case 2: 79 as->nchannels = 2; 80 break; 81 82 default: 83 dolog ( 84 "Invalid wave format, number of channels is not 1 or 2, but %d\n", 85 wfx->nChannels 86 ); 87 return -1; 88 } 89 90 if (wfx->wFormatTag == WAVE_FORMAT_PCM) { 91 switch (wfx->wBitsPerSample) { 92 case 8: 93 as->fmt = AUDIO_FORMAT_U8; 94 break; 95 96 case 16: 97 as->fmt = AUDIO_FORMAT_S16; 98 break; 99 100 case 32: 101 as->fmt = AUDIO_FORMAT_S32; 102 break; 103 104 default: 105 dolog("Invalid PCM wave format, bits per sample is not " 106 "8, 16 or 32, but %d\n", 107 wfx->wBitsPerSample); 108 return -1; 109 } 110 } else if (wfx->wFormatTag == WAVE_FORMAT_IEEE_FLOAT) { 111 switch (wfx->wBitsPerSample) { 112 case 32: 113 as->fmt = AUDIO_FORMAT_F32; 114 break; 115 116 default: 117 dolog("Invalid IEEE_FLOAT wave format, bits per sample is not " 118 "32, but %d\n", 119 wfx->wBitsPerSample); 120 return -1; 121 } 122 } else { 123 dolog("Invalid wave format, tag is not PCM and not IEEE_FLOAT, " 124 "but %d\n", 125 wfx->wFormatTag); 126 return -1; 127 } 128 129 return 0; 130 } 131 132