Files
viseq/src/midi.h
T

113 lines
2.8 KiB
C++
Raw Normal View History

#pragma once
#include "libremidi/libremidi.hpp"
#include "libremidi/message.hpp"
#include "libremidi/observer_configuration.hpp"
#include "raylib.h"
2024-10-28 19:24:18 +01:00
#include <iostream>
#include <map>
#include <memory>
2024-10-20 01:17:18 +02:00
#include "datatypes.h"
2024-11-03 03:48:49 +01:00
namespace VISEQ::MIDI {
2024-11-03 03:48:49 +01:00
struct NoteTimer{
int midi_out;
int channel;
int note;
int velocity;
float start;
int gate;
bool erase = false;
};
2024-11-03 03:48:49 +01:00
class Midi {
2024-11-03 03:48:49 +01:00
public:
Midi() {
enumerate();
}
2024-10-20 02:01:30 +02:00
2024-11-03 03:48:49 +01:00
libremidi::observer obs;
2024-11-03 03:48:49 +01:00
std::map<int, std::shared_ptr<libremidi::midi_out>> midi_outs;
std::vector<libremidi::input_port> midi_in_ports;
std::vector<MidiOutPort> midi_out_ports;
2024-11-03 03:48:49 +01:00
std::vector<NoteTimer> notes;
2024-11-03 03:48:49 +01:00
float timer;
void 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++;
}
2024-10-28 19:24:18 +01:00
}
2024-11-03 03:48:49 +01:00
void 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;
}
}
2024-11-03 03:48:49 +01:00
void 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);
}
2024-10-20 23:42:38 +02:00
}
2024-11-03 03:48:49 +01:00
void 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);
}
2024-10-20 01:17:18 +02:00
}
}
2024-11-03 03:48:49 +01:00
void 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));
}
}
}
2024-11-03 03:48:49 +01:00
void 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));
}
}
}
2024-11-03 03:48:49 +01:00
void 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));
n.erase = true;
}
}
2024-11-03 03:48:49 +01:00
std::erase_if(notes, [](const auto& item){return item.erase;});
2024-10-27 00:40:57 +02:00
2024-11-03 03:48:49 +01:00
for(auto& p : midi_out_ports){
if(p.enabled) {
open_midi_out(&p);
} else if(!p.enabled) {
close_midi_out(&p);
}
}
}
2024-11-03 03:48:49 +01:00
};
}