1d5631638Smalc /* public domain */
2d5631638Smalc
36086a565SPeter Maydell #include "qemu/osdep.h"
4d5631638Smalc
5d5631638Smalc #define AUDIO_CAP "win-int"
6d5631638Smalc #include <windows.h>
711575061SVolker Rümelin #include <mmreg.h>
8d5631638Smalc #include <mmsystem.h>
9d5631638Smalc
10d5631638Smalc #include "audio.h"
11d5631638Smalc #include "audio_int.h"
12d5631638Smalc #include "audio_win_int.h"
13d5631638Smalc
waveformat_from_audio_settings(WAVEFORMATEX * wfx,struct audsettings * as)14d5631638Smalc int waveformat_from_audio_settings (WAVEFORMATEX *wfx,
15d5631638Smalc struct audsettings *as)
16d5631638Smalc {
17d5631638Smalc memset (wfx, 0, sizeof (*wfx));
18d5631638Smalc
19d5631638Smalc wfx->nChannels = as->nchannels;
20d5631638Smalc wfx->nSamplesPerSec = as->freq;
21d5631638Smalc wfx->nAvgBytesPerSec = as->freq << (as->nchannels == 2);
22d5631638Smalc wfx->nBlockAlign = 1 << (as->nchannels == 2);
23d5631638Smalc wfx->cbSize = 0;
24d5631638Smalc
25d5631638Smalc switch (as->fmt) {
2685bc5852SKővágó, Zoltán case AUDIO_FORMAT_S8:
2785bc5852SKővágó, Zoltán case AUDIO_FORMAT_U8:
2811575061SVolker Rümelin wfx->wFormatTag = WAVE_FORMAT_PCM;
29d5631638Smalc wfx->wBitsPerSample = 8;
30d5631638Smalc break;
31d5631638Smalc
3285bc5852SKővágó, Zoltán case AUDIO_FORMAT_S16:
3385bc5852SKővágó, Zoltán case AUDIO_FORMAT_U16:
3411575061SVolker Rümelin wfx->wFormatTag = WAVE_FORMAT_PCM;
35d5631638Smalc wfx->wBitsPerSample = 16;
36d5631638Smalc wfx->nAvgBytesPerSec <<= 1;
37d5631638Smalc wfx->nBlockAlign <<= 1;
38d5631638Smalc break;
39d5631638Smalc
4085bc5852SKővágó, Zoltán case AUDIO_FORMAT_S32:
4185bc5852SKővágó, Zoltán case AUDIO_FORMAT_U32:
4211575061SVolker Rümelin wfx->wFormatTag = WAVE_FORMAT_PCM;
4311575061SVolker Rümelin wfx->wBitsPerSample = 32;
4411575061SVolker Rümelin wfx->nAvgBytesPerSec <<= 2;
4511575061SVolker Rümelin wfx->nBlockAlign <<= 2;
4611575061SVolker Rümelin break;
4711575061SVolker Rümelin
4811575061SVolker Rümelin case AUDIO_FORMAT_F32:
4911575061SVolker Rümelin wfx->wFormatTag = WAVE_FORMAT_IEEE_FLOAT;
50d5631638Smalc wfx->wBitsPerSample = 32;
51d5631638Smalc wfx->nAvgBytesPerSec <<= 2;
52d5631638Smalc wfx->nBlockAlign <<= 2;
53d5631638Smalc break;
54d5631638Smalc
55d5631638Smalc default:
56*2d96a005SVolker Rümelin dolog("Internal logic error: Bad audio format %d\n", as->fmt);
57d5631638Smalc return -1;
58d5631638Smalc }
59d5631638Smalc
60d5631638Smalc return 0;
61d5631638Smalc }
62d5631638Smalc
waveformat_to_audio_settings(WAVEFORMATEX * wfx,struct audsettings * as)63d5631638Smalc int waveformat_to_audio_settings (WAVEFORMATEX *wfx,
64d5631638Smalc struct audsettings *as)
65d5631638Smalc {
66d5631638Smalc if (!wfx->nSamplesPerSec) {
67d5631638Smalc dolog ("Invalid wave format, frequency is zero\n");
68d5631638Smalc return -1;
69d5631638Smalc }
70d5631638Smalc as->freq = wfx->nSamplesPerSec;
71d5631638Smalc
72d5631638Smalc switch (wfx->nChannels) {
73d5631638Smalc case 1:
74d5631638Smalc as->nchannels = 1;
75d5631638Smalc break;
76d5631638Smalc
77d5631638Smalc case 2:
78d5631638Smalc as->nchannels = 2;
79d5631638Smalc break;
80d5631638Smalc
81d5631638Smalc default:
82d5631638Smalc dolog (
83d5631638Smalc "Invalid wave format, number of channels is not 1 or 2, but %d\n",
84d5631638Smalc wfx->nChannels
85d5631638Smalc );
86d5631638Smalc return -1;
87d5631638Smalc }
88d5631638Smalc
8911575061SVolker Rümelin if (wfx->wFormatTag == WAVE_FORMAT_PCM) {
90d5631638Smalc switch (wfx->wBitsPerSample) {
91d5631638Smalc case 8:
9285bc5852SKővágó, Zoltán as->fmt = AUDIO_FORMAT_U8;
93d5631638Smalc break;
94d5631638Smalc
95d5631638Smalc case 16:
9685bc5852SKővágó, Zoltán as->fmt = AUDIO_FORMAT_S16;
97d5631638Smalc break;
98d5631638Smalc
99d5631638Smalc case 32:
10085bc5852SKővágó, Zoltán as->fmt = AUDIO_FORMAT_S32;
101d5631638Smalc break;
102d5631638Smalc
103d5631638Smalc default:
10411575061SVolker Rümelin dolog("Invalid PCM wave format, bits per sample is not "
105d5631638Smalc "8, 16 or 32, but %d\n",
106d5631638Smalc wfx->wBitsPerSample);
107d5631638Smalc return -1;
108d5631638Smalc }
10911575061SVolker Rümelin } else if (wfx->wFormatTag == WAVE_FORMAT_IEEE_FLOAT) {
11011575061SVolker Rümelin switch (wfx->wBitsPerSample) {
11111575061SVolker Rümelin case 32:
11211575061SVolker Rümelin as->fmt = AUDIO_FORMAT_F32;
11311575061SVolker Rümelin break;
11411575061SVolker Rümelin
11511575061SVolker Rümelin default:
11611575061SVolker Rümelin dolog("Invalid IEEE_FLOAT wave format, bits per sample is not "
11711575061SVolker Rümelin "32, but %d\n",
11811575061SVolker Rümelin wfx->wBitsPerSample);
11911575061SVolker Rümelin return -1;
12011575061SVolker Rümelin }
12111575061SVolker Rümelin } else {
12211575061SVolker Rümelin dolog("Invalid wave format, tag is not PCM and not IEEE_FLOAT, "
12311575061SVolker Rümelin "but %d\n",
12411575061SVolker Rümelin wfx->wFormatTag);
12511575061SVolker Rümelin return -1;
12611575061SVolker Rümelin }
127d5631638Smalc
128d5631638Smalc return 0;
129d5631638Smalc }
130d5631638Smalc
131