#include "midi.h" #include "libremidi/libremidi.hpp" #include "raylib.h" #include #include #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(); 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); } } } }