mirror of
https://github.com/gnif/LookingGlass.git
synced 2026-11-13 07:17:28 +00:00
[idd] audio: support 32-bit and common channel layouts
Advertise signed and floating-point 32-bit formats across mono, stereo, quad, surround, 5.1, and 7.1 at every supported rate. Carry sample encoding through the broker and LGMP protocol so integer and floating-point streams remain distinct. Expand packet, shared-memory, and ring capacity for eight-channel 32-bit audio.
This commit is contained in:
@@ -70,7 +70,8 @@ namespace
|
||||
|
||||
bool SameFormat(const AudioFormat& left, const AudioFormat& right)
|
||||
{
|
||||
return left.sampleRate == right.sampleRate &&
|
||||
return left.sampleFormat == right.sampleFormat &&
|
||||
left.sampleRate == right.sampleRate &&
|
||||
left.channelMask == right.channelMask &&
|
||||
left.channels == right.channels &&
|
||||
left.containerBits == right.containerBits &&
|
||||
@@ -78,6 +79,22 @@ namespace
|
||||
left.blockAlign == right.blockAlign;
|
||||
}
|
||||
|
||||
bool ValidSampleFormat(const AudioFormat& format)
|
||||
{
|
||||
switch (format.sampleFormat)
|
||||
{
|
||||
case AudioSampleFormat::S16_LE:
|
||||
return format.containerBits == 16 && format.validBits == 16;
|
||||
case AudioSampleFormat::S24_LE:
|
||||
return format.containerBits == 24 && format.validBits == 24;
|
||||
case AudioSampleFormat::S32_LE:
|
||||
case AudioSampleFormat::F32_LE:
|
||||
return format.containerBits == 32 && format.validBits == 32;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool ValidFormat(const AudioFormat& format)
|
||||
{
|
||||
return format.sampleRate && format.sampleRate <= 192000 &&
|
||||
@@ -85,15 +102,52 @@ namespace
|
||||
format.channelMask &&
|
||||
!(format.channelMask & ~AUDIO_CHANNEL_POSITION_MASK) &&
|
||||
PopCount(format.channelMask) == format.channels &&
|
||||
(format.containerBits == 16 || format.containerBits == 24) &&
|
||||
format.validBits == format.containerBits &&
|
||||
ValidSampleFormat(format) &&
|
||||
format.blockAlign ==
|
||||
format.channels * (format.containerBits / 8);
|
||||
}
|
||||
|
||||
AudioSampleFormat BrokerSampleFormat(uint32_t source)
|
||||
{
|
||||
switch (source)
|
||||
{
|
||||
case LGAUDIO_BROKER_SAMPLE_S16_LE:
|
||||
return AudioSampleFormat::S16_LE;
|
||||
case LGAUDIO_BROKER_SAMPLE_S24_LE:
|
||||
return AudioSampleFormat::S24_LE;
|
||||
case LGAUDIO_BROKER_SAMPLE_S32_LE:
|
||||
return AudioSampleFormat::S32_LE;
|
||||
case LGAUDIO_BROKER_SAMPLE_F32_LE:
|
||||
return AudioSampleFormat::F32_LE;
|
||||
default:
|
||||
return AudioSampleFormat::UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t DeviceSampleFormat(AudioSampleFormat source)
|
||||
{
|
||||
switch (source)
|
||||
{
|
||||
case AudioSampleFormat::S16_LE:
|
||||
return LGAUDIO_BROKER_SAMPLE_S16_LE;
|
||||
case AudioSampleFormat::S24_LE:
|
||||
return LGAUDIO_BROKER_SAMPLE_S24_LE;
|
||||
case AudioSampleFormat::S32_LE:
|
||||
return LGAUDIO_BROKER_SAMPLE_S32_LE;
|
||||
case AudioSampleFormat::F32_LE:
|
||||
return LGAUDIO_BROKER_SAMPLE_F32_LE;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
AudioFormat BrokerFormat(const LGAudioBrokerFormat& source)
|
||||
{
|
||||
AudioFormat result;
|
||||
if (source.reserved)
|
||||
return result;
|
||||
|
||||
result.sampleFormat = BrokerSampleFormat(source.sampleFormat);
|
||||
result.sampleRate = source.sampleRate;
|
||||
result.channelMask = source.channelMask;
|
||||
result.channels = source.channels;
|
||||
@@ -106,6 +160,7 @@ namespace
|
||||
LGAudioBrokerFormat DeviceFormat(const AudioFormat& source)
|
||||
{
|
||||
LGAudioBrokerFormat result = {};
|
||||
result.sampleFormat = DeviceSampleFormat(source.sampleFormat);
|
||||
result.sampleRate = source.sampleRate;
|
||||
result.channelMask = source.channelMask;
|
||||
result.channels = source.channels;
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
static constexpr uint32_t AUDIO_MAX_CHANNELS = 18;
|
||||
static constexpr uint32_t AUDIO_STREAM_MAX_CHANNELS = 8;
|
||||
static constexpr uint32_t AUDIO_MAX_FRAMES_PER_PACKET = 2048;
|
||||
static constexpr uint32_t AUDIO_MAX_BYTES_PER_SAMPLE = 3;
|
||||
static constexpr uint32_t AUDIO_MAX_BYTES_PER_SAMPLE = 4;
|
||||
static constexpr uint32_t AUDIO_MAX_PCM_BYTES =
|
||||
AUDIO_MAX_FRAMES_PER_PACKET * AUDIO_STREAM_MAX_CHANNELS *
|
||||
AUDIO_MAX_BYTES_PER_SAMPLE;
|
||||
@@ -54,6 +54,15 @@ enum AudioClockFlag : uint32_t
|
||||
AUDIO_CLOCK_DISCONTINUITY = 1U << 2,
|
||||
};
|
||||
|
||||
enum class AudioSampleFormat : uint32_t
|
||||
{
|
||||
UNKNOWN = 0,
|
||||
S16_LE = 1,
|
||||
S24_LE = 2,
|
||||
S32_LE = 3,
|
||||
F32_LE = 4,
|
||||
};
|
||||
|
||||
enum class AudioStreamState : uint32_t
|
||||
{
|
||||
UNAVAILABLE,
|
||||
@@ -75,12 +84,13 @@ enum class AudioResult
|
||||
|
||||
struct AudioFormat
|
||||
{
|
||||
uint32_t sampleRate = 0;
|
||||
uint32_t channelMask = 0;
|
||||
uint16_t channels = 0;
|
||||
uint16_t containerBits = 0;
|
||||
uint16_t validBits = 0;
|
||||
uint16_t blockAlign = 0;
|
||||
AudioSampleFormat sampleFormat = AudioSampleFormat::UNKNOWN;
|
||||
uint32_t sampleRate = 0;
|
||||
uint32_t channelMask = 0;
|
||||
uint16_t channels = 0;
|
||||
uint16_t containerBits = 0;
|
||||
uint16_t validBits = 0;
|
||||
uint16_t blockAlign = 0;
|
||||
};
|
||||
|
||||
struct AudioStreamStatus
|
||||
|
||||
@@ -50,6 +50,16 @@ namespace
|
||||
"audio packet limits differ");
|
||||
static_assert(AUDIO_MAX_PCM_BYTES == KVMFR_AUDIO_PCM_BYTES,
|
||||
"audio PCM limits differ");
|
||||
static_assert(
|
||||
static_cast<uint32_t>(AudioSampleFormat::S16_LE) ==
|
||||
KVMFR_AUDIO_SAMPLE_S16_LE &&
|
||||
static_cast<uint32_t>(AudioSampleFormat::S24_LE) ==
|
||||
KVMFR_AUDIO_SAMPLE_S24_LE &&
|
||||
static_cast<uint32_t>(AudioSampleFormat::S32_LE) ==
|
||||
KVMFR_AUDIO_SAMPLE_S32_LE &&
|
||||
static_cast<uint32_t>(AudioSampleFormat::F32_LE) ==
|
||||
KVMFR_AUDIO_SAMPLE_F32_LE,
|
||||
"audio sample formats differ");
|
||||
static_assert(static_cast<uint32_t>(AUDIO_CAP_PLAYBACK) ==
|
||||
static_cast<uint32_t>(KVMFR_AUDIO_CAP_PLAYBACK) &&
|
||||
static_cast<uint32_t>(AUDIO_CAP_CAPTURE) ==
|
||||
@@ -75,7 +85,7 @@ namespace
|
||||
KVMFR_AUDIO_MESSAGE_CLOCK_VALID |
|
||||
KVMFR_AUDIO_MESSAGE_CLOCK_STABLE;
|
||||
constexpr size_t AUDIO_SHARED_MEMORY_PREFLIGHT =
|
||||
2U * 1024U * 1024U;
|
||||
3U * 1024U * 1024U;
|
||||
|
||||
bool ArmAudioPollTimer(HANDLE timer, uint32_t waitUs)
|
||||
{
|
||||
@@ -122,7 +132,8 @@ CLGMPAudioTransport::~CLGMPAudioTransport()
|
||||
bool CLGMPAudioTransport::SameFormat(
|
||||
const AudioFormat& left, const AudioFormat& right)
|
||||
{
|
||||
return left.sampleRate == right.sampleRate &&
|
||||
return left.sampleFormat == right.sampleFormat &&
|
||||
left.sampleRate == right.sampleRate &&
|
||||
left.channelMask == right.channelMask &&
|
||||
left.channels == right.channels &&
|
||||
left.containerBits == right.containerBits &&
|
||||
@@ -152,11 +163,29 @@ bool CLGMPAudioTransport::ValidFormat(const AudioFormat& format)
|
||||
ChannelCount(format.channelMask) != format.channels)
|
||||
return false;
|
||||
|
||||
const bool s16 = format.containerBits == 16 && format.validBits == 16;
|
||||
const bool s24 = format.containerBits == 24 && format.validBits == 24;
|
||||
bool validSampleFormat = false;
|
||||
switch (format.sampleFormat)
|
||||
{
|
||||
case AudioSampleFormat::S16_LE:
|
||||
validSampleFormat =
|
||||
format.containerBits == 16 && format.validBits == 16;
|
||||
break;
|
||||
case AudioSampleFormat::S24_LE:
|
||||
validSampleFormat =
|
||||
format.containerBits == 24 && format.validBits == 24;
|
||||
break;
|
||||
case AudioSampleFormat::S32_LE:
|
||||
case AudioSampleFormat::F32_LE:
|
||||
validSampleFormat =
|
||||
format.containerBits == 32 && format.validBits == 32;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
const uint16_t bytes = static_cast<uint16_t>(
|
||||
format.channels * (format.containerBits / 8U));
|
||||
return (s16 || s24) && format.blockAlign == bytes;
|
||||
return validSampleFormat && format.blockAlign == bytes;
|
||||
}
|
||||
|
||||
KVMFRAudioFormat CLGMPAudioTransport::WireFormat(
|
||||
@@ -165,8 +194,8 @@ KVMFRAudioFormat CLGMPAudioTransport::WireFormat(
|
||||
KVMFRAudioFormat result = {};
|
||||
result.version = KVMFR_AUDIO_FORMAT_VERSION;
|
||||
result.size = sizeof(result);
|
||||
result.sampleFormat = format.containerBits == 16 ?
|
||||
KVMFR_AUDIO_SAMPLE_S16_LE : KVMFR_AUDIO_SAMPLE_S24_LE;
|
||||
result.sampleFormat =
|
||||
static_cast<uint32_t>(format.sampleFormat);
|
||||
result.sampleRate = format.sampleRate;
|
||||
result.channelMask = format.channelMask;
|
||||
result.channelCount = format.channels;
|
||||
|
||||
Reference in New Issue
Block a user