Skip to content

Commit

Permalink
[python] Add some more utilities
Browse files Browse the repository at this point in the history
  • Loading branch information
jcelerier committed Sep 8, 2024
1 parent 5e9e23a commit d3af179
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 7 deletions.
48 changes: 45 additions & 3 deletions bindings/python/pylibremidi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,10 @@ struct midi_out_poll_wrapper {

NB_MODULE(pylibremidi, m) {
namespace nb = nanobind;
nb::class_<stdx::error>(m, "Error");
nb::class_<stdx::error>(m, "Error")
.def("__bool__", [](stdx::error e) { return e != stdx::error{}; })
.def("__str__", [](stdx::error e) { return e.message().data(); })
.def("__repr__", [](stdx::error e) { return e.message().data(); });
nb::enum_<libremidi::API>(m, "API")
.value("UNSPECIFIED", libremidi::API::UNSPECIFIED)
.value("COREMIDI", libremidi::API::COREMIDI)
Expand All @@ -203,13 +206,52 @@ NB_MODULE(pylibremidi, m) {
.value("KEYBOARD_UMP", libremidi::API::KEYBOARD_UMP)
.value("DUMMY", libremidi::API::DUMMY)
.export_values();
nb::class_<libremidi::message>(m, "Message").def(nb::init<>()).def_rw("bytes", &libremidi::message::bytes).def_rw("timestamp", &libremidi::message::timestamp);

m.def("available_apis", libremidi::available_apis);
m.def("available_ump_apis", libremidi::available_ump_apis);
m.def("get_version", libremidi::get_version);
m.def("get_api_name", libremidi::get_api_name);
m.def("get_api_display_name", libremidi::get_api_display_name);
m.def("get_compiled_api_by_name", libremidi::get_compiled_api_by_name);
m.def("midi1_default_api", libremidi::midi1::default_api);
m.def("midi2_default_api", libremidi::midi2::default_api);

nb::class_<libremidi::message>(m, "Message")
.def(nb::init<>())
.def_rw("bytes", &libremidi::message::bytes)
.def_rw("timestamp", &libremidi::message::timestamp)
.def("__len__", [](const libremidi::message &m, int idx) { return m.size(); })
.def("__getitem__", [](const libremidi::message &m, int idx) { return m[idx]; })
.def("__setitem__", [](libremidi::message &m, int idx, uint8_t res) { return m[idx] = res; })
.def("__repr__", [](const libremidi::message &m) {
std::stringstream str;
str << m.timestamp << ": ";
str << std::hex;
str << "[ ";
for (int val : m)
str << val << ' ';
str << ']';
return str.str();
});
nb::class_<libremidi::ump>(m, "Ump")
.def(nb::init<>())
.def_prop_rw(
"data", [](const libremidi::ump &obj) { return std::array<uint32_t, 4>{obj.data[0], obj.data[1], obj.data[2], obj.data[3]}; },
[](libremidi::ump &obj, std::array<uint32_t, 4> v) { std::copy_n(v.begin(), 4, obj.data); })
.def_rw("timestamp", &libremidi::ump::timestamp);
.def_rw("timestamp", &libremidi::ump::timestamp)
.def("__len__", [](const libremidi::ump &m, int idx) { return m.size(); })
.def("__getitem__", [](const libremidi::ump &m, int idx) { return m[idx]; })
.def("__setitem__", [](libremidi::ump &m, int idx, uint32_t res) { return m[idx] = res; })
.def("__repr__", [](const libremidi::ump &m) {
std::stringstream str;
str << m.timestamp << ": ";
str << std::hex;
str << "[ ";
for (uint32_t val : m)
str << val << ' ';
str << ']';
return str.str();
});

nb::class_<libremidi::port_information>(m, "PortInformation")
.def(nb::init<>())
Expand Down
14 changes: 10 additions & 4 deletions bindings/python/test.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/env python3.13
import pylibremidi as lm
observer_config = lm.ObserverConfiguration()
observer = lm.Observer(observer_config, lm.API.ALSA_SEQ)
observer = lm.Observer(observer_config, lm.midi2_default_api())

pi = observer.get_input_ports()
if len(pi) == 0:
Expand All @@ -14,13 +14,19 @@
exit(1)

midi_out = lm.MidiOut()
midi_out.open_port(po[0])
err = midi_out.open_port(po[0])
if err:
print(err)
exit(1)

in_config = lm.UmpInputConfiguration()
in_config.on_message = lambda msg: print(msg.data[0])
in_config.on_message = lambda msg: print(f"{msg}")

midi_in = lm.MidiIn(in_config)
midi_in.open_port(pi[0])
err = midi_in.open_port(pi[0])
if err:
print(err)
exit(1)

while True:
midi_in.poll()

0 comments on commit d3af179

Please sign in to comment.