122 lines
3.0 KiB
C++
122 lines
3.0 KiB
C++
#include <jack/jack.h>
|
|
#include <jack/midiport.h>
|
|
#include "cvin.h"
|
|
|
|
void CVIn::shutdown()
|
|
{
|
|
}
|
|
|
|
int CVIn::process(jack_nframes_t nframes)
|
|
{
|
|
if (!m_ready) return 0;
|
|
|
|
void *midi_out = jack_port_get_buffer(m_midi_out, nframes);
|
|
jack_midi_clear_buffer(midi_out);
|
|
|
|
for (unsigned i = 0; i < m_mapping_list.size(); i++) {
|
|
m_buffers[i] = static_cast<sample_t *>(jack_port_get_buffer(m_ports[i], nframes));
|
|
}
|
|
|
|
for (jack_nframes_t f = 0; f < nframes; f++) {
|
|
int port = 0;
|
|
MappingList::iterator it;
|
|
for (it = m_it_begin; it != m_it_end; ++it, port++) {
|
|
Mapping *m = &(*it);
|
|
jack_midi_data_t buf[3];
|
|
|
|
m->cur_mv = m->to_mv(*m_buffers[port]++);
|
|
|
|
if (m->tick_cvin()) {
|
|
switch (m->type) {
|
|
case TYPE_PB:
|
|
buf[0] = 0xE0 | m->channel;
|
|
buf[1] = m->last_mv >> 7;
|
|
buf[2] = m->last_mv & 0x7F;
|
|
jack_midi_event_write(midi_out, f, buf, sizeof buf);
|
|
break;
|
|
|
|
case TYPE_CC:
|
|
buf[0] = 0xB0 | m->channel;
|
|
buf[1] = m->ccmsb;
|
|
if (m->has_lsb) {
|
|
buf[2] = m->last_mv >> 7;
|
|
jack_midi_event_write(midi_out, f, buf, sizeof buf);
|
|
buf[1] = m->cclsb;
|
|
}
|
|
buf[2] = m->last_mv & 0x7F;
|
|
jack_midi_event_write(midi_out, f, buf, sizeof buf);
|
|
break;
|
|
|
|
case TYPE_NRPN:
|
|
buf[0] = 0xB0 | m->channel;
|
|
buf[1] = 99;
|
|
buf[2] = m->ccmsb;
|
|
jack_midi_event_write(midi_out, f, buf, sizeof buf);
|
|
buf[1] = 98;
|
|
buf[2] = m->cclsb;
|
|
jack_midi_event_write(midi_out, f, buf, sizeof buf);
|
|
buf[1] = 6;
|
|
if (m->has_lsb) {
|
|
buf[2] = m->last_mv >> 7;
|
|
jack_midi_event_write(midi_out, f, buf, sizeof buf);
|
|
buf[1] = 38;
|
|
}
|
|
buf[2] = m->last_mv & 0x7F;
|
|
jack_midi_event_write(midi_out, f, buf, sizeof buf);
|
|
break;
|
|
|
|
case TYPE_RPN:
|
|
buf[0] = 0xB0 | m->channel;
|
|
buf[1] = 101;
|
|
buf[2] = m->ccmsb;
|
|
jack_midi_event_write(midi_out, f, buf, sizeof buf);
|
|
buf[1] = 100;
|
|
buf[2] = m->cclsb;
|
|
jack_midi_event_write(midi_out, f, buf, sizeof buf);
|
|
buf[1] = 6;
|
|
if (m->has_lsb) {
|
|
buf[2] = m->last_mv >> 7;
|
|
jack_midi_event_write(midi_out, f, buf, sizeof buf);
|
|
buf[1] = 38;
|
|
}
|
|
buf[2] = m->last_mv & 0x7F;
|
|
jack_midi_event_write(midi_out, f, buf, sizeof buf);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void CVIn::start()
|
|
{
|
|
m_ready = false;
|
|
m_tick = 0;
|
|
|
|
if (m_mapping_list.size() == 0) return;
|
|
|
|
m_ports = new jack_port_t *[m_mapping_list.size()];
|
|
m_buffers = new sample_t *[m_mapping_list.size()];
|
|
|
|
if (!open(m_config_name.empty() ? "m2cv_in" : m_config_name.c_str())) exit(EXIT_FAILURE);
|
|
|
|
m_midi_out = port_register("midi_out", JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput, 0);
|
|
|
|
MappingList::iterator it_begin = m_mapping_list.begin();
|
|
MappingList::iterator it_end = m_mapping_list.end();
|
|
|
|
int port = 0;
|
|
MappingList::iterator it;
|
|
for (it = it_begin; it != it_end; ++it, port++) {
|
|
Mapping *m = &(*it);
|
|
m_ports[port] = port_register(m->name.c_str(), JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
|
|
|
|
m->latency_ticks = m_sample_rate * m->latency / 1000.0f;
|
|
}
|
|
|
|
m_it_end = it_end;
|
|
m_it_begin = it_begin;
|
|
m_ready = true;
|
|
}
|