Fixed Win32 audio.
This commit is contained in:
parent
dfa260b87c
commit
1f5299ad1b
@ -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);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
{
|
|
||||||
HRESULT r = client->GetCurrentPadding(&sampleSize);
|
|
||||||
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, 0, "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) + ".");
|
EHS_LOG_INT(LogType::ERR, 1, "Failed to retrieve samples padding with error #" + Str_8::FromNum(r) + ".");
|
||||||
|
return 0;
|
||||||
sampleSize = maxFrames - sampleSize;
|
|
||||||
}
|
|
||||||
else if (captureClient)
|
|
||||||
{
|
|
||||||
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) + ".");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return sampleSize;
|
UInt_32 frameSize = maxFrames - frameOffset;
|
||||||
}
|
if (frameSize > outFrameSize)
|
||||||
|
frameSize = outFrameSize;
|
||||||
|
|
||||||
Byte* AudioDevice::Map(UInt_64* offset, UInt_64* frames)
|
|
||||||
{
|
|
||||||
Byte *buffer = nullptr;
|
Byte *buffer = nullptr;
|
||||||
|
|
||||||
if (!IsValid())
|
r = playbackClient->GetBuffer(frameSize, &buffer);
|
||||||
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.");
|
|
||||||
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::WARN, 2, "The audio device has been invalidated.");
|
||||||
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)
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
UInt_32 flags = 0;
|
||||||
|
Byte* buffer = nullptr;
|
||||||
|
|
||||||
r = captureClient->GetBuffer(&buffer, (UINT32*)frames, (DWORD*)&flags, nullptr, nullptr);
|
r = captureClient->GetBuffer(&buffer, (UINT32*)&frameSize, (DWORD*)&flags, nullptr, nullptr);
|
||||||
if (r == AUDCLNT_E_DEVICE_INVALIDATED)
|
if (r == AUDCLNT_E_DEVICE_INVALIDATED)
|
||||||
EHS_LOG_INT(LogType::ERR, 1, "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, 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)
|
r = captureClient->ReleaseBuffer(frameSize);
|
||||||
{
|
|
||||||
if (!IsValid() || !streaming)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (playbackClient)
|
|
||||||
{
|
|
||||||
HRESULT r = playbackClient->ReleaseBuffer(frames, 0);
|
|
||||||
if (r == AUDCLNT_E_DEVICE_INVALIDATED)
|
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);
|
EHS_LOG_INT(LogType::WARN, 6, "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 release buffer with error #" + Str_8::FromNum(r) + ".");
|
|
||||||
}
|
}
|
||||||
|
else if (FAILED(r))
|
||||||
|
{
|
||||||
|
EHS_LOG_INT(LogType::ERR, 7, "Failed to release buffer with error #" + Str_8::FromNum(r) + ".");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
EHS_LOG_SUCCESS();
|
||||||
|
|
||||||
|
return frameSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
Str_32 AudioDevice::GetInterfaceName_32() const
|
Str_32 AudioDevice::GetInterfaceName_32() const
|
||||||
|
Loading…
Reference in New Issue
Block a user