Merge tag 'pull-la-20220704' of https://gitlab.com/rth7680/qemu into staging
[qemu.git] / audio / audio_win_int.c
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