blob: 5ea8157dfcc8145a2bbbf49c86d8319c4e22386e [file] [log] [blame]
malcd5631632009-10-10 01:13:41 +04001/* public domain */
2
Peter Maydell6086a562016-01-18 17:33:52 +00003#include "qemu/osdep.h"
malcd5631632009-10-10 01:13:41 +04004#include "qemu-common.h"
malcd5631632009-10-10 01:13:41 +04005
6#define AUDIO_CAP "win-int"
7#include <windows.h>
Volker Rümelin11575062021-01-10 11:02:38 +01008#include <mmreg.h>
malcd5631632009-10-10 01:13:41 +04009#include <mmsystem.h>
10
11#include "audio.h"
12#include "audio_int.h"
13#include "audio_win_int.h"
14
15int waveformat_from_audio_settings (WAVEFORMATEX *wfx,
16 struct audsettings *as)
17{
18 memset (wfx, 0, sizeof (*wfx));
19
malcd5631632009-10-10 01:13:41 +040020 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) {
Kővágó, Zoltán85bc5852019-03-08 23:34:13 +010027 case AUDIO_FORMAT_S8:
28 case AUDIO_FORMAT_U8:
Volker Rümelin11575062021-01-10 11:02:38 +010029 wfx->wFormatTag = WAVE_FORMAT_PCM;
malcd5631632009-10-10 01:13:41 +040030 wfx->wBitsPerSample = 8;
31 break;
32
Kővágó, Zoltán85bc5852019-03-08 23:34:13 +010033 case AUDIO_FORMAT_S16:
34 case AUDIO_FORMAT_U16:
Volker Rümelin11575062021-01-10 11:02:38 +010035 wfx->wFormatTag = WAVE_FORMAT_PCM;
malcd5631632009-10-10 01:13:41 +040036 wfx->wBitsPerSample = 16;
37 wfx->nAvgBytesPerSec <<= 1;
38 wfx->nBlockAlign <<= 1;
39 break;
40
Kővágó, Zoltán85bc5852019-03-08 23:34:13 +010041 case AUDIO_FORMAT_S32:
42 case AUDIO_FORMAT_U32:
Volker Rümelin11575062021-01-10 11:02:38 +010043 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;
malcd5631632009-10-10 01:13:41 +040051 wfx->wBitsPerSample = 32;
52 wfx->nAvgBytesPerSec <<= 2;
53 wfx->nBlockAlign <<= 2;
54 break;
55
56 default:
Volker Rümelin2d96a002021-01-10 11:02:39 +010057 dolog("Internal logic error: Bad audio format %d\n", as->fmt);
malcd5631632009-10-10 01:13:41 +040058 return -1;
59 }
60
61 return 0;
62}
63
64int waveformat_to_audio_settings (WAVEFORMATEX *wfx,
65 struct audsettings *as)
66{
malcd5631632009-10-10 01:13:41 +040067 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
Volker Rümelin11575062021-01-10 11:02:38 +010090 if (wfx->wFormatTag == WAVE_FORMAT_PCM) {
91 switch (wfx->wBitsPerSample) {
92 case 8:
93 as->fmt = AUDIO_FORMAT_U8;
94 break;
malcd5631632009-10-10 01:13:41 +040095
Volker Rümelin11575062021-01-10 11:02:38 +010096 case 16:
97 as->fmt = AUDIO_FORMAT_S16;
98 break;
malcd5631632009-10-10 01:13:41 +040099
Volker Rümelin11575062021-01-10 11:02:38 +0100100 case 32:
101 as->fmt = AUDIO_FORMAT_S32;
102 break;
malcd5631632009-10-10 01:13:41 +0400103
Volker Rümelin11575062021-01-10 11:02:38 +0100104 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);
malcd5631632009-10-10 01:13:41 +0400126 return -1;
127 }
128
129 return 0;
130}
131