mirror of https://github.com/probonopd/MiniDexed
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
169 lines
4.3 KiB
169 lines
4.3 KiB
9 months ago
|
#include "midi_arp.h"
|
||
|
#include <stdio.h>
|
||
|
|
||
9 months ago
|
MidiArp::MidiArp(float32_t samplerate, CDexedAdapter* synth) : MidiEffect(samplerate, synth)
|
||
9 months ago
|
{
|
||
|
arpeggiator.transmitHostInfo(0, 4, 1, 1, 120.0);
|
||
|
arpeggiator.setSampleRate(samplerate);
|
||
9 months ago
|
|
||
9 months ago
|
arpeggiator.setBpm(120);
|
||
9 months ago
|
|
||
|
this->setParameter(MidiArp::Param::LATCH, 0);
|
||
|
this->setParameter(MidiArp::Param::ARP_MODE, 0);
|
||
|
this->setParameter(MidiArp::Param::DIVISION, 9);
|
||
|
this->setParameter(MidiArp::Param::NOTE_LENGTH, 70);
|
||
|
this->setParameter(MidiArp::Param::VELOCITY, 110);
|
||
|
this->setParameter(MidiArp::Param::OCTAVE_SPREAD, 1);
|
||
|
this->setParameter(MidiArp::Param::OCTAVE_MODE, 4);
|
||
9 months ago
|
}
|
||
|
|
||
|
MidiArp::~MidiArp()
|
||
|
{
|
||
|
}
|
||
|
|
||
9 months ago
|
void MidiArp::setTempo(unsigned tempo)
|
||
|
{
|
||
|
arpeggiator.setBpm(tempo);
|
||
|
}
|
||
|
|
||
|
void MidiArp::setParameter(unsigned param, unsigned value)
|
||
|
{
|
||
|
switch (param)
|
||
|
{
|
||
|
case MidiArp::Param::BYPASS:
|
||
|
this->setBypass(value == 1);
|
||
|
break;
|
||
|
case MidiArp::Param::LATCH:
|
||
|
this->arpeggiator.setLatchMode(value == 1);
|
||
|
break;
|
||
|
case MidiArp::Param::SYNC:
|
||
|
this->arpeggiator.setSyncMode(value);
|
||
|
break;
|
||
|
case MidiArp::Param::ARP_MODE:
|
||
|
this->arpeggiator.setArpMode(value);
|
||
|
break;
|
||
|
case MidiArp::Param::DIVISION:
|
||
|
this->arpeggiator.setDivision(value);
|
||
|
break;
|
||
|
case MidiArp::Param::NOTE_LENGTH:
|
||
9 months ago
|
this->arpeggiator.setNoteLength((float) value / 100.0f);
|
||
9 months ago
|
break;
|
||
|
case MidiArp::Param::VELOCITY:
|
||
|
this->arpeggiator.setVelocity(value);
|
||
|
break;
|
||
|
case MidiArp::Param::OCTAVE_SPREAD:
|
||
|
this->arpeggiator.setOctaveSpread(value);
|
||
|
break;
|
||
|
case MidiArp::Param::OCTAVE_MODE:
|
||
|
this->arpeggiator.setOctaveMode(value);
|
||
|
break;
|
||
|
case MidiArp::Param::PANIC:
|
||
|
this->arpeggiator.setPanic(value == 1);
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
unsigned MidiArp::getParameter(unsigned param)
|
||
|
{
|
||
|
switch (param)
|
||
|
{
|
||
|
case MidiArp::Param::BYPASS:
|
||
|
return this->getBypass() ? 1 : 0;
|
||
|
case MidiArp::Param::LATCH:
|
||
|
return this->arpeggiator.getLatchMode() ? 1 : 0;
|
||
|
case MidiArp::Param::SYNC:
|
||
|
return this->arpeggiator.getSyncMode();
|
||
|
case MidiArp::Param::ARP_MODE:
|
||
|
return this->arpeggiator.getArpMode();
|
||
|
case MidiArp::Param::DIVISION:
|
||
|
return this->arpeggiator.getDivision();
|
||
|
case MidiArp::Param::NOTE_LENGTH:
|
||
9 months ago
|
return roundf(this->arpeggiator.getNoteLength() * 100);
|
||
9 months ago
|
case MidiArp::Param::VELOCITY:
|
||
|
return this->arpeggiator.getVelocity();
|
||
|
case MidiArp::Param::OCTAVE_SPREAD:
|
||
|
return this->arpeggiator.getOctaveSpread();
|
||
|
case MidiArp::Param::OCTAVE_MODE:
|
||
|
return this->arpeggiator.getOctaveMode();
|
||
|
case MidiArp::Param::PANIC:
|
||
|
return this->arpeggiator.getPanic();
|
||
|
default:
|
||
|
return 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
9 months ago
|
void MidiArp::keydown(int16_t pitch, uint8_t velocity)
|
||
|
{
|
||
|
MidiEvent event;
|
||
|
event.data[0] = MIDI_NOTE_ON << 4;
|
||
|
event.data[1] = pitch;
|
||
|
event.data[2] = velocity;
|
||
|
event.size = 3;
|
||
|
event.frame = 0;
|
||
|
this->events.push_back(event);
|
||
|
}
|
||
|
|
||
|
void MidiArp::keyup(int16_t pitch)
|
||
|
{
|
||
|
MidiEvent event;
|
||
|
event.data[0] = MIDI_NOTE_OFF << 4;
|
||
|
event.data[1] = pitch;
|
||
|
event.data[2] = 0;
|
||
|
event.size = 3;
|
||
|
event.frame = 0;
|
||
|
this->events.push_back(event);
|
||
|
}
|
||
|
|
||
9 months ago
|
void MidiArp::doProcess(uint16_t len)
|
||
9 months ago
|
{
|
||
|
arpeggiator.emptyMidiBuffer();
|
||
|
|
||
|
// Check if host supports Bar-Beat-Tick position
|
||
9 months ago
|
arpeggiator.setSyncMode(0);
|
||
9 months ago
|
/*
|
||
|
const TimePosition& position = getTimePosition();
|
||
|
if (!position.bbt.valid) {
|
||
|
// set-arpeggiator in free running mode
|
||
|
arpeggiator.setSyncMode(0);
|
||
|
} else {
|
||
|
arpeggiator.setSyncMode(syncMode);
|
||
|
arpeggiator.transmitHostInfo(position.playing, position.bbt.beatsPerBar, position.bbt.beat, position.bbt.barBeat, static_cast<float>(position.bbt.beatsPerMinute));
|
||
|
}
|
||
|
*/
|
||
|
|
||
|
arpeggiator.process(events.data(), events.size(), len);
|
||
|
events.clear();
|
||
|
events.shrink_to_fit();
|
||
|
|
||
|
struct MidiBuffer buffer = arpeggiator.getMidiBuffer();
|
||
|
for (unsigned x = 0; x < buffer.numBufferedEvents + buffer.numBufferedThroughEvents; x++) {
|
||
|
MidiEvent event = buffer.bufferedEvents[x];
|
||
|
unsigned eventType = event.data[0] >> 4;
|
||
|
|
||
|
switch (eventType)
|
||
|
{
|
||
|
case MIDI_NOTE_ON:
|
||
|
if (event.data[2] > 0)
|
||
|
{
|
||
|
if (event.data[2] <= 127)
|
||
|
{
|
||
|
this->synth->keydown(event.data[1], event.data[2]);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
this->synth->keyup(event.data[1]);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case MIDI_NOTE_OFF:
|
||
|
this->synth->keyup(event.data[1]);
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|