master
c 129 lines 3.2 KB
Raw
1 /* public domain */
2
3 #include "qemu/osdep.h"
4
5 #include <windows.h>
6 #include <mmreg.h>
7 #include <mmsystem.h>
8
9 #include "qemu/audio.h"
10 #include "qemu/error-report.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 error_report("dsound: Internal logic error: Bad audio format %d", 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 error_report("dsound: Invalid wave format, frequency is zero");
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 error_report("dsound: Invalid wave format, "
83 "number of channels is not 1 or 2, but %d",
84 wfx->nChannels);
85 return -1;
86 }
87
88 if (wfx->wFormatTag == WAVE_FORMAT_PCM) {
89 switch (wfx->wBitsPerSample) {
90 case 8:
91 as->fmt = AUDIO_FORMAT_U8;
92 break;
93
94 case 16:
95 as->fmt = AUDIO_FORMAT_S16;
96 break;
97
98 case 32:
99 as->fmt = AUDIO_FORMAT_S32;
100 break;
101
102 default:
103 error_report("dsound: Invalid PCM wave format, bits per sample is not "
104 "8, 16 or 32, but %d",
105 wfx->wBitsPerSample);
106 return -1;
107 }
108 } else if (wfx->wFormatTag == WAVE_FORMAT_IEEE_FLOAT) {
109 switch (wfx->wBitsPerSample) {
110 case 32:
111 as->fmt = AUDIO_FORMAT_F32;
112 break;
113
114 default:
115 error_report("dsound: Invalid IEEE_FLOAT wave format, "
116 "bits per sample is not 32, but %d",
117 wfx->wBitsPerSample);
118 return -1;
119 }
120 } else {
121 error_report("dsound: Invalid wave format, "
122 "tag is not PCM and not IEEE_FLOAT, but %d",
123 wfx->wFormatTag);
124 return -1;
125 }
126
127 return 0;
128 }
129