From 03cb18e0655acc70fcd8c8c7e3637c84ae36d01e Mon Sep 17 00:00:00 2001 From: "Robin E. R. Davies" Date: Sun, 29 Jun 2025 08:30:26 -0400 Subject: [PATCH] Midi handling in the Dummy Audio driver. --- PiPedalCommon/src/AlsaSequencer.cpp | 7 +++ src/AlsaDriver.cpp | 12 ++---- src/DummyAudioDriver.cpp | 66 ++++++++++++++++++++++++++--- todo.txt | 2 +- 4 files changed, 72 insertions(+), 15 deletions(-) diff --git a/PiPedalCommon/src/AlsaSequencer.cpp b/PiPedalCommon/src/AlsaSequencer.cpp index d3d5afd..71a636d 100644 --- a/PiPedalCommon/src/AlsaSequencer.cpp +++ b/PiPedalCommon/src/AlsaSequencer.cpp @@ -244,6 +244,13 @@ namespace pipedal // convert rc to message throw std::runtime_error(SS("Failed to open ALSA sequencer:" << snd_strerror(rc))); } + size_t inputBufferSize = snd_seq_get_input_buffer_size(seqHandle); + (void)inputBufferSize; + + rc = snd_seq_set_input_buffer_size(seqHandle, 128*1024); + if (rc < 0) { + Lv2Log::warning("Failed resize the ALSA sequencer input buffer: %s",snd_strerror(rc)); + } snd_seq_set_client_name(seqHandle, "PiPedal"); inPort = snd_seq_create_simple_port(seqHandle, "PiPedal:in", diff --git a/src/AlsaDriver.cpp b/src/AlsaDriver.cpp index feb108e..5df7144 100644 --- a/src/AlsaDriver.cpp +++ b/src/AlsaDriver.cpp @@ -303,12 +303,8 @@ namespace pipedal : driverHost(driverHost) { midiEventMemoryIndex = 0; - midiEventMemory.resize(MAX_MIDI_EVENT * MAX_MIDI_EVENT_SIZE); + midiEventMemory.resize(MIDI_MEMORY_BUFFER_SIZE); midiEvents.resize(MAX_MIDI_EVENT); - for (size_t i = 0; i < midiEvents.size(); ++i) - { - midiEvents[i].buffer = midiEventMemory.data() + i * MAX_MIDI_EVENT_SIZE; - } } virtual ~AlsaDriverImpl() { @@ -1522,7 +1518,7 @@ namespace pipedal } while (frames > 0); return framesRead; } - + protected: void ReadMidiData(uint32_t audioFrame) { AlsaMidiMessage message; @@ -1558,6 +1554,7 @@ namespace pipedal } } + private: long WriteBuffer(snd_pcm_t *handle, uint8_t *buf, size_t frames) { @@ -1782,8 +1779,7 @@ namespace pipedal Lv2Log::debug("Audio thread joined."); } - static constexpr size_t MAX_MIDI_EVENT_SIZE = 3; - static constexpr size_t MIDI_BUFFER_SIZE = 16 * 1024; + static constexpr size_t MIDI_MEMORY_BUFFER_SIZE = 32 * 1024; static constexpr size_t MAX_MIDI_EVENT = 4 * 1024; size_t midiEventCount = 0; diff --git a/src/DummyAudioDriver.cpp b/src/DummyAudioDriver.cpp index 88848a5..37b25bb 100644 --- a/src/DummyAudioDriver.cpp +++ b/src/DummyAudioDriver.cpp @@ -104,6 +104,11 @@ namespace pipedal captureChannels = channels; playbackChannels = channels; + midiEventMemoryIndex = 0; + midiEventMemory.resize(MIDI_MEMORY_BUFFER_SIZE); + midiEvents.resize(MAX_MIDI_EVENT); + + } virtual ~DummyDriverImpl() { @@ -124,6 +129,15 @@ namespace pipedal JackServerSettings jackServerSettings; AlsaSequencer::ptr alsaSequencer; + static constexpr size_t MIDI_MEMORY_BUFFER_SIZE = 32 * 1024; + static constexpr size_t MAX_MIDI_EVENT = 4 * 1024; + + size_t midiEventCount = 0; + std::vector midiEvents; + size_t midiEventMemoryIndex = 0; + std::vector midiEventMemory; + + unsigned int periods = 0; @@ -159,11 +173,13 @@ namespace pipedal } } - virtual size_t GetMidiInputEventCount() override { - return 0; + virtual size_t GetMidiInputEventCount() override + { + return midiEventCount; } - virtual MidiEvent*GetMidiEvents() { - return nullptr; + virtual MidiEvent *GetMidiEvents() override + { + return this->midiEvents.data(); } @@ -224,6 +240,43 @@ namespace pipedal bool block = false; + void ReadMidiData(uint32_t audioFrame) + { + AlsaMidiMessage message; + + midiEventCount = 0; + while(alsaSequencer->ReadMessage(message,0)) + { + size_t messageSize = message.size; + if (messageSize == 0) + { + continue; + } + if (midiEventMemoryIndex + messageSize >= this->midiEventMemory.size()) { + continue; + } + if (midiEventCount >= this->midiEvents.size()) { + midiEvents.resize(midiEventCount*2); + } + // for now, prevent META event messages from propagating. + if (message.data[0] == 0xFF && message.size > 1) { + continue; + } + MidiEvent *pEvent = midiEvents.data() + midiEventCount++; + pEvent->time = audioFrame; + pEvent->size = messageSize; + pEvent->buffer = midiEventMemory.data() + midiEventMemoryIndex; + + memcpy( + midiEventMemory.data() + midiEventMemoryIndex, + message.data, + message.size); + midiEventMemoryIndex += messageSize; + + } + } + + void AudioThread() { SetThreadName("dummyAudioDriver"); @@ -236,11 +289,14 @@ namespace pipedal while (true) { + if (terminateAudio()) { break; } + ReadMidiData((uint32_t)0); + ssize_t framesRead = this->bufferSize; this->driverHost->OnProcess(framesRead); @@ -340,8 +396,6 @@ namespace pipedal Lv2Log::debug("Audio thread joined."); } - static constexpr size_t MIDI_BUFFER_SIZE = 16 * 1024; - static constexpr size_t MAX_MIDI_EVENT = 4 * 1024; public: diff --git a/todo.txt b/todo.txt index f3ed0a6..354eb88 100644 --- a/todo.txt +++ b/todo.txt @@ -1,4 +1,4 @@ -Route the midi connections. +VU decay on a timer. Midi handling in the dummy audio connector.