Merge remote-tracking branch 'remotes/kraxel/tags/audio-20210115-pull-request' into...
[qemu.git] / audio / audio_win_int.c
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