Fixed Win32 audio.
Some checks failed
Build & Release / Linux-AMD64-Build (push) Failing after 8s
Build & Release / Linux-AARCH64-Build (push) Failing after 14s
Build & Release / Windows-AMD64-Build (push) Failing after 5m56s

This commit is contained in:
Arron David Nelson 2024-10-01 18:58:15 -07:00
parent dfa260b87c
commit 1f5299ad1b
2 changed files with 109 additions and 78 deletions

View File

@ -37,11 +37,9 @@ namespace ehs
void CloseStream() override; void CloseStream() override;
UInt_64 GetAvailFrames() const override; UInt_64 SendStream(const void *data, UInt_64 outFrameSize) override;
Byte* Map(UInt_64* offset, UInt_64* frames) override; UInt_64 ReceiveStream(void *data, UInt_64 inFrameSize) override;
void UnMap(const UInt_64 offset, const UInt_64 frames) override;
Str_32 GetInterfaceName_32() const; Str_32 GetInterfaceName_32() const;
@ -59,8 +57,8 @@ namespace ehs
bool IsValid() const override; bool IsValid() const override;
static AudioDevice GetDefault(const AudioDeviceType type); static AudioDevice GetDefault(AudioDeviceType type);
static Array<AudioDevice> Get(const AudioDeviceType type, const AudioDeviceState state); static Array<AudioDevice> Get(AudioDeviceType type, AudioDeviceState state);
}; };
} }

View File

@ -70,7 +70,7 @@ namespace ehs
void AudioDevice::OpenStream() void AudioDevice::OpenStream()
{ {
if (streaming) if (IsStreaming())
return; return;
HRESULT r = hdl->Activate(__uuidof(IAudioClient), CLSCTX_ALL, nullptr, (void**)&client); HRESULT r = hdl->Activate(__uuidof(IAudioClient), CLSCTX_ALL, nullptr, (void**)&client);
@ -80,14 +80,14 @@ namespace ehs
WAVEFORMATEXTENSIBLE* format; WAVEFORMATEXTENSIBLE* format;
client->GetMixFormat((WAVEFORMATEX**)&format); client->GetMixFormat((WAVEFORMATEX**)&format);
if (bitDepth) if (byteDepth)
{ {
if (dataType == DataType::FLOAT) if (dataType == DataType::FLOAT)
format->SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT; format->SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT;
else else
format->SubFormat = KSDATAFORMAT_SUBTYPE_PCM; format->SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
format->Format.wBitsPerSample = bitDepth; format->Format.wBitsPerSample = byteDepth * 8;
} }
else else
{ {
@ -96,7 +96,7 @@ namespace ehs
else else
dataType = FromAudioBitDepth(format->Format.wBitsPerSample); dataType = FromAudioBitDepth(format->Format.wBitsPerSample);
bitDepth = format->Format.wBitsPerSample; byteDepth = format->Format.wBitsPerSample / 8;
} }
if (sampleRate) if (sampleRate)
@ -109,7 +109,7 @@ namespace ehs
else else
channels = format->Format.nChannels; channels = format->Format.nChannels;
format->Format.nBlockAlign = bitDepth / 8 * channels; format->Format.nBlockAlign = byteDepth * channels;
format->Format.nAvgBytesPerSec = format->Format.nBlockAlign * sampleRate; format->Format.nAvgBytesPerSec = format->Format.nBlockAlign * sampleRate;
WAVEFORMATEX* match = {}; WAVEFORMATEX* match = {};
@ -265,7 +265,7 @@ namespace ehs
return; return;
} }
streaming = true; EHS_LOG_SUCCESS();
} }
void AudioDevice::CloseStream() void AudioDevice::CloseStream()
@ -300,95 +300,128 @@ namespace ehs
hdl->Release(); hdl->Release();
hdl = nullptr; hdl = nullptr;
} }
EHS_LOG_SUCCESS();
} }
UInt_64 AudioDevice::GetAvailFrames() const UInt_64 AudioDevice::SendStream(const void *data, UInt_64 outFrameSize)
{ {
if (!IsValid() || !IsStreaming()) if (!IsValid() || !IsStreaming() || !playbackClient || !data || !outFrameSize)
return 0; return 0;
UInt_32 sampleSize = 0; UInt_32 frameOffset = 0;
if (playbackClient) HRESULT r = client->GetCurrentPadding(&frameOffset);
if (r == AUDCLNT_E_DEVICE_INVALIDATED)
{ {
HRESULT r = client->GetCurrentPadding(&sampleSize); EHS_LOG_INT(LogType::WARN, 0, "The audio device has been invalidated.");
if (r == AUDCLNT_E_DEVICE_INVALIDATED) return 0;
EHS_LOG_INT(LogType::ERR, 0, "The audio device has been invalidated.");
else if (FAILED(r))
EHS_LOG_INT(LogType::ERR, 1, "Failed to retrieve samples padding with error #" + Str_8::FromNum(r) + ".");
sampleSize = maxFrames - sampleSize;
} }
else if (captureClient) else if (FAILED(r))
{ {
HRESULT r = captureClient->GetNextPacketSize(&sampleSize); EHS_LOG_INT(LogType::ERR, 1, "Failed to retrieve samples padding with error #" + Str_8::FromNum(r) + ".");
if (r == AUDCLNT_E_DEVICE_INVALIDATED) return 0;
EHS_LOG_INT(LogType::ERR, 0, "The audio device has been invalidated.");
else if (FAILED(r))
EHS_LOG_INT(LogType::ERR, 1, "Failed to retrieve samples size with error #" + Str_8::FromNum(r) + ".");
} }
return sampleSize; UInt_32 frameSize = maxFrames - frameOffset;
if (frameSize > outFrameSize)
frameSize = outFrameSize;
Byte *buffer = nullptr;
r = playbackClient->GetBuffer(frameSize, &buffer);
if (r == AUDCLNT_E_DEVICE_INVALIDATED)
{
EHS_LOG_INT(LogType::WARN, 2, "The audio device has been invalidated.");
return 0;
}
else if (FAILED(r))
{
EHS_LOG_INT(LogType::ERR, 3, "Failed to retrieve buffer with error #" + Str_8::FromNum(r) + ".");
return 0;
}
r = playbackClient->ReleaseBuffer(frameSize, 0);
if (r == AUDCLNT_E_DEVICE_INVALIDATED)
{
EHS_LOG_INT(LogType::WARN, 4, "The audio device has been invalidated.");
return 0;
}
else if (FAILED(r))
{
EHS_LOG_INT(LogType::ERR, 5, "Failed to release buffer with error #" + Str_8::FromNum(r) + ".");
return 0;
}
return frameSize;
} }
Byte* AudioDevice::Map(UInt_64* offset, UInt_64* frames) UInt_64 AudioDevice::ReceiveStream(void *data, UInt_64 inFrameSize)
{ {
if (!IsValid() || !IsStreaming() || !captureClient || !data || !inFrameSize)
return 0;
UInt_32 frameSize = 0;
HRESULT r = captureClient->GetNextPacketSize(&frameSize);
if (r == AUDCLNT_E_DEVICE_INVALIDATED)
{
EHS_LOG_INT(LogType::WARN, 0, "The audio device has been invalidated.");
return 0;
}
else if (FAILED(r))
{
EHS_LOG_INT(LogType::ERR, 1, "Failed to retrieve samples size with error #" + Str_8::FromNum(r) + ".");
return 0;
}
if (frameSize > inFrameSize)
frameSize = inFrameSize;
UInt_64 frameOffset = 0;
r = client->GetCurrentPadding((UINT32*)&frameOffset);
if (r == AUDCLNT_E_DEVICE_INVALIDATED)
{
EHS_LOG_INT(LogType::WARN, 2, "The audio device has been invalidated.");
return 0;
}
else if (FAILED(r))
{
EHS_LOG_INT(LogType::ERR, 3, "Failed to retrieve samples padding with error #" + Str_8::FromNum(r) + ".");
return 0;
}
UInt_32 flags = 0;
Byte* buffer = nullptr; Byte* buffer = nullptr;
if (!IsValid()) r = captureClient->GetBuffer(&buffer, (UINT32*)&frameSize, (DWORD*)&flags, nullptr, nullptr);
return buffer;
HRESULT r = client->GetCurrentPadding((UINT32*)&offset);
if (r == AUDCLNT_E_DEVICE_INVALIDATED) if (r == AUDCLNT_E_DEVICE_INVALIDATED)
EHS_LOG_INT(LogType::ERR, 0, "The audio device has been invalidated."); {
EHS_LOG_INT(LogType::WARN, 4, "The audio device has been invalidated.");
return 0;
}
else if (FAILED(r)) else if (FAILED(r))
EHS_LOG_INT(LogType::ERR, 1, "Failed to retrieve samples padding with error #" + Str_8::FromNum(r) + ".");
if (playbackClient)
{ {
r = playbackClient->GetBuffer(*frames, &buffer); EHS_LOG_INT(LogType::ERR, 5, "Failed to retrieve buffer with error #" + Str_8::FromNum(r) + ".");
if (r == AUDCLNT_E_BUFFER_TOO_LARGE) return 0;
EHS_LOG_INT(LogType::ERR, 0, "The given frame size, " + Str_8::FromNum(*frames) + ", must be less than or equal to, " + Str_8::FromNum(maxFrames - *offset) + ".");
else if (r == AUDCLNT_E_DEVICE_INVALIDATED)
EHS_LOG_INT(LogType::ERR, 1, "The audio device has been invalidated.");
else if (FAILED(r))
EHS_LOG_INT(LogType::ERR, 2, "Failed to retrieve buffer with error #" + Str_8::FromNum(r) + ".");
}
else if (captureClient)
{
UInt_32 flags = 0;
r = captureClient->GetBuffer(&buffer, (UINT32*)frames, (DWORD*)&flags, nullptr, nullptr);
if (r == AUDCLNT_E_DEVICE_INVALIDATED)
EHS_LOG_INT(LogType::ERR, 1, "The audio device has been invalidated.");
else if (FAILED(r))
EHS_LOG_INT(LogType::ERR, 2, "Failed to retrieve buffer with error #" + Str_8::FromNum(r) + ".");
} }
return buffer; Util::Copy(data, &buffer[frameOffset], frameSize * byteDepth * channels);
}
void AudioDevice::UnMap(const UInt_64 offset, const UInt_64 frames) r = captureClient->ReleaseBuffer(frameSize);
{ if (r == AUDCLNT_E_DEVICE_INVALIDATED)
if (!IsValid() || !streaming) {
return; EHS_LOG_INT(LogType::WARN, 6, "The audio device has been invalidated.");
return 0;
}
else if (FAILED(r))
{
EHS_LOG_INT(LogType::ERR, 7, "Failed to release buffer with error #" + Str_8::FromNum(r) + ".");
return 0;
}
if (playbackClient) EHS_LOG_SUCCESS();
{
HRESULT r = playbackClient->ReleaseBuffer(frames, 0); return frameSize;
if (r == AUDCLNT_E_DEVICE_INVALIDATED)
EHS_LOG_INT(LogType::ERR, 0, "The audio device has been invalidated.");
else if (FAILED(r))
EHS_LOG_INT(LogType::ERR, 1, "Failed to release buffer with error #" + Str_8::FromNum(r) + ".");
}
else if (captureClient)
{
HRESULT r = captureClient->ReleaseBuffer(frames);
if (r == AUDCLNT_E_DEVICE_INVALIDATED)
EHS_LOG_INT(LogType::ERR, 0, "The audio device has been invalidated.");
else if (FAILED(r))
EHS_LOG_INT(LogType::ERR, 1, "Failed to release buffer with error #" + Str_8::FromNum(r) + ".");
}
} }
Str_32 AudioDevice::GetInterfaceName_32() const Str_32 AudioDevice::GetInterfaceName_32() const