wyjście midi na urządzenie
This commit is contained in:
parent
7e751ac660
commit
22b2656f72
@ -163,7 +163,7 @@ struct Runner
|
|||||||
{
|
{
|
||||||
static inline Runner *the;
|
static inline Runner *the;
|
||||||
|
|
||||||
midi::Rt_Midi midi;
|
midi::Serial_Midi midi;
|
||||||
Interpreter interpreter;
|
Interpreter interpreter;
|
||||||
std::shared_ptr<serialport::State> serial_state;
|
std::shared_ptr<serialport::State> serial_state;
|
||||||
std::optional<std::jthread> serial_event_loop;
|
std::optional<std::jthread> serial_event_loop;
|
||||||
@ -179,6 +179,7 @@ struct Runner
|
|||||||
/// Setup communication over serial
|
/// Setup communication over serial
|
||||||
serial_state = std::make_shared<serialport::State>();
|
serial_state = std::make_shared<serialport::State>();
|
||||||
interpreter.serialport = serial_state;
|
interpreter.serialport = serial_state;
|
||||||
|
midi.serialport = serial_state;
|
||||||
serialport::initialize();
|
serialport::initialize();
|
||||||
|
|
||||||
serial_event_loop = std::jthread([this](std::stop_token token) mutable{
|
serial_event_loop = std::jthread([this](std::stop_token token) mutable{
|
||||||
@ -186,29 +187,6 @@ struct Runner
|
|||||||
});
|
});
|
||||||
|
|
||||||
interpreter.midi_connection = &midi;
|
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> {
|
Env::global->force_define("say", +[](Interpreter &interpreter, std::vector<Value> args) -> Result<Value> {
|
||||||
for (auto it = args.begin(); it != args.end(); ++it) {
|
for (auto it = args.begin(); it != args.end(); ++it) {
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include <functional>
|
#include <functional>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <musique/serialport/serialport.hh>
|
||||||
|
|
||||||
// Documentation of midi messages available at http://midi.teragonaudio.com/tech/midispec.htm
|
// Documentation of midi messages available at http://midi.teragonaudio.com/tech/midispec.htm
|
||||||
namespace midi
|
namespace midi
|
||||||
@ -22,6 +23,20 @@ namespace midi
|
|||||||
void send_all_sounds_off(uint8_t channel);
|
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
|
struct Rt_Midi : Connection
|
||||||
{
|
{
|
||||||
~Rt_Midi() override = default;
|
~Rt_Midi() override = default;
|
||||||
|
29
musique/midi/serial_midi.cc
Normal file
29
musique/midi/serial_midi.cc
Normal 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();
|
||||||
|
}
|
@ -17,6 +17,15 @@ namespace serialport{
|
|||||||
state[position] = value;
|
state[position] = value;
|
||||||
return;
|
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()
|
void initialize()
|
||||||
{
|
{
|
||||||
@ -80,13 +89,15 @@ namespace serialport{
|
|||||||
|
|
||||||
state.set(control - 65, value);
|
state.set(control - 65, value);
|
||||||
|
|
||||||
switch(control){
|
while(state.head != state.tail){
|
||||||
case 68: // D
|
if(state.message_types[state.tail] == 0){
|
||||||
|
uint8_t bytes_to_send[3] = {0b10010000, state.message_data[state.tail], 0b00000000};
|
||||||
break;
|
serial_conn.write(bytes_to_send, 3);
|
||||||
case 66: // B
|
}else if(state.message_types[state.tail] == 1){
|
||||||
|
uint8_t bytes_to_send[3] = {0b10000000, state.message_data[state.tail], 0b00000000};
|
||||||
break;
|
serial_conn.write(bytes_to_send, 3);
|
||||||
|
}
|
||||||
|
state.tail = (state.tail + 1) % 128;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (std::exception &e) {
|
} catch (std::exception &e) {
|
||||||
|
@ -15,8 +15,13 @@ namespace serialport{
|
|||||||
constexpr std::size_t MAX_VALUE = 4095;
|
constexpr std::size_t MAX_VALUE = 4095;
|
||||||
struct State{
|
struct State{
|
||||||
std::array<std::atomic<std::uint32_t>, MAX_STATE_COUNT> 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();
|
int test();
|
||||||
Number get(unsigned position) const;
|
Number get(unsigned position) const;
|
||||||
|
void send(uint8_t message_type, uint8_t note_number);
|
||||||
void set(unsigned position, std::uint32_t value);
|
void set(unsigned position, std::uint32_t value);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user