wyjście midi na urządzenie

This commit is contained in:
Mateusz Drabek 2023-01-09 19:11:33 +01:00
parent 7e751ac660
commit 22b2656f72
5 changed files with 70 additions and 32 deletions

View File

@ -163,7 +163,7 @@ struct Runner
{
static inline Runner *the;
midi::Rt_Midi midi;
midi::Serial_Midi midi;
Interpreter interpreter;
std::shared_ptr<serialport::State> serial_state;
std::optional<std::jthread> serial_event_loop;
@ -179,6 +179,7 @@ struct Runner
/// Setup communication over serial
serial_state = std::make_shared<serialport::State>();
interpreter.serialport = serial_state;
midi.serialport = serial_state;
serialport::initialize();
serial_event_loop = std::jthread([this](std::stop_token token) mutable{
@ -186,29 +187,6 @@ struct Runner
});
interpreter.midi_connection = &midi;
if (output_port) {
if(output_port == 42){
/// TODO CHANGE THE MAGIC NUMBER TO SEPARATE ARGUMENT
midi.connect_output();
if (!quiet_mode) {
std::cout << "Created new MIDI output port 'Musique'. Ready to play!" << std::endl;
}
}else{
midi.connect_output(*output_port);
if (!quiet_mode) {
std::cout << "Connected MIDI output to port " << *output_port << ". Ready to play!" << std::endl;
}
}
} else {
bool connected_to_existing_port = midi.connect_or_create_output();
if (!quiet_mode) {
if (connected_to_existing_port) {
std::cout << "Connected MIDI output to port " << midi.output->getPortName(0) << std::endl;
} else {
std::cout << "Created new MIDI output port 'Musique'. Ready to play!" << std::endl;
}
}
}
Env::global->force_define("say", +[](Interpreter &interpreter, std::vector<Value> args) -> Result<Value> {
for (auto it = args.begin(); it != args.end(); ++it) {

View File

@ -4,6 +4,7 @@
#include <functional>
#include <optional>
#include <string>
#include <musique/serialport/serialport.hh>
// Documentation of midi messages available at http://midi.teragonaudio.com/tech/midispec.htm
namespace midi
@ -22,6 +23,20 @@ namespace midi
void send_all_sounds_off(uint8_t channel);
};
struct Serial_Midi : Connection
{
~Serial_Midi() = default;
bool supports_output() const override;
void send_note_on (uint8_t channel, uint8_t note_number, uint8_t velocity) override;
void send_note_off(uint8_t channel, uint8_t note_number, uint8_t velocity) override;
void send_program_change(uint8_t channel, uint8_t program) override;
void send_controller_change(uint8_t channel, uint8_t controller_number, uint8_t value) override;
std::shared_ptr<serialport::State> serialport;
};
struct Rt_Midi : Connection
{
~Rt_Midi() override = default;

View File

@ -0,0 +1,29 @@
#include <musique/errors.hh>
#include <musique/midi/midi.hh>
#include <musique/serialport/serialport.hh>
#include <musique/interpreter/interpreter.hh>
bool midi::Serial_Midi::supports_output() const
{
return true;
}
void midi::Serial_Midi::send_note_on (uint8_t channel, uint8_t note_number, uint8_t velocity)
{
serialport->send(0, note_number);
}
void midi::Serial_Midi::send_note_off(uint8_t channel, uint8_t note_number, uint8_t velocity)
{
serialport->send(1, note_number);
}
void midi::Serial_Midi::send_program_change(uint8_t channel, uint8_t program)
{
unimplemented();
}
void midi::Serial_Midi::send_controller_change(uint8_t channel, uint8_t controller_number, uint8_t value)
{
unimplemented();
}

View File

@ -17,6 +17,15 @@ namespace serialport{
state[position] = value;
return;
}
void State::send(uint8_t message_type, uint8_t note_number)
{
if((head + 1) % 128 != tail){
message_data[head] = note_number;
message_types[head] = message_type;
head = (head + 1)%128;
}
return;
}
void initialize()
{
@ -80,14 +89,16 @@ namespace serialport{
state.set(control - 65, value);
switch(control){
case 68: // D
break;
case 66: // B
break;
}
while(state.head != state.tail){
if(state.message_types[state.tail] == 0){
uint8_t bytes_to_send[3] = {0b10010000, state.message_data[state.tail], 0b00000000};
serial_conn.write(bytes_to_send, 3);
}else if(state.message_types[state.tail] == 1){
uint8_t bytes_to_send[3] = {0b10000000, state.message_data[state.tail], 0b00000000};
serial_conn.write(bytes_to_send, 3);
}
state.tail = (state.tail + 1) % 128;
}
}
} catch (std::exception &e) {
/// No connection to the device

View File

@ -15,8 +15,13 @@ namespace serialport{
constexpr std::size_t MAX_VALUE = 4095;
struct State{
std::array<std::atomic<std::uint32_t>, MAX_STATE_COUNT> state;
std::array<std::atomic<std::uint8_t>, 128> message_types;
std::array<std::atomic<std::uint8_t>, 128> message_data;
std::atomic<std::uint8_t> head = 0;
std::atomic<std::uint8_t> tail = 0;
int test();
Number get(unsigned position) const;
void send(uint8_t message_type, uint8_t note_number);
void set(unsigned position, std::uint32_t value);
};