10#define LOC QString("AOWin: ")
12#ifndef WAVE_FORMAT_IEEE_FLOAT
13#define WAVE_FORMAT_IEEE_FLOAT 0x0003
16#ifndef WAVE_FORMAT_DOLBY_AC3_SPDIF
17#define WAVE_FORMAT_DOLBY_AC3_SPDIF 0x0092
20#ifndef WAVE_FORMAT_EXTENSIBLE
21#define WAVE_FORMAT_EXTENSIBLE 0xFFFE
24#ifndef _WAVEFORMATEXTENSIBLE_
41 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
43 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
45 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
54 m_hEvent = CreateEvent(
nullptr, FALSE, TRUE,
nullptr);
81 static void CALLBACK
waveOutProc(HWAVEOUT hwo, UINT uMsg, DWORD dwInstance,
82 DWORD dwParam1, DWORD dwParam2);
97 [[maybe_unused]] DWORD dwParam1,
98 [[maybe_unused]] DWORD dwParam2)
100 if (uMsg != WOM_DONE)
104 InterlockedDecrement(&instance->
m_nPkts);
114 m_UseSPDIF(settings.m_usePassthru)
149 while (DWORD rate = (DWORD)settings->
GetNextRate())
166 for (
uint i = 2; i < 7; i++)
182 LOG(VB_AUDIO, LOG_INFO,
LOC + QString(
"Buffering %1 fragments of %2 bytes each, total: %3 bytes")
199 wf.
SubFormat = _KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF;
204 wf.
SubFormat = _KSDATAFORMAT_SUBTYPE_IEEE_FLOAT;
208 wf.
Format.wFormatTag = WAVE_FORMAT_PCM;
209 wf.
SubFormat = _KSDATAFORMAT_SUBTYPE_PCM;
212 LOG(VB_AUDIO, LOG_INFO,
LOC + QString(
"New format: %1bits %2ch %3Hz %4")
229 (intptr_t)
this, CALLBACK_FUNCTION);
231 if (mmr == WAVERR_BADFORMAT)
233 Error(QString(
"Unable to set audio output parameters %1")
234 .arg(wf.
Format.nSamplesPerSec));
261 if (wh->dwFlags & WHDR_PREPARED)
269 memset(wh, 0,
sizeof(WAVEHDR));
271 wh->dwBufferLength = size;
275 LOG(VB_GENERAL, LOG_ERR,
LOC +
"WriteAudio: failed to prepare header");
278 LOG(VB_GENERAL, LOG_ERR,
LOC +
"WriteAudio: failed to write packet");
290 DWORD dwVolume = 0xffffffff;
292 if (MMSYSERR_NOERROR == waveOutGetVolume((HWAVEOUT)WAVE_MAPPER, &dwVolume))
294 Volume = (channel == 0) ?
295 (LOWORD(dwVolume) / (0xffff / 100)) :
296 (HIWORD(dwVolume) / (0xffff / 100));
299 LOG(VB_AUDIO, LOG_INFO, QString(
"GetVolume(%1) %2 (%3)")
300 .arg(channel).arg(Volume).arg(dwVolume));
308 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Windows volume only supports stereo!");
310 DWORD dwVolume = 0xffffffff;
311 if (MMSYSERR_NOERROR == waveOutGetVolume((HWAVEOUT)WAVE_MAPPER, &dwVolume))
314 dwVolume = (dwVolume & 0xffff0000) | (volume * (0xffff / 100));
316 dwVolume = (dwVolume & 0xffff) | ((volume * (0xffff / 100)) << 16);
320 dwVolume = volume * (0xffff / 100);
321 dwVolume |= (dwVolume << 16);
324 LOG(VB_AUDIO, LOG_INFO,
LOC + QString(
"SetVolume(%1) %2(%3)")
325 .arg(channel).arg(volume).arg(dwVolume));
327 waveOutSetVolume((HWAVEOUT)WAVE_MAPPER, dwVolume);
DEFINE_GUID(_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT, WAVE_FORMAT_IEEE_FLOAT, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71)
#define WAVE_FORMAT_IEEE_FLOAT
#define WAVE_FORMAT_EXTENSIBLE
#define WAVE_FORMAT_DOLBY_AC3_SPDIF
void KillAudio(void)
Kill the output thread and cleanup.
void Reconfigure(const AudioSettings &settings) override
(Re)Configure AudioOutputBase
AudioFormat m_outputFormat
int m_outputBytesPerFrame
long m_soundcardBufferSize
void InitSettings(const AudioSettings &settings)
void AddSupportedRate(int rate)
void setPassthrough(int val)
static int FormatToBits(AudioFormat format)
void AddSupportedChannels(int channels)
void AddSupportedFormat(AudioFormat format)
AudioOutputWinPrivate & operator=(const AudioOutputWinPrivate &)=delete
static void CALLBACK waveOutProc(HWAVEOUT hwo, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
AudioOutputWinPrivate(const AudioOutputWinPrivate &)=delete
void SetVolumeChannel(int channel, int volume) override
int GetBufferedOnSoundcard(void) const override
Return the size in bytes of frames currently in the audio buffer adjusted with the audio playback lat...
AudioOutputWinPrivate * m_priv
static const uint kPacketCnt
bool OpenDevice(void) override
AudioOutputSettings * GetOutputSettings(bool digital) override
virtual ~AudioOutputWin()
int GetVolumeChannel(int channel) const override
unsigned char ** m_OutPkts
void CloseDevice(void) override
AudioOutputWin(const AudioSettings &settings)
void WriteAudio(unsigned char *aubuf, int size) override
void Error(const QString &msg)
bool m_init
If set to false, AudioOutput instance will not try to initially open the audio device.
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
union WAVEFORMATEXTENSIBLE::@2 Samples