xref: /qemu/audio/audio_win_int.c (revision 138ca49a)
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