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