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 <mmsystem.h>
9 
10 #include "audio.h"
11 #include "audio_int.h"
12 #include "audio_win_int.h"
13 
waveformat_from_audio_settings(WAVEFORMATEX * wfx,struct audsettings * as)14 int waveformat_from_audio_settings (WAVEFORMATEX *wfx,
15                                     struct audsettings *as)
16 {
17     memset (wfx, 0, sizeof (*wfx));
18 
19     wfx->wFormatTag = WAVE_FORMAT_PCM;
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->wBitsPerSample = 8;
30         break;
31 
32     case AUDIO_FORMAT_S16:
33     case AUDIO_FORMAT_U16:
34         wfx->wBitsPerSample = 16;
35         wfx->nAvgBytesPerSec <<= 1;
36         wfx->nBlockAlign <<= 1;
37         break;
38 
39     case AUDIO_FORMAT_S32:
40     case AUDIO_FORMAT_U32:
41         wfx->wBitsPerSample = 32;
42         wfx->nAvgBytesPerSec <<= 2;
43         wfx->nBlockAlign <<= 2;
44         break;
45 
46     default:
47         dolog ("Internal logic error: Bad audio format %d\n", as->freq);
48         return -1;
49     }
50 
51     return 0;
52 }
53 
waveformat_to_audio_settings(WAVEFORMATEX * wfx,struct audsettings * as)54 int waveformat_to_audio_settings (WAVEFORMATEX *wfx,
55                                   struct audsettings *as)
56 {
57     if (wfx->wFormatTag != WAVE_FORMAT_PCM) {
58         dolog ("Invalid wave format, tag is not PCM, but %d\n",
59                wfx->wFormatTag);
60         return -1;
61     }
62 
63     if (!wfx->nSamplesPerSec) {
64         dolog ("Invalid wave format, frequency is zero\n");
65         return -1;
66     }
67     as->freq = wfx->nSamplesPerSec;
68 
69     switch (wfx->nChannels) {
70     case 1:
71         as->nchannels = 1;
72         break;
73 
74     case 2:
75         as->nchannels = 2;
76         break;
77 
78     default:
79         dolog (
80             "Invalid wave format, number of channels is not 1 or 2, but %d\n",
81             wfx->nChannels
82             );
83         return -1;
84     }
85 
86     switch (wfx->wBitsPerSample) {
87     case 8:
88         as->fmt = AUDIO_FORMAT_U8;
89         break;
90 
91     case 16:
92         as->fmt = AUDIO_FORMAT_S16;
93         break;
94 
95     case 32:
96         as->fmt = AUDIO_FORMAT_S32;
97         break;
98 
99     default:
100         dolog ("Invalid wave format, bits per sample is not "
101                "8, 16 or 32, but %d\n",
102                wfx->wBitsPerSample);
103         return -1;
104     }
105 
106     return 0;
107 }
108 
109