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