Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
394b4e2
Initial changes for migration to juce 8
jthorborg Jun 8, 2025
04a8833
WIP work on preset manager, since juce no longer supports modal dialogs.
jthorborg Jun 8, 2025
ddadef2
port to arm64
Jul 29, 2025
16345e1
optimise arm64 load time
Jul 30, 2025
7350c02
Apply suggestions from code review
mtrin Sep 13, 2025
3233c2e
Fixed CPresetManager / CPresetWidget to operate correctly under async…
jthorborg Dec 30, 2025
e70354f
Fix up initial ARM simd support shenanigans
jthorborg Dec 30, 2025
5c31de5
Various compilation fixes on macos
jthorborg Dec 30, 2025
dfc227d
Use native simd headers on windows
jthorborg Dec 31, 2025
37ce295
Merge pull request #2 from jthorborg/dev/juce-8-arm-support
jthorborg Dec 31, 2025
6d5c641
Round 1 of C++17 warnings
jthorborg Dec 31, 2025
842d42b
Further fixes of int <> float warnings
jthorborg Jan 2, 2026
d83155d
Fixed bug in lanczos interpolation constants
jthorborg Jan 2, 2026
c510841
Fix assertions related to grabbing keyboard focus on edit spaces.
jthorborg Jan 3, 2026
9e7d77f
Fixed edit spaces not animating success/error after pressing enter (n…
jthorborg Jan 3, 2026
446a6ab
Various warnings and fixes for clang.
jthorborg Jan 11, 2026
91d0a67
Functioning CProcessorTimer on arm
jthorborg Jan 11, 2026
8d8a394
Swathe of compilation fixes to minimize platform inclusion
jthorborg Jan 12, 2026
78d74f0
Revert to emulated file selector on macos
jthorborg Jan 12, 2026
42548a2
Initial working compilation on gcc/ubuntu24
jthorborg Jan 15, 2026
aea066a
Compilation support on Windows
jthorborg Jan 16, 2026
20459fb
Make it possible for the AudioStream to transactionally commit many c…
jthorborg Jan 17, 2026
7a025f8
Fixed colour selectors not showing up
jthorborg Jan 19, 2026
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
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,6 @@
[submodule "external/filesystem"]
path = external/filesystem
url = https://github.com/gulrak/filesystem
[submodule "external/simde"]
path = external/simde
url = https://github.com/simd-everywhere/simde
2 changes: 1 addition & 1 deletion AudioStream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ namespace cpl

janitorThreads();

CPL_RUNTIME_ASSERTION(threads.size() == 0);
CPL_RUNTIME_ASSERTION(threads.size() == 0); // TODO: This can happen and hang the process.
}

private:
Expand Down
143 changes: 79 additions & 64 deletions AudioStream.h
Original file line number Diff line number Diff line change
Expand Up @@ -537,40 +537,14 @@ namespace cpl
protected:
std::shared_ptr<StreamType> stream;
Reference() = default;
Reference(Reference&& ref)
Reference(Reference&& ref) noexcept
: stream(std::move(ref.stream))
{
}
public:
Handle getHandle() const noexcept { return { stream.get() }; }
};

struct ExclusiveDebugScope
{
ExclusiveDebugScope(std::atomic_flag& flag)
: flag(flag)
{
if (flag.test_and_set(std::memory_order_release))
{
flag.clear();
CPL_RUNTIME_EXCEPTION("Re-entrancy / concurrency detected in audio stream producer");
}
}

~ExclusiveDebugScope() noexcept(false)
{
// TODO: use test() in C++20
if (!flag.test_and_set(std::memory_order_release))
{
CPL_RUNTIME_EXCEPTION("Re-entrancy / concurrency detected in audio stream producer");
}

flag.clear();
}

std::atomic_flag& flag;
};

class Output final : public Reference
{
public:
Expand Down Expand Up @@ -704,8 +678,33 @@ namespace cpl

struct FrameBatch
{
FrameBatch(std::shared_ptr<Output>&& out)
: output(std::move(out)), stream(nullptr)
{
if (output)
output->beginFrameProcessing();
}

bool submitFrame(ProducerFrame&& frame)
{
if (output)
output->handleFrame(std::move(frame));
else if(stream)
return stream->publishFrame(std::move(frame));

return true;
}

~FrameBatch()
{
if (output)
output->endFrameProcessing();
}

protected:

template <typename Other>
bool hasContents(const std::weak_ptr<Other>& w)
static bool hasContents(const std::weak_ptr<Other>& w)
{
return w.owner_before(std::weak_ptr<Other>{}) || std::weak_ptr<Other>{}.owner_before(w);
}
Expand All @@ -724,36 +723,54 @@ namespace cpl
}
}

FrameBatch(std::shared_ptr<Output>&& out)
: output(std::move(out)), stream(nullptr)
private:

AudioStream* stream;
std::shared_ptr<Output> output;
};

struct ExclusiveDebugScope
{
ExclusiveDebugScope(std::atomic_flag& flag)
: flag(flag)
{
if (output)
output->beginFrameProcessing();
if (flag.test_and_set(std::memory_order_release))
{
flag.clear();
CPL_RUNTIME_EXCEPTION("Re-entrancy / concurrency detected in audio stream producer");
}
}

bool submitFrame(ProducerFrame&& frame)
~ExclusiveDebugScope() noexcept(false)
{
if (output)
output->handleFrame(std::move(frame));
else if(stream)
return stream->publishFrame(std::move(frame));
// TODO: use test() in C++20
if (!flag.test_and_set(std::memory_order_release))
{
CPL_RUNTIME_EXCEPTION("Re-entrancy / concurrency detected in audio stream producer");
}

return true;
flag.clear();
}

~FrameBatch()
{
if (output)
output->endFrameProcessing();
}
std::atomic_flag& flag;
};

AudioStream* stream;
std::shared_ptr<Output> output;
class Input;

struct InputFrameBatch : public FrameBatch
{
InputFrameBatch(Input& input);

private:

ExclusiveDebugScope debugScope;
};

class Input final : public Reference
{
friend class AudioStream<T, PacketSize>;
friend struct InputFrameBatch;

public:
#ifdef CPL_JUCE
void processIncomingRTAudio(const T* const * buffer, std::size_t numChannels, std::size_t numSamples, juce::AudioPlayHead& ph)
Expand All @@ -766,15 +783,15 @@ namespace cpl
void processIncomingRTAudio(const T* const * buffer, std::size_t numChannels, std::size_t numSamples, const Playhead& ph);

/// <summary>
/// Returns the playhead for the system.
/// Only valid to call and read, while you're inside a
/// real time callback.
/// This must be called at least once, before streaming starts.
/// It is not safe to call this function concurrently
/// - decide on one thread, controlling it.
/// </summary>
const Playhead& getPlayhead() const noexcept
template<typename ModifierFunc>
void initializeInfo(ModifierFunc&& func, InputFrameBatch& batch)
{
ExclusiveDebugScope scope(reentrancy);

return playhead;
func(internalInfo);
batch.submitFrame(ProducerFrame(internalInfo));
}

/// <summary>
Expand All @@ -785,24 +802,24 @@ namespace cpl
template<typename ModifierFunc>
void initializeInfo(ModifierFunc&& func)
{
ExclusiveDebugScope scope(reentrancy);

func(internalInfo);
FrameBatch batch(*this->stream);
batch.submitFrame(ProducerFrame(internalInfo));
InputFrameBatch batch(*this);
initializeInfo(std::move(func), batch);
}

void enqueueChannelName(std::size_t index, std::string&& name)
void enqueueChannelName(std::size_t index, std::string&& name, InputFrameBatch& batch)
{
ExclusiveDebugScope scope(reentrancy);

ProducerFrame frame;
frame.template emplace<ChannelNameData>(ChannelNameData{ index, std::move(name) });

FrameBatch batch(*this->stream);
batch.submitFrame(std::move(frame));
}

void enqueueChannelName(std::size_t index, std::string&& name)
{
InputFrameBatch batch(*this);
enqueueChannelName(index, std::move(name), batch);
}

/// <summary>
/// Checks to see if there currently is anyone listening to the output.
/// If not, you're free to skip calling <see cref="processIncomingRTAudio"/>
Expand Down Expand Up @@ -955,9 +972,7 @@ namespace cpl
input.stream = stream;
output->stream = std::move(stream);

auto ret = std::make_tuple(std::move(input), std::move(output));

return std::move(ret);
return std::make_tuple(std::move(input), std::move(output));
}

private:
Expand Down
11 changes: 8 additions & 3 deletions AudioStream.inl
Original file line number Diff line number Diff line change
Expand Up @@ -329,16 +329,21 @@ namespace cpl
}

template<typename T, std::size_t PacketSize>
inline void AudioStream<T, PacketSize>::Input::processIncomingRTAudio(const T* const* buffer, std::size_t numChannels, std::size_t numSamples, const AudioStream<T, PacketSize>::Playhead& ph)
inline AudioStream<T, PacketSize>::InputFrameBatch::InputFrameBatch(Input& input)
: FrameBatch(*input.stream), debugScope(input.reentrancy)
{
ExclusiveDebugScope scope(reentrancy);
}


template<typename T, std::size_t PacketSize>
inline void AudioStream<T, PacketSize>::Input::processIncomingRTAudio(const T* const* buffer, std::size_t numChannels, std::size_t numSamples, const AudioStream<T, PacketSize>::Playhead& ph)
{
if (internalInfo.isSuspended)
return;

CPL_RUNTIME_ASSERTION(numChannels == internalInfo.channels);

FrameBatch batch(*this->stream);
InputFrameBatch batch(*this);

cpl::CProcessorTimer overhead, all;
overhead.start(); all.start();
Expand Down
6 changes: 3 additions & 3 deletions CPLSource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,11 @@
#include "MacroConstants.h"
#include "LibraryOptions.h"

#include "Common.h"
#include "PlatformSpecific.h"
#include "simd/simd_consts.cpp"

#ifdef CPL_JUCE
#include "rendering/CDisplaySetup.cpp"

#include "Resources.cpp"
//#include "fonts/tahoma.cpp"
Expand All @@ -43,7 +44,6 @@
#include "gui/GUI.cpp"
// rendering
#include "rendering/CSubpixelSoftwareGraphics.cpp"
#include "rendering/CDisplaySetup.cpp"

// io and stuff

Expand Down Expand Up @@ -80,4 +80,4 @@
#if !defined(CPL_LEAN)
#include "CPLTests.cpp"
#endif
*/
*/
Loading