diff --git a/include/ehs/io/audio/Audio.h b/include/ehs/io/audio/Audio.h index 48c0b7f..22eff2c 100644 --- a/include/ehs/io/audio/Audio.h +++ b/include/ehs/io/audio/Audio.h @@ -81,10 +81,14 @@ namespace ehs UInt_64 GetSampleCount() const; + UInt_8 GetFrameSize() const; + UInt_64 GetSize() const; float GetLength() const; + Byte* GetFrame(UInt_64 frameIndex) const; + Array FrameAsMono(UInt_64 frameIndex) const; Array FrameAsStereo(UInt_64 frameIndex) const; diff --git a/include/ehs/io/audio/BaseAudioDevice.h b/include/ehs/io/audio/BaseAudioDevice.h index a866ac4..0f3ec82 100644 --- a/include/ehs/io/audio/BaseAudioDevice.h +++ b/include/ehs/io/audio/BaseAudioDevice.h @@ -52,7 +52,9 @@ namespace ehs virtual UInt_64 ReceiveStream(void *data, UInt_64 size); - void BridgeStreams(UInt_64 bufferSize); + void BridgeStreams(BaseAudioDevice *input, UInt_64 frameBufferSize); + + void BridgeStreams(UInt_64 frameBufferSize); AudioDeviceType GetType() const; diff --git a/src/io/audio/Audio.cpp b/src/io/audio/Audio.cpp index d9ed4a2..25e9612 100644 --- a/src/io/audio/Audio.cpp +++ b/src/io/audio/Audio.cpp @@ -290,6 +290,11 @@ namespace ehs return channels * frames; } + UInt_8 Audio::GetFrameSize() const + { + return byteDepth * channels; + } + UInt_64 Audio::GetSize() const { return byteDepth * channels * frames; @@ -300,6 +305,11 @@ namespace ehs return length; } + Byte* Audio::GetFrame(UInt_64 frameIndex) const + { + return &data[frameIndex * GetFrameSize()]; + } + Array Audio::FrameAsMono(const UInt_64 frameIndex) const { Array result(byteDepth); @@ -1743,161 +1753,161 @@ namespace ehs void Audio::SInt_16_to_SInt_8(Byte* newData, Byte* newPeak) const { for (UInt_64 a = 0; a < GetSampleCount(); ++a) - newData[a] = (Byte)((float)((SInt_16*)data)[a] / (float)EHS_SINT_16_MAX * (float)EHS_SINT_8_MAX); + newData[a] = (Byte)((double)((SInt_16*)data)[a] / (double)EHS_SINT_16_MAX * (double)EHS_SINT_8_MAX); - *(SInt_8*)newPeak = (SInt_8)((float)*(SInt_16*)peak / (float)EHS_SINT_16_MAX * (float)EHS_SINT_8_MAX); + *(SInt_8*)newPeak = (SInt_8)((double)*(SInt_16*)peak / (double)EHS_SINT_16_MAX * (double)EHS_SINT_8_MAX); } void Audio::Float_to_SInt_8(Byte* newData, Byte* newPeak) const { for (UInt_64 a = 0; a < GetSampleCount(); ++a) - ((SInt_8*)newData)[a] = (SInt_8)(((float*)data)[a] * (float)EHS_SINT_8_MAX); + ((SInt_8*)newData)[a] = (SInt_8)((double)((float*)data)[a] * (double)EHS_SINT_8_MAX); - *(SInt_8*)newPeak = (SInt_8)(*(float*)peak * (float)EHS_SINT_8_MAX); + *(SInt_8*)newPeak = (SInt_8)((double)(*(float*)peak) * (double)EHS_SINT_8_MAX); } void Audio::SInt_32_to_SInt_8(Byte* newData, Byte* newPeak) const { for (UInt_64 a = 0; a < GetSampleCount(); ++a) - newData[a] = (Byte)((float)((SInt_32*)data)[a] / (float)EHS_SINT_32_MAX * (float)EHS_SINT_8_MAX); + newData[a] = (Byte)((double)((SInt_32*)data)[a] / (double)EHS_SINT_32_MAX * (double)EHS_SINT_8_MAX); - *(SInt_8*)newPeak = (SInt_8)((float)*(SInt_32*)peak / (float)EHS_SINT_32_MAX * (float)EHS_SINT_8_MAX); + *(SInt_8*)newPeak = (SInt_8)((double)*(SInt_32*)peak / (double)EHS_SINT_32_MAX * (double)EHS_SINT_8_MAX); } void Audio::SInt_64_to_SInt_8(Byte* newData, Byte* newPeak) const { for (UInt_64 a = 0; a < GetSampleCount(); ++a) - newData[a] = (Byte)((float)((SInt_64*)data)[a] / (float)EHS_SINT_64_MAX * (float)EHS_SINT_8_MAX); + newData[a] = (Byte)((double)((SInt_64*)data)[a] / (double)EHS_SINT_64_MAX * (double)EHS_SINT_8_MAX); - *(SInt_8*)newPeak = (SInt_8)((float)*(SInt_64*)peak / (float)EHS_SINT_64_MAX * (float)EHS_SINT_8_MAX); + *(SInt_8*)newPeak = (SInt_8)((double)*(SInt_64*)peak / (double)EHS_SINT_64_MAX * (double)EHS_SINT_8_MAX); } void Audio::SInt_8_to_SInt_16(Byte* newData, Byte* newPeak) const { for (UInt_64 a = 0; a < GetSampleCount(); ++a) - ((SInt_16*)newData)[a] = (SInt_16)((float)(SInt_8)data[a] / (float)EHS_SINT_8_MAX * (float)EHS_SINT_16_MAX); + ((SInt_16*)newData)[a] = (SInt_16)((double)(SInt_8)data[a] / (double)EHS_SINT_8_MAX * (double)EHS_SINT_16_MAX); - *(SInt_16*)newPeak = (SInt_16)((float)*(SInt_8*)peak / (float)EHS_SINT_8_MAX * (float)EHS_SINT_16_MAX); + *(SInt_16*)newPeak = (SInt_16)((double)*(SInt_8*)peak / (double)EHS_SINT_8_MAX * (double)EHS_SINT_16_MAX); } void Audio::Float_to_SInt_16(Byte* newData, Byte* newPeak) const { for (UInt_64 a = 0; a < GetSampleCount(); ++a) - ((SInt_16*)newData)[a] = (SInt_16)(((float*)data)[a] * (float)EHS_SINT_16_MAX); + ((SInt_16*)newData)[a] = (SInt_16)((double)((float*)data)[a] * (double)EHS_SINT_16_MAX); - *(SInt_16*)newPeak = (SInt_16)(*(float*)peak * (float)EHS_SINT_16_MAX); + *(SInt_16*)newPeak = (SInt_16)((double)(*(float*)peak) * (double)EHS_SINT_16_MAX); } void Audio::SInt_32_to_SInt_16(Byte* newData, Byte* newPeak) const { for (UInt_64 a = 0; a < GetSampleCount(); ++a) - ((SInt_16*)newData)[a] = (SInt_16)((float)((SInt_32*)data)[a] / (float)EHS_SINT_32_MAX * (float)EHS_SINT_16_MAX); + ((SInt_16*)newData)[a] = (SInt_16)((double)((SInt_32*)data)[a] / (double)EHS_SINT_32_MAX * (double)EHS_SINT_16_MAX); - *(SInt_16*)newPeak = (SInt_16)((float)*(SInt_32*)peak / (float)EHS_SINT_32_MAX * (float)EHS_SINT_16_MAX); + *(SInt_16*)newPeak = (SInt_16)((double)*(SInt_32*)peak / (double)EHS_SINT_32_MAX * (double)EHS_SINT_16_MAX); } void Audio::SInt_64_to_SInt_16(Byte* newData, Byte* newPeak) const { for (UInt_64 a = 0; a < GetSampleCount(); ++a) - ((SInt_16*)newData)[a] = (SInt_16)((float)((SInt_64*)data)[a] / (float)EHS_SINT_64_MAX * (float)EHS_SINT_16_MAX); + ((SInt_16*)newData)[a] = (SInt_16)((double)((SInt_64*)data)[a] / (double)EHS_SINT_64_MAX * (double)EHS_SINT_16_MAX); - *(SInt_16*)newPeak = (SInt_16)((float)*(SInt_64*)peak / (float)EHS_SINT_64_MAX * (float)EHS_SINT_16_MAX); + *(SInt_16*)newPeak = (SInt_16)((double)*(SInt_64*)peak / (double)EHS_SINT_64_MAX * (double)EHS_SINT_16_MAX); } void Audio::SInt_8_to_Float(Byte* newData, Byte* newPeak) const { for (UInt_64 a = 0; a < GetSampleCount(); ++a) - ((float*)newData)[a] = (float)(((SInt_8*)data)[a]) / (float)EHS_SINT_8_MAX; + ((float*)newData)[a] = (float)((double)(((SInt_8*)data)[a]) / (double)EHS_SINT_8_MAX); - *(float*)newPeak = (float)*(SInt_8*)peak / (float)EHS_SINT_8_MAX; + *(float*)newPeak = (float)((double)*(SInt_8*)peak / (double)EHS_SINT_8_MAX); } void Audio::SInt_16_to_Float(Byte* newData, Byte* newPeak) const { for (UInt_64 a = 0; a < GetSampleCount(); ++a) - ((float*)newData)[a] = (float)(((SInt_16*)data)[a]) / (float)EHS_SINT_16_MAX; + ((float*)newData)[a] = (float)((double)(((SInt_16*)data)[a]) / (double)EHS_SINT_16_MAX); - *(float*)newPeak = (float)*(SInt_16*)peak / (float)EHS_SINT_16_MAX; + *(float*)newPeak = (float)((double)*(SInt_16*)peak / (double)EHS_SINT_16_MAX); } void Audio::SInt_32_to_Float(Byte* newData, Byte* newPeak) const { for (UInt_64 a = 0; a < GetSampleCount(); ++a) - ((float*)newData)[a] = (float)(((SInt_32*)data)[a]) / (float)EHS_SINT_32_MAX; + ((float*)newData)[a] = (float)((double)(((SInt_32*)data)[a]) / (double)EHS_SINT_32_MAX); - *(float*)newPeak = (float)*(SInt_32*)peak / (float)EHS_SINT_32_MAX; + *(float*)newPeak = (float)((double)*(SInt_32*)peak / (double)EHS_SINT_32_MAX); } void Audio::SInt_64_to_Float(Byte* newData, Byte* newPeak) const { for (UInt_64 a = 0; a < GetSampleCount(); ++a) - ((float*)newData)[a] = (float)(((SInt_64*)data)[a]) / (float)EHS_SINT_64_MAX; + ((float*)newData)[a] = (float)((double)(((SInt_64*)data)[a]) / (double)EHS_SINT_64_MAX); - *(float*)newPeak = (float)*(SInt_64*)peak / (float)EHS_SINT_64_MAX; + *(float*)newPeak = (float)((double)*(SInt_64*)peak / (double)EHS_SINT_64_MAX); } void Audio::SInt_8_to_SInt_32(Byte* newData, Byte* newPeak) const { for (UInt_64 a = 0; a < GetSampleCount(); ++a) - ((SInt_32*)newData)[a] = (SInt_32)((float)(SInt_8)data[a] / (float)EHS_SINT_8_MAX * (float)EHS_SINT_32_MAX); + ((SInt_32*)newData)[a] = (SInt_32)((double)(SInt_8)data[a] / (double)EHS_SINT_8_MAX * (double)EHS_SINT_32_MAX); - *(SInt_32*)newPeak = (SInt_32)((float)*(SInt_8*)peak / (float)EHS_SINT_8_MAX * (float)EHS_SINT_32_MAX); + *(SInt_32*)newPeak = (SInt_32)((double)*(SInt_8*)peak / (double)EHS_SINT_8_MAX * (double)EHS_SINT_32_MAX); } void Audio::SInt_16_to_SInt_32(Byte* newData, Byte* newPeak) const { for (UInt_64 a = 0; a < GetSampleCount(); ++a) - ((SInt_32*)newData)[a] = (SInt_32)((float)((SInt_16*)data)[a] / (float)EHS_SINT_16_MAX * (float)EHS_SINT_32_MAX); + ((SInt_32*)newData)[a] = (SInt_32)((double)((SInt_16*)data)[a] / (double)EHS_SINT_16_MAX * (double)EHS_SINT_32_MAX); - *(SInt_32*)newPeak = (SInt_32)((float)*(SInt_16*)peak / (float)EHS_SINT_16_MAX * (float)EHS_SINT_32_MAX); + *(SInt_32*)newPeak = (SInt_32)((double)*(SInt_16*)peak / (double)EHS_SINT_16_MAX * (double)EHS_SINT_32_MAX); } void Audio::Float_to_SInt_32(Byte* newData, Byte* newPeak) const { for (UInt_64 a = 0; a < GetSampleCount(); ++a) - ((SInt_32*)newData)[a] = (SInt_32)(((float*)data)[a] * (float)EHS_SINT_32_MAX); + ((SInt_32*)newData)[a] = (SInt_32)(((double*)data)[a] * (double)EHS_SINT_32_MAX); - *(SInt_32*)newPeak = (SInt_32)(*(float*)peak * (float)EHS_SINT_32_MAX); + *(SInt_32*)newPeak = (SInt_32)(*(double*)peak * (double)EHS_SINT_32_MAX); } void Audio::SInt_64_to_SInt_32(Byte* newData, Byte* newPeak) const { for (UInt_64 a = 0; a < GetSampleCount(); ++a) - ((SInt_32*)newData)[a] = (SInt_32)((float)((SInt_64*)data)[a] / (float)EHS_SINT_64_MAX * (float)EHS_SINT_32_MAX); + ((SInt_32*)newData)[a] = (SInt_32)((double)((SInt_64*)data)[a] / (double)EHS_SINT_64_MAX * (double)EHS_SINT_32_MAX); - *(SInt_32*)newPeak = (SInt_32)((float)*(SInt_64*)peak / (float)EHS_SINT_64_MAX * (float)EHS_SINT_32_MAX); + *(SInt_32*)newPeak = (SInt_32)((double)*(SInt_64*)peak / (double)EHS_SINT_64_MAX * (double)EHS_SINT_32_MAX); } void Audio::SInt_8_to_SInt_64(Byte* newData, Byte* newPeak) const { for (UInt_64 a = 0; a < GetSampleCount(); ++a) - ((SInt_64*)newData)[a] = (SInt_64)((float)(SInt_8)data[a] / (float)EHS_SINT_8_MAX * (float)EHS_SINT_64_MAX); + ((SInt_64*)newData)[a] = (SInt_64)((double)(SInt_8)data[a] / (double)EHS_SINT_8_MAX * (double)EHS_SINT_64_MAX); - *(SInt_64*)newPeak = (SInt_64)((float)*(SInt_8*)peak / (float)EHS_SINT_8_MAX * (float)EHS_SINT_64_MAX); + *(SInt_64*)newPeak = (SInt_64)((double)*(SInt_8*)peak / (double)EHS_SINT_8_MAX * (double)EHS_SINT_64_MAX); } void Audio::SInt_16_to_SInt_64(Byte* newData, Byte* newPeak) const { for (UInt_64 a = 0; a < GetSampleCount(); ++a) - ((SInt_64*)newData)[a] = (SInt_64)((float)((SInt_16*)data)[a] / (float)EHS_SINT_16_MAX * (float)EHS_SINT_64_MAX); + ((SInt_64*)newData)[a] = (SInt_64)((double)((SInt_16*)data)[a] / (double)EHS_SINT_16_MAX * (double)EHS_SINT_64_MAX); - *(SInt_64*)newPeak = (SInt_64)((float)*(SInt_16*)peak / (float)EHS_SINT_16_MAX * (float)EHS_SINT_64_MAX); + *(SInt_64*)newPeak = (SInt_64)((double)*(SInt_16*)peak / (double)EHS_SINT_16_MAX * (double)EHS_SINT_64_MAX); } void Audio::Float_to_SInt_64(Byte* newData, Byte* newPeak) const { for (UInt_64 a = 0; a < GetSampleCount(); ++a) - ((SInt_64*)newData)[a] = (SInt_64)(((float*)data)[a] * (float)EHS_SINT_64_MAX); + ((SInt_64*)newData)[a] = (SInt_64)(((double*)data)[a] * (double)EHS_SINT_64_MAX); - *(SInt_64*)newPeak = (SInt_64)(*(float*)peak * (float)EHS_SINT_64_MAX); + *(SInt_64*)newPeak = (SInt_64)(*(double*)peak * (double)EHS_SINT_64_MAX); } void Audio::SInt_32_to_SInt_64(Byte* newData, Byte* newPeak) const { for (UInt_64 a = 0; a < GetSampleCount(); ++a) - ((SInt_64*)newData)[a] = (SInt_64)((float)((SInt_32*)data)[a] / (float)EHS_SINT_32_MAX * (float)EHS_SINT_64_MAX); + ((SInt_64*)newData)[a] = (SInt_64)((double)((SInt_32*)data)[a] / (double)EHS_SINT_32_MAX * (double)EHS_SINT_64_MAX); - *(SInt_64*)newPeak = (SInt_64)((float)*(SInt_32*)peak / (float)EHS_SINT_32_MAX * (float)EHS_SINT_64_MAX); + *(SInt_64*)newPeak = (SInt_64)((double)*(SInt_32*)peak / (double)EHS_SINT_32_MAX * (double)EHS_SINT_64_MAX); } bool EncodeEHA(const ehs::AudioCodec* const codec, ehs::Serializer& out, const ehs::Audio* const in) diff --git a/src/io/audio/AudioDevice_W32.cpp b/src/io/audio/AudioDevice_W32.cpp index b26f3d8..293811e 100644 --- a/src/io/audio/AudioDevice_W32.cpp +++ b/src/io/audio/AudioDevice_W32.cpp @@ -341,6 +341,8 @@ namespace ehs return 0; } + Util::Copy(buffer, data, frameSize * byteDepth * channels); + r = playbackClient->ReleaseBuffer(frameSize, 0); if (r == AUDCLNT_E_DEVICE_INVALIDATED) { diff --git a/src/io/audio/BaseAudioDevice.cpp b/src/io/audio/BaseAudioDevice.cpp index 7eb2335..be0be64 100644 --- a/src/io/audio/BaseAudioDevice.cpp +++ b/src/io/audio/BaseAudioDevice.cpp @@ -1,4 +1,5 @@ #include "ehs/io/audio/BaseAudioDevice.h" +#include "ehs/log.h" namespace ehs { @@ -49,19 +50,48 @@ namespace ehs return 0; } - void BaseAudioDevice::BridgeStreams(const UInt_64 bufferSize) + void BaseAudioDevice::BridgeStreams(BaseAudioDevice* input, UInt_64 frameBufferSize) { - Byte* buffer = new Byte[bufferSize]; + if (type != AudioDeviceType::OUTPUT) + { + EHS_LOG_INT(LogType::WARN, 0, "The current audio device object is not an output device."); + return; + } - UInt_64 result = ReceiveStream(buffer, bufferSize); - while (result < bufferSize) - result += ReceiveStream(&buffer[result], bufferSize - result); + if (input->type != AudioDeviceType::INPUT) + { + EHS_LOG_INT(LogType::WARN, 1, "The provided audio device is not an input device."); + return; + } + + Byte* buffer = new Byte[frameBufferSize * GetFrameSize()]; + + UInt_64 result = 0; + while (result < frameBufferSize) + result += input->ReceiveStream(&buffer[result * GetFrameSize()], frameBufferSize - result); - result -= SendStream(buffer, result); while (result) - result -= SendStream(&buffer[bufferSize - result], result); + result -= SendStream(&buffer[(frameBufferSize - result) * GetFrameSize()], result); delete[] buffer; + + EHS_LOG_SUCCESS(); + } + + void BaseAudioDevice::BridgeStreams(const UInt_64 frameBufferSize) + { + Byte* buffer = new Byte[frameBufferSize * GetFrameSize()]; + + UInt_64 result = ReceiveStream(buffer, frameBufferSize); + while (result < frameBufferSize) + result += ReceiveStream(&buffer[result * GetFrameSize()], frameBufferSize - result); + + while (result) + result -= SendStream(&buffer[(frameBufferSize - result) * GetFrameSize()], result); + + delete[] buffer; + + EHS_LOG_SUCCESS(); } AudioDeviceType BaseAudioDevice::GetType() const