Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions ASFWDriver/Audio/Core/AudioEndpointRuntime.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ class AudioEndpointRuntime final : public Runtime::IDirectAudioBindingSource {
directOutputBase_ = reinterpret_cast<const float*>(
static_cast<uintptr_t>(directOutputMap_->GetAddress()));
directOutputBytes_ = directOutputMap_->GetLength();
directInputBase_ = reinterpret_cast<int32_t*>(
directInputBase_ = reinterpret_cast<float*>(
static_cast<uintptr_t>(directInputMap_->GetAddress()));
directInputBytes_ = directInputMap_->GetLength();
directControl_ = reinterpret_cast<Runtime::AudioTransportControlBlock*>(
Expand Down Expand Up @@ -507,7 +507,7 @@ class AudioEndpointRuntime final : public Runtime::IDirectAudioBindingSource {
uint64_t directOutputBytes_{0};
uint32_t directOutputCapacityFrames_{0};
uint32_t directOutputChannels_{0};
int32_t* directInputBase_{nullptr};
float* directInputBase_{nullptr};
uint64_t directInputBytes_{0};
uint32_t directInputCapacityFrames_{0};
uint32_t directInputChannels_{0};
Expand Down
2 changes: 1 addition & 1 deletion ASFWDriver/Audio/DriverKit/ASFWAudioDriverDirect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ bool BindDirectAudioSkeleton(ASFWAudioDriver_IVars& ivars) noexcept {
.guid = ivars.device.guid,
.sampleRateHz = static_cast<uint32_t>(ivars.device.currentSampleRate),
.memory = ASFW::Audio::Runtime::AudioStreamMemory{
.inputBase = reinterpret_cast<int32_t*>(static_cast<uintptr_t>(ivars.inputMap->GetAddress())),
.inputBase = reinterpret_cast<float*>(static_cast<uintptr_t>(ivars.inputMap->GetAddress())),
.outputBase = reinterpret_cast<const float*>(static_cast<uintptr_t>(ivars.outputMap->GetAddress())),
.inputFrameCapacity = inputFrameCapacity,
.outputFrameCapacity = outputFrameCapacity,
Expand Down
21 changes: 3 additions & 18 deletions ASFWDriver/Audio/DriverKit/ASFWAudioDriverGraph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,21 +85,6 @@ void CopyParsedConfigToDeviceState(const ASFW::Isoch::Audio::ParsedAudioDriverCo
return kIOReturnSuccess;
}

void FillPcm24Format(IOUserAudioStreamBasicDescription& fmt,
double sampleRate,
uint32_t channels) noexcept {
fmt.mSampleRate = sampleRate;
fmt.mFormatID = IOUserAudioFormatID::LinearPCM;
fmt.mFormatFlags = static_cast<IOUserAudioFormatFlags>(
static_cast<uint32_t>(IOUserAudioFormatFlags::FormatFlagIsSignedInteger) |
static_cast<uint32_t>(IOUserAudioFormatFlags::FormatFlagsNativeEndian));
fmt.mBytesPerPacket = sizeof(int32_t) * channels;
fmt.mFramesPerPacket = 1;
fmt.mBytesPerFrame = sizeof(int32_t) * channels;
fmt.mChannelsPerFrame = channels;
fmt.mBitsPerChannel = 24;
}

void FillFloat32Format(IOUserAudioStreamBasicDescription& fmt,
double sampleRate,
uint32_t channels) noexcept {
Expand Down Expand Up @@ -243,7 +228,7 @@ kern_return_t BuildAudioGraph(ASFWAudioDriver& driver,
? "blocking" : "non-blocking");

ASFW_LOG(Audio,
"ASFWAudioDriver: Forcing single advertised format: input=24-bit integer output=Float32");
"ASFWAudioDriver: Forcing single advertised format: input=Float32 output=Float32");
ASFW_LOG(Audio,
"ASFWAudioDriver: Effective runtime channels: input=%u output=%u aggregate=%u",
ivars.device.inputChannelCount,
Expand Down Expand Up @@ -324,12 +309,12 @@ kern_return_t BuildAudioGraph(ASFWAudioDriver& driver,
IOUserAudioStreamBasicDescription outputFormats[8] = {};
const uint32_t formatCount = ivars.device.sampleRateCount > 8 ? 8 : ivars.device.sampleRateCount;
for (uint32_t i = 0; i < formatCount; i++) {
FillPcm24Format(inputFormats[i], ivars.device.sampleRates[i], ivars.device.inputChannelCount);
FillFloat32Format(inputFormats[i], ivars.device.sampleRates[i], ivars.device.inputChannelCount);
FillFloat32Format(outputFormats[i], ivars.device.sampleRates[i], ivars.device.outputChannelCount);
}

ASFW_LOG(Audio,
"ASFWAudioDriver: Created %u stream formats input=int24/%u ch output=float32/%u ch",
"ASFWAudioDriver: Created %u stream formats input=float32/%u ch output=float32/%u ch",
formatCount,
ivars.device.inputChannelCount,
ivars.device.outputChannelCount);
Expand Down
4 changes: 2 additions & 2 deletions ASFWDriver/Audio/DriverKit/Runtime/AudioStreamMemory.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ enum class AudioSampleStorage : uint32_t {
};

struct AudioStreamMemory final {
int32_t* inputBase{nullptr};
float* inputBase{nullptr};
const float* outputBase{nullptr};

uint32_t inputFrameCapacity{0};
Expand All @@ -38,7 +38,7 @@ struct AudioStreamMemory final {
return HasInput() || HasOutput();
}

[[nodiscard]] int32_t* InputFrame(uint64_t absoluteFrame) const noexcept {
[[nodiscard]] float* InputFrame(uint64_t absoluteFrame) const noexcept {
if (!HasInput()) {
return nullptr;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace ASFW::Audio::Runtime {
struct DirectAudioBindingSnapshot {
uint64_t generation{0};

int32_t* inputBase{nullptr};
float* inputBase{nullptr};
uint64_t inputBytes{0};
uint32_t inputFrames{0};
uint32_t inputChannels{0};
Expand Down
2 changes: 1 addition & 1 deletion ASFWDriver/Audio/Engine/Direct/DirectInputWriter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class DirectInputWriter final {
return binding_ != nullptr && binding_->HasInput();
}

[[nodiscard]] int32_t* Frame(uint64_t absoluteFrame) const noexcept {
[[nodiscard]] float* Frame(uint64_t absoluteFrame) const noexcept {
if (!IsBound()) {
return nullptr;
}
Expand Down
38 changes: 32 additions & 6 deletions ASFWDriver/Audio/Engine/Direct/Rx/DirectRxPacketDecoder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,49 @@

#include "DirectRxTypes.hpp"
#include "../../../Wire/AM824/AM824Decoder.hpp"
#include "../../../Wire/RawPcm24In32/RawPcm24In32Decoder.hpp"
#include <cstdint>

namespace ASFW::AudioEngine::Direct::Rx {

namespace Detail {

[[nodiscard]] constexpr float Signed24ToFloat32(int32_t sample) noexcept {
if (sample <= -8388608) {
return -1.0f;
}
return static_cast<float>(sample) / 8388607.0f;
}

[[nodiscard]] inline float DecodeAm824SlotToFloat32(uint32_t wireQuadlet) noexcept {
auto sample = ASFW::Isoch::AM824Decoder::DecodeSample(wireQuadlet);
return sample ? Signed24ToFloat32(*sample) : 0.0f;
}

[[nodiscard]] inline float DecodeRawSlotAsLabeledMBLAToFloat32(uint32_t wireQuadlet) noexcept {
const uint32_t hostQuadlet = OSSwapBigToHostInt32(wireQuadlet);
// Saffire raw capture carries native signed 24-in-32 slots. Normalize it
// to an AM824 MBLA slot by adding the 0x40 label at the wire/content seam;
// cross-validated with Linux amdtp-am824.c:170 and :200.
const uint32_t labeledHostQuadlet =
0x40000000u | (hostQuadlet & 0x00FFFFFFu);
return DecodeAm824SlotToFloat32(OSSwapHostToBigInt32(labeledHostQuadlet));
}

} // namespace Detail

inline void DecodeDirectRxFrame(const uint32_t* inWireQuadlets,
uint32_t pcmChannels,
uint32_t am824Slots,
ASFW::Encoding::AudioWireFormat format,
int32_t* outPcmFrame) noexcept {
float* outPcmFrame) noexcept {
(void)am824Slots;
for (uint32_t ch = 0; ch < pcmChannels; ++ch) {
if (format == ASFW::Encoding::AudioWireFormat::kRawPcm24In32) {
auto sample = ASFW::Encoding::RawPcm24In32::Decode(inWireQuadlets[ch]);
outPcmFrame[ch] = sample ? *sample : 0;
outPcmFrame[ch] =
Detail::DecodeRawSlotAsLabeledMBLAToFloat32(inWireQuadlets[ch]);
} else {
auto sample = ASFW::Isoch::AM824Decoder::DecodeSample(inWireQuadlets[ch]);
outPcmFrame[ch] = sample ? *sample : 0;
outPcmFrame[ch] =
Detail::DecodeAm824SlotToFloat32(inWireQuadlets[ch]);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ RxAudioPacketProcessorResult RxAudioPacketProcessor::ProcessPacket(const uint8_t
// If armed: decode quadlets directly to ADK input memory
const uint32_t* dataBlocks = &quadlets[2];
for (size_t i = 0; i < eventCount; ++i) {
int32_t* frameOut = writer_.Frame(absoluteFrame + i);
float* frameOut = writer_.Frame(absoluteFrame + i);
if (!frameOut) {
result.status = DirectRxWriteStatus::kInvalidRange;
return result;
Expand Down
2 changes: 1 addition & 1 deletion ASFWDriver/Isoch/Receive/IsochReceiveContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ uint32_t IsochReceiveContext::Poll() {
directInputView_.memory.inputBase = snapshot.inputBase;
directInputView_.memory.inputFrameCapacity = snapshot.inputFrames;
directInputView_.memory.inputChannels = snapshot.inputChannels;
directInputView_.memory.storage = ASFW::Audio::Runtime::AudioSampleStorage::kInt32Native;
directInputView_.memory.storage = ASFW::Audio::Runtime::AudioSampleStorage::kFloat32Native;
directInputView_.control = snapshot.control;
directInputView_.deviceToHostAm824Slots = am824Slots_ > 0 ? am824Slots_ : snapshot.inputChannels;
directInputView_.hostToDeviceAm824Slots = snapshot.outputChannels;
Expand Down
14 changes: 7 additions & 7 deletions tests/audio/AudioRuntime/AudioGraphBindingTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ using ASFW::Audio::Runtime::AudioWireFormat;

AudioGraphBinding MakeBinding(AudioTransportControlBlock* control,
IOUserAudioDevice* audioDevice,
int32_t* input,
float* input,
const float* output) {
return AudioGraphBinding{
.guid = 0x1122334455667788ULL,
Expand All @@ -42,7 +42,7 @@ AudioGraphBinding MakeBinding(AudioTransportControlBlock* control,
TEST(AudioGraphBindingTests, InvalidWithoutGuid) {
AudioTransportControlBlock control{};
IOUserAudioDevice audioDevice{};
std::array<int32_t, 16> input{};
std::array<float, 16> input{};

auto binding = MakeBinding(&control, &audioDevice, input.data(), nullptr);
binding.guid = 0;
Expand All @@ -53,7 +53,7 @@ TEST(AudioGraphBindingTests, InvalidWithoutGuid) {
TEST(AudioGraphBindingTests, InvalidWithoutSampleRate) {
AudioTransportControlBlock control{};
IOUserAudioDevice audioDevice{};
std::array<int32_t, 16> input{};
std::array<float, 16> input{};

auto binding = MakeBinding(&control, &audioDevice, input.data(), nullptr);
binding.sampleRateHz = 0;
Expand All @@ -63,7 +63,7 @@ TEST(AudioGraphBindingTests, InvalidWithoutSampleRate) {

TEST(AudioGraphBindingTests, InvalidWithoutControl) {
IOUserAudioDevice audioDevice{};
std::array<int32_t, 16> input{};
std::array<float, 16> input{};

const auto binding = MakeBinding(nullptr, &audioDevice, input.data(), nullptr);

Expand All @@ -72,7 +72,7 @@ TEST(AudioGraphBindingTests, InvalidWithoutControl) {

TEST(AudioGraphBindingTests, InvalidWithoutAudioDevice) {
AudioTransportControlBlock control{};
std::array<int32_t, 16> input{};
std::array<float, 16> input{};

const auto binding = MakeBinding(&control, nullptr, input.data(), nullptr);

Expand All @@ -82,7 +82,7 @@ TEST(AudioGraphBindingTests, InvalidWithoutAudioDevice) {
TEST(AudioGraphBindingTests, ValidWithInputOnly) {
AudioTransportControlBlock control{};
IOUserAudioDevice audioDevice{};
std::array<int32_t, 16> input{};
std::array<float, 16> input{};

const auto binding = MakeBinding(&control, &audioDevice, input.data(), nullptr);

Expand All @@ -106,7 +106,7 @@ TEST(AudioGraphBindingTests, ValidWithOutputOnly) {
TEST(AudioGraphBindingTests, ValidWithDuplex) {
AudioTransportControlBlock control{};
IOUserAudioDevice audioDevice{};
std::array<int32_t, 16> input{};
std::array<float, 16> input{};
std::array<float, 16> output{};

const auto binding = MakeBinding(&control, &audioDevice, input.data(), output.data());
Expand Down
4 changes: 2 additions & 2 deletions tests/audio/AudioRuntime/AudioStreamMemoryTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace {
using ASFW::Audio::Runtime::AudioStreamMemory;

TEST(AudioStreamMemoryTests, InputFrameWrapsByFrameCapacityAndUsesChannelStride) {
std::array<int32_t, 8> input{};
std::array<float, 8> input{};

const AudioStreamMemory memory{
.inputBase = input.data(),
Expand Down Expand Up @@ -50,7 +50,7 @@ TEST(AudioStreamMemoryTests, MissingBuffersReturnNullAndReportInvalidDirections)
}

TEST(AudioStreamMemoryTests, MemoryIsValidWithEitherDirection) {
std::array<int32_t, 2> input{};
std::array<float, 2> input{};
std::array<float, 2> output{};

const AudioStreamMemory inputOnly{
Expand Down
2 changes: 1 addition & 1 deletion tests/audio/AudioRuntime/DirectAudioDebugSnapshotTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ using ASFW::Audio::Runtime::ShouldLogDirectAudioDebugSnapshot;
TEST(DirectAudioDebugSnapshotTests, CapturesBindingCountersAndCursors) {
AudioTransportControlBlock control{};
IOUserAudioDevice audioDevice{};
std::array<int32_t, 16> input{};
std::array<float, 16> input{};
std::array<float, 16> output{};

const AudioGraphBinding binding{
Expand Down
12 changes: 6 additions & 6 deletions tests/audio/AudioRuntime/DirectAudioEngineTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ using ASFW::AudioEngine::Direct::FireWireAudioEngine;

AudioGraphBinding MakeDuplexBinding(AudioTransportControlBlock& control,
IOUserAudioDevice& audioDevice,
int32_t* input,
float* input,
const float* output) {
return AudioGraphBinding{
.guid = 0x1122334455667788ULL,
Expand Down Expand Up @@ -55,7 +55,7 @@ void PublishPlaybackWriteEnd(AudioTransportControlBlock& control,
TEST(DirectAudioEngineTests, BindValidGraphBindsSubcomponents) {
AudioTransportControlBlock control{};
IOUserAudioDevice audioDevice{};
std::array<int32_t, 16> input{};
std::array<float, 16> input{};
std::array<float, 16> output{};
FireWireAudioEngine engine{};

Expand All @@ -72,7 +72,7 @@ TEST(DirectAudioEngineTests, BindValidGraphBindsSubcomponents) {
TEST(DirectAudioEngineTests, BindInvalidGraphClearsState) {
AudioTransportControlBlock control{};
IOUserAudioDevice audioDevice{};
std::array<int32_t, 16> input{};
std::array<float, 16> input{};
std::array<float, 16> output{};
FireWireAudioEngine engine{};

Expand All @@ -91,7 +91,7 @@ TEST(DirectAudioEngineTests, BindInvalidGraphClearsState) {
TEST(DirectAudioEngineTests, UnbindClearsState) {
AudioTransportControlBlock control{};
IOUserAudioDevice audioDevice{};
std::array<int32_t, 16> input{};
std::array<float, 16> input{};
std::array<float, 16> output{};
FireWireAudioEngine engine{};

Expand All @@ -108,7 +108,7 @@ TEST(DirectAudioEngineTests, UnbindClearsState) {
TEST(DirectAudioEngineTests, OutputReaderUsesPlaybackRingCursorAvailability) {
AudioTransportControlBlock control{};
IOUserAudioDevice audioDevice{};
std::array<int32_t, 16> input{};
std::array<float, 16> input{};
std::array<float, 16> output{};
FireWireAudioEngine engine{};

Expand All @@ -126,7 +126,7 @@ TEST(DirectAudioEngineTests, OutputReaderUsesPlaybackRingCursorAvailability) {
TEST(DirectAudioEngineTests, OutputReaderRejectsOverflowingFrameRange) {
AudioTransportControlBlock control{};
IOUserAudioDevice audioDevice{};
std::array<int32_t, 16> input{};
std::array<float, 16> input{};
std::array<float, 16> output{};
FireWireAudioEngine engine{};

Expand Down
Loading
Loading