Midi handling in the Dummy Audio driver.

This commit is contained in:
Robin E. R. Davies
2025-06-29 08:30:26 -04:00
parent a81056a657
commit 03cb18e065
4 changed files with 72 additions and 15 deletions
+7
View File
@@ -244,6 +244,13 @@ namespace pipedal
// convert rc to message // convert rc to message
throw std::runtime_error(SS("Failed to open ALSA sequencer:" << snd_strerror(rc))); 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"); snd_seq_set_client_name(seqHandle, "PiPedal");
inPort = snd_seq_create_simple_port(seqHandle, "PiPedal:in", inPort = snd_seq_create_simple_port(seqHandle, "PiPedal:in",
+4 -8
View File
@@ -303,12 +303,8 @@ namespace pipedal
: driverHost(driverHost) : driverHost(driverHost)
{ {
midiEventMemoryIndex = 0; midiEventMemoryIndex = 0;
midiEventMemory.resize(MAX_MIDI_EVENT * MAX_MIDI_EVENT_SIZE); midiEventMemory.resize(MIDI_MEMORY_BUFFER_SIZE);
midiEvents.resize(MAX_MIDI_EVENT); 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() virtual ~AlsaDriverImpl()
{ {
@@ -1522,7 +1518,7 @@ namespace pipedal
} while (frames > 0); } while (frames > 0);
return framesRead; return framesRead;
} }
protected:
void ReadMidiData(uint32_t audioFrame) void ReadMidiData(uint32_t audioFrame)
{ {
AlsaMidiMessage message; AlsaMidiMessage message;
@@ -1558,6 +1554,7 @@ namespace pipedal
} }
} }
private:
long WriteBuffer(snd_pcm_t *handle, uint8_t *buf, size_t frames) long WriteBuffer(snd_pcm_t *handle, uint8_t *buf, size_t frames)
{ {
@@ -1782,8 +1779,7 @@ namespace pipedal
Lv2Log::debug("Audio thread joined."); Lv2Log::debug("Audio thread joined.");
} }
static constexpr size_t MAX_MIDI_EVENT_SIZE = 3; static constexpr size_t MIDI_MEMORY_BUFFER_SIZE = 32 * 1024;
static constexpr size_t MIDI_BUFFER_SIZE = 16 * 1024;
static constexpr size_t MAX_MIDI_EVENT = 4 * 1024; static constexpr size_t MAX_MIDI_EVENT = 4 * 1024;
size_t midiEventCount = 0; size_t midiEventCount = 0;
+60 -6
View File
@@ -104,6 +104,11 @@ namespace pipedal
captureChannels = channels; captureChannels = channels;
playbackChannels = channels; playbackChannels = channels;
midiEventMemoryIndex = 0;
midiEventMemory.resize(MIDI_MEMORY_BUFFER_SIZE);
midiEvents.resize(MAX_MIDI_EVENT);
} }
virtual ~DummyDriverImpl() virtual ~DummyDriverImpl()
{ {
@@ -124,6 +129,15 @@ namespace pipedal
JackServerSettings jackServerSettings; JackServerSettings jackServerSettings;
AlsaSequencer::ptr alsaSequencer; 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<MidiEvent> midiEvents;
size_t midiEventMemoryIndex = 0;
std::vector<uint8_t> midiEventMemory;
unsigned int periods = 0; unsigned int periods = 0;
@@ -159,11 +173,13 @@ namespace pipedal
} }
} }
virtual size_t GetMidiInputEventCount() override { virtual size_t GetMidiInputEventCount() override
return 0; {
return midiEventCount;
} }
virtual MidiEvent*GetMidiEvents() { virtual MidiEvent *GetMidiEvents() override
return nullptr; {
return this->midiEvents.data();
} }
@@ -224,6 +240,43 @@ namespace pipedal
bool block = false; 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() void AudioThread()
{ {
SetThreadName("dummyAudioDriver"); SetThreadName("dummyAudioDriver");
@@ -236,11 +289,14 @@ namespace pipedal
while (true) while (true)
{ {
if (terminateAudio()) if (terminateAudio())
{ {
break; break;
} }
ReadMidiData((uint32_t)0);
ssize_t framesRead = this->bufferSize; ssize_t framesRead = this->bufferSize;
this->driverHost->OnProcess(framesRead); this->driverHost->OnProcess(framesRead);
@@ -340,8 +396,6 @@ namespace pipedal
Lv2Log::debug("Audio thread joined."); Lv2Log::debug("Audio thread joined.");
} }
static constexpr size_t MIDI_BUFFER_SIZE = 16 * 1024;
static constexpr size_t MAX_MIDI_EVENT = 4 * 1024;
public: public:
+1 -1
View File
@@ -1,4 +1,4 @@
Route the midi connections. VU decay on a timer.
Midi handling in the dummy audio connector. Midi handling in the dummy audio connector.