diff --git a/src/interpreter.cc b/src/interpreter.cc index 957dd76..9f7cd67 100644 --- a/src/interpreter.cc +++ b/src/interpreter.cc @@ -27,15 +27,33 @@ struct Interpreter::Incoming_Midi_Callbacks template void register_callback(std::function &target, Value &callback, Interpreter &i) { - target = [interpreter = &i, callback = &callback](T ...source_args) - { - std::cout << "hello from callback!" << std::endl; - if (callback->type != Value::Type::Nil) { - auto result = (*callback)(*interpreter, { Value::from(Number(source_args))... }); - // We discard this since callback is running in another thread. - (void) result; - } - }; + if (&callback == ¬e_on || &callback == ¬e_off) { + // This messages have MIDI note number as second value, so they should be represented + // in our own note abstraction, not as numbers. + target = [interpreter = &i, callback = &callback](T ...source_args) + { + if (callback->type != Value::Type::Nil) { + std::vector args { Value::from(Number(source_args))... }; + args[1] = Value::from(Chord { .notes { Note { + .base = i32(args[1].n.num % 12), + .octave = args[1].n.num / 12 + }}}); + auto result = (*callback)(*interpreter, std::move(args)); + // We discard this since callback is running in another thread. + (void) result; + } + }; + } else { + // Generic case, preserve all passed parameters as numbers + target = [interpreter = &i, callback = &callback](T ...source_args) + { + if (callback->type != Value::Type::Nil) { + auto result = (*callback)(*interpreter, { Value::from(Number(source_args))... }); + // We discard this since callback is running in another thread. + (void) result; + } + }; + } } }; @@ -43,6 +61,11 @@ void Interpreter::register_callbacks() { assert(callbacks != nullptr, "Interpreter constructor should initialize this field"); callbacks->add_callbacks(*midi_connection, *this); + + callbacks->note_on = Value(+[](Interpreter &, std::vector args) -> Result { + std::cout << "Received: " << args[1] << "\r\n" << std::flush; + return Value{}; + }); } /// Intrinsic implementation primitive providing a short way to check if arguments match required type signature @@ -670,7 +693,6 @@ Result Interpreter::eval(Ast &&ast) return *v = Try(eval(std::move(rhs))); } - if (ast.token.source == "and" || ast.token.source == "or") { auto lhs = std::move(ast.arguments.front()); auto rhs = std::move(ast.arguments.back());