Skip to content

Commit

Permalink
Merge branch 'model-refactor'
Browse files Browse the repository at this point in the history
  • Loading branch information
gvnnz committed Mar 31, 2024
2 parents ca1965d + bf9c28d commit 291e30f
Show file tree
Hide file tree
Showing 37 changed files with 981 additions and 546 deletions.
4 changes: 4 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,10 @@ list(APPEND SOURCES
src/core/channels/midiChannel.cpp
src/core/channels/channelShared.cpp
src/core/channels/channelFactory.cpp
src/core/model/document.cpp
src/core/model/loadState.cpp
src/core/model/sharedLock.cpp
src/core/model/shared.cpp
src/core/model/sequencer.cpp
src/core/model/mixer.cpp
src/core/model/model.cpp
Expand Down
1 change: 1 addition & 0 deletions src/core/api/configApi.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#define G_CONFIG_API_H

#include "core/kernelAudio.h"
#include "core/kernelMidi.h"
#include <vector>

namespace giada::m::model
Expand Down
18 changes: 9 additions & 9 deletions src/core/api/sampleEditorApi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ void SampleEditorApi::setPreviewTracker(Frame f)
void SampleEditorApi::cut(ID channelId, Frame a, Frame b)
{
copy(channelId, a, b);
model::DataLock lock = m_model.lockData();
model::SharedLock lock = m_model.lockShared();
wfx::cut(getWave(channelId), a, b);
resetBeginEnd(channelId);
loadPreviewChannel(channelId); // Refresh preview channel properties
Expand Down Expand Up @@ -100,7 +100,7 @@ void SampleEditorApi::paste(ID channelId, Frame a)
/* Temporary disable wave reading in channel. From now on, the audio
thread won't be reading any wave, so editing it is safe. */

model::DataLock lock = m_model.lockData();
model::SharedLock lock = m_model.lockShared();

/* Paste copied data to destination wave. */

Expand All @@ -120,47 +120,47 @@ void SampleEditorApi::paste(ID channelId, Frame a)

void SampleEditorApi::silence(ID channelId, Frame a, Frame b)
{
model::DataLock lock = m_model.lockData();
model::SharedLock lock = m_model.lockShared();
wfx::silence(getWave(channelId), a, b);
}

/* -------------------------------------------------------------------------- */

void SampleEditorApi::fade(ID channelId, Frame a, Frame b, wfx::Fade type)
{
model::DataLock lock = m_model.lockData();
model::SharedLock lock = m_model.lockShared();
wfx::fade(getWave(channelId), a, b, type);
}

/* -------------------------------------------------------------------------- */

void SampleEditorApi::smoothEdges(ID channelId, Frame a, Frame b)
{
model::DataLock lock = m_model.lockData();
model::SharedLock lock = m_model.lockShared();
wfx::smooth(getWave(channelId), a, b);
}

/* -------------------------------------------------------------------------- */

void SampleEditorApi::reverse(ID channelId, Frame a, Frame b)
{
model::DataLock lock = m_model.lockData();
model::SharedLock lock = m_model.lockShared();
wfx::reverse(getWave(channelId), a, b);
}

/* -------------------------------------------------------------------------- */

void SampleEditorApi::normalize(ID channelId, Frame a, Frame b)
{
model::DataLock lock = m_model.lockData();
model::SharedLock lock = m_model.lockShared();
wfx::normalize(getWave(channelId), a, b);
}

/* -------------------------------------------------------------------------- */

void SampleEditorApi::trim(ID channelId, Frame a, Frame b)
{
model::DataLock lock = m_model.lockData();
model::SharedLock lock = m_model.lockShared();
wfx::trim(getWave(channelId), a, b);
resetBeginEnd(channelId);
loadPreviewChannel(channelId); // Refresh preview channel properties
Expand All @@ -173,7 +173,7 @@ void SampleEditorApi::shift(ID channelId, Frame offset)
const Channel& ch = m_channelManager.getChannel(channelId);
const Frame oldShift = ch.sampleChannel->shift;

m::model::DataLock lock = m_model.lockData();
m::model::SharedLock lock = m_model.lockShared();
m::wfx::shift(getWave(channelId), offset - oldShift);
// Model has been swapped by DataLock constructor, needs to get Channel again
m_channelManager.getChannel(channelId).sampleChannel->shift = offset;
Expand Down
25 changes: 15 additions & 10 deletions src/core/channels/channelFactory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,14 @@ IdManager channelId_;

/* -------------------------------------------------------------------------- */

std::unique_ptr<ChannelShared> makeShared_(ChannelType type, int bufferSize, Resampler::Quality quality)
std::unique_ptr<ChannelShared> makeShared_(ChannelType type, ID channelId, int bufferSize, Resampler::Quality quality)
{
std::unique_ptr<ChannelShared> shared = std::make_unique<ChannelShared>(bufferSize);
std::unique_ptr<ChannelShared> shared = std::make_unique<ChannelShared>(channelId, bufferSize);

if (type == ChannelType::SAMPLE || type == ChannelType::PREVIEW)
{
shared->quantizer.emplace();
shared->renderQueue.emplace();
shared->renderQueue.emplace(/*size=*/2, 0, /*num_threads=*/2);
shared->resampler.emplace(quality, G_MAX_IO_CHANS);
}

Expand Down Expand Up @@ -79,8 +79,10 @@ void reset()

Data create(ID channelId, ChannelType type, int bufferSize, Resampler::Quality quality, bool overdubProtection)
{
std::unique_ptr<ChannelShared> shared = makeShared_(type, bufferSize, quality);
Channel ch = Channel(type, channelId_.generate(channelId), *shared.get());
channelId = channelId_.generate(channelId);

std::unique_ptr<ChannelShared> shared = makeShared_(type, channelId, bufferSize, quality);
Channel ch = Channel(type, channelId, *shared.get());

if (ch.sampleChannel)
ch.sampleChannel->overdubProtection = overdubProtection;
Expand All @@ -92,7 +94,7 @@ Data create(ID channelId, ChannelType type, int bufferSize, Resampler::Quality q

Data create(const Channel& o, int bufferSize, Resampler::Quality quality)
{
std::unique_ptr<ChannelShared> shared = makeShared_(o.type, bufferSize, quality);
std::unique_ptr<ChannelShared> shared = makeShared_(o.type, o.id, bufferSize, quality);
Channel ch = Channel(o);

ch.id = channelId_.generate();
Expand All @@ -103,14 +105,17 @@ Data create(const Channel& o, int bufferSize, Resampler::Quality quality)

/* -------------------------------------------------------------------------- */

Data deserializeChannel(const Patch::Channel& pch, float samplerateRatio, int bufferSize, Resampler::Quality quality, Wave* wave, std::vector<Plugin*> plugins)
Channel deserializeChannel(const Patch::Channel& pch, ChannelShared& shared, float samplerateRatio, Wave* wave, std::vector<Plugin*> plugins)
{
channelId_.set(pch.id);
return Channel(pch, shared, samplerateRatio, wave, plugins);
}

std::unique_ptr<ChannelShared> shared = makeShared_(pch.type, bufferSize, quality);
Channel ch = Channel(pch, *shared.get(), samplerateRatio, wave, plugins);
/* -------------------------------------------------------------------------- */

return {ch, std::move(shared)};
std::unique_ptr<ChannelShared> deserializeShared(const Patch::Channel& pch, int bufferSize, Resampler::Quality quality)
{
return makeShared_(pch.type, pch.id, bufferSize, quality);
}

/* -------------------------------------------------------------------------- */
Expand Down
12 changes: 9 additions & 3 deletions src/core/channels/channelFactory.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,17 @@ Data create(ID channelId, ChannelType type, int bufferSize, Resampler::Quality,

Data create(const Channel& ch, int bufferSize, Resampler::Quality);

/* (de)serializeWave
Creates a new channel given the patch raw data and vice versa. */
/* (de)deserializeChannel
Creates a new channel given the patch raw data and vice versa. */

Data deserializeChannel(const Patch::Channel& c, float samplerateRatio, int bufferSize, Resampler::Quality, Wave*, std::vector<Plugin*>);
Channel deserializeChannel(const Patch::Channel& c, ChannelShared&, float samplerateRatio, Wave*, std::vector<Plugin*>);
const Patch::Channel serializeChannel(const Channel& c);

/* deserializeShared
Returns a new ChannelShared object to be passed to deserializeChannel() above. */

std::unique_ptr<ChannelShared> deserializeShared(const Patch::Channel&, int bufferSize, Resampler::Quality);

} // namespace giada::m::channelFactory

#endif
6 changes: 3 additions & 3 deletions src/core/channels/channelManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ void ChannelManager::loadSampleChannel(ID channelId, Wave& wave)
m_model.swap(model::SwapType::HARD);

/* Remove the old Wave, if any. It is safe to do it now: the audio thread is
already processing the new layout. */
already processing the new Document. */

if (oldWave != nullptr)
m_model.removeWave(*oldWave);
Expand Down Expand Up @@ -435,7 +435,7 @@ bool ChannelManager::saveSample(ID channelId, const std::string& filePath)

/* Reset logical and edited states in Wave. */

model::DataLock lock = m_model.lockData();
model::SharedLock lock = m_model.lockShared();
wave->setLogical(false);
wave->setEdited(false);

Expand Down Expand Up @@ -571,7 +571,7 @@ void ChannelManager::overdubChannel(Channel& ch, const mcl::AudioBuffer& buffer,
/* Need model::DataLock here, as data might be being read by the audio
thread at the same time. */

model::DataLock lock = m_model.lockData();
model::SharedLock lock = m_model.lockShared();

wave->getBuffer().sum(buffer, /*gain=*/1.0f);
wave->setLogical(true);
Expand Down
5 changes: 3 additions & 2 deletions src/core/channels/channelShared.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,9 @@

namespace giada::m
{
ChannelShared::ChannelShared(Frame bufferSize)
: audioBuffer(bufferSize, G_MAX_IO_CHANS)
ChannelShared::ChannelShared(ID id, Frame bufferSize)
: id(id)
, audioBuffer(bufferSize, G_MAX_IO_CHANS)
{
}

Expand Down
12 changes: 7 additions & 5 deletions src/core/channels/channelShared.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@
#include "core/const.h"
#include "core/midiEvent.h"
#include "core/quantizer.h"
#include "core/queue.h"
#include "core/rendering/sampleRendering.h"
#include "core/resampler.h"
#include "deps/concurrentqueue/concurrentqueue.h"
#include "deps/mcl-audio-buffer/src/audioBuffer.hpp"
#include <juce_audio_basics/juce_audio_basics.h>
#include <optional>
Expand All @@ -41,10 +41,10 @@ namespace giada::m
{
struct ChannelShared final
{
using MidiQueue = Queue<MidiEvent, 32>; // TODO - must be multi-producer (multiple midi threads)
using RenderQueue = Queue<rendering::RenderInfo, 2>;
using MidiQueue = moodycamel::ConcurrentQueue<MidiEvent>;
using RenderQueue = moodycamel::ConcurrentQueue<rendering::RenderInfo>;

ChannelShared(Frame bufferSize);
ChannelShared(ID, Frame bufferSize);

bool isReadingActions() const;

Expand All @@ -53,9 +53,11 @@ struct ChannelShared final

void setBufferSize(int);

ID id; // Must match the corresponding Channel ID

mcl::AudioBuffer audioBuffer;
juce::MidiBuffer midiBuffer;
MidiQueue midiQueue;
MidiQueue midiQueue{/*size=*/32, 0, /*num_threads=*/8}; // TODO - maximum 8 MIDI threads for now

WeakAtomic<Frame> tracker = 0;
WeakAtomic<ChannelStatus> playStatus = ChannelStatus::OFF;
Expand Down
4 changes: 2 additions & 2 deletions src/core/engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ void Engine::init(const Conf& conf)
m_model.init();
m_model.load(conf);

const model::Layout& layout = m_model.get();
const model::Document& document = m_model.get();

m_kernelAudio.init();

Expand All @@ -245,7 +245,7 @@ void Engine::init(const Conf& conf)
m_kernelMidi.start();

m_midiMapper.init();
m_midiMapper.read(layout.kernelMidi.midiMapPath);
m_midiMapper.read(document.kernelMidi.midiMapPath);
m_midiMapper.sendInitMessages();

m_eventDispatcher.start();
Expand Down
4 changes: 2 additions & 2 deletions src/core/midiDispatcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -407,8 +407,8 @@ void MidiDispatcher::learnMaster(MidiEvent e, int param, std::function<void()> d

void MidiDispatcher::learnPlugin(MidiEvent e, std::size_t paramIndex, ID pluginId, std::function<void()> doneCb)
{
model::DataLock lock = m_model.lockData(model::SwapType::NONE);
Plugin* plugin = m_model.findPlugin(pluginId);
model::SharedLock lock = m_model.lockShared(model::SwapType::NONE);
Plugin* plugin = m_model.findPlugin(pluginId);

assert(plugin != nullptr);
assert(paramIndex < plugin->midiInParams.size());
Expand Down
12 changes: 6 additions & 6 deletions src/core/mixer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ void Mixer::enable()
void Mixer::disable()
{
m_model.get().mixer.a_setActive(false);
while (m_model.isLocked())
while (m_model.isRtLocked())
;
u::log::print("[mixer::disable] disabled\n");
}
Expand Down Expand Up @@ -133,12 +133,12 @@ void Mixer::setInputRecMode(InputRecMode m)

/* -------------------------------------------------------------------------- */

void Mixer::render(const mcl::AudioBuffer& in, const model::Layout& layout_RT, int maxFramesToRec) const
void Mixer::render(const mcl::AudioBuffer& in, const model::Document& document_RT, int maxFramesToRec) const
{
const model::Mixer& mixer = layout_RT.mixer;
const model::Sequencer& sequencer = layout_RT.sequencer;
const model::Channels& channels = layout_RT.channels;
const model::KernelAudio& kernelAudio = layout_RT.kernelAudio;
const model::Mixer& mixer = document_RT.mixer;
const model::Sequencer& sequencer = document_RT.sequencer;
const model::Channels& channels = document_RT.channels;
const model::KernelAudio& kernelAudio = document_RT.kernelAudio;

const Channel& masterInCh = channels.get(Mixer::MASTER_IN_CHANNEL_ID);

Expand Down
5 changes: 2 additions & 3 deletions src/core/mixer.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
#define G_MIXER_H

#include "core/midiEvent.h"
#include "core/queue.h"
#include "core/ringBuffer.h"
#include "core/sequencer.h"
#include "core/types.h"
Expand All @@ -45,7 +44,7 @@ namespace giada::m::model
{
class Mixer;
class Channels;
struct Layout;
struct Document;
} // namespace giada::m::model

namespace giada::m
Expand Down Expand Up @@ -88,7 +87,7 @@ class Mixer
/* render
Core rendering function. */

void render(const mcl::AudioBuffer& in, const model::Layout&, int maxFramesToRec) const;
void render(const mcl::AudioBuffer& in, const model::Document&, int maxFramesToRec) const;

/* reset
Brings everything back to the initial state. Must be called only when mixer
Expand Down
Loading

0 comments on commit 291e30f

Please sign in to comment.