92 lines
3.2 KiB
C++
92 lines
3.2 KiB
C++
#include "midi.h"
|
|
|
|
#include "libremidi/libremidi.hpp"
|
|
#include "raylib.h"
|
|
|
|
#include <iostream>
|
|
#include <memory>
|
|
#include "datatypes.h"
|
|
|
|
namespace VISEQ::MIDI {
|
|
|
|
void Midi::enumerate(){
|
|
std::cout << (int)obs.get_current_api() << std::endl;
|
|
|
|
|
|
int i = 0;
|
|
midi_out_ports.clear();
|
|
for(const libremidi::output_port& port : obs.get_output_ports()){
|
|
midi_out_ports.push_back({port, i, false});
|
|
i++;
|
|
}
|
|
|
|
auto out_conf = libremidi::midi1::out_default_configuration();
|
|
virtual_midi_out = libremidi::midi_out(libremidi::output_configuration(), out_conf);
|
|
virtual_midi_out.open_virtual_port("viseq out");
|
|
|
|
//midi_out_ports.push_back({&virtual_midi_out, 99, false});
|
|
}
|
|
|
|
void Midi::open_midi_out(MidiOutPort *out_port){
|
|
if(!midi_outs.contains(out_port->number)){
|
|
auto out = std::make_shared<libremidi::midi_out>();
|
|
out->open_port(out_port->port);
|
|
midi_outs[out_port->number] = out;
|
|
}
|
|
}
|
|
|
|
void Midi::close_midi_out(MidiOutPort *out_port){
|
|
if(midi_outs.contains(out_port->number)){
|
|
midi_outs[out_port->number]->close_port();
|
|
midi_outs.erase(out_port->number);
|
|
}
|
|
}
|
|
|
|
void Midi::note(int midi_out, int channel, int note, int velocity, int gate){
|
|
if(midi_outs.contains(midi_out)){
|
|
if(midi_outs[midi_out]->is_port_open()){
|
|
midi_outs[midi_out]->send_message(libremidi::channel_events::note_on(channel, note, velocity));
|
|
notes.emplace_back(midi_out, channel, note, velocity, GetTime(), gate);
|
|
}
|
|
}
|
|
virtual_midi_out.send_message(libremidi::channel_events::note_on(channel, note, velocity));
|
|
notes.emplace_back(99, channel, note, velocity, GetTime(), gate);
|
|
}
|
|
|
|
void Midi::cc(int midi_out, int channel, int cc, int value){
|
|
if(midi_outs.contains(midi_out)){
|
|
if(midi_outs[midi_out]->is_port_open()){
|
|
midi_outs[midi_out]->send_message(libremidi::channel_events::control_change(channel, cc, value));
|
|
}
|
|
}
|
|
}
|
|
|
|
void Midi::pitch_bend(int midi_out, int channel, int pitch_value){
|
|
if(midi_outs.contains(midi_out)){
|
|
if(midi_outs[midi_out]->is_port_open()){
|
|
midi_outs[midi_out]->send_message(libremidi::channel_events::pitch_bend(channel, pitch_value));
|
|
}
|
|
}
|
|
}
|
|
|
|
void Midi::update(){
|
|
float time = GetTime();
|
|
for(auto &n : notes){
|
|
if(time - n.start >= (float)n.gate / 1000.0f){
|
|
if(midi_outs.contains(n.midi_out) && midi_outs[n.midi_out]->is_port_open()) midi_outs[n.midi_out]->send_message(libremidi::channel_events::note_off(n.channel, n.note, n.velocity));
|
|
virtual_midi_out.send_message(libremidi::channel_events::note_off(n.channel, n.note, n.velocity));
|
|
n.erase = true;
|
|
}
|
|
}
|
|
std::erase_if(notes, [](const auto& item){return item.erase;});
|
|
|
|
for(auto& p : midi_out_ports){
|
|
if(p.enabled) {
|
|
open_midi_out(&p);
|
|
} else if(!p.enabled) {
|
|
close_midi_out(&p);
|
|
}
|
|
}
|
|
}
|
|
}
|