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;
|
||||
|
||||
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) {
|
||||
|
@ -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;
|
||||
|
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;
|
||||
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
|
||||
|
@ -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);
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user