1
- #include < nanobind/stl /chrono.h>
2
- #include < nanobind/nanobind .h>
1
+ #include < pybind11 /chrono.h>
2
+ #include < pybind11/pybind11 .h>
3
3
4
4
#include < algorithm>
5
5
#include < chrono>
9
9
10
10
#include < ableton/Link.hpp>
11
11
12
- namespace nb = nanobind ;
12
+ namespace py = pybind11 ;
13
13
14
14
struct SchedulerSyncEvent {
15
- nb ::object future;
15
+ py ::object future;
16
16
17
17
double beat;
18
18
double offset;
@@ -40,10 +40,10 @@ static double next_link_beat(double current_beat, double sync_beat, double offse
40
40
return std::max (next_beat, 0.0 );
41
41
}
42
42
43
- static void set_future_result (nb ::object future, double link_beat) {
44
- nb ::gil_scoped_acquire acquire;
43
+ static void set_future_result (py ::object future, double link_beat) {
44
+ py ::gil_scoped_acquire acquire;
45
45
46
- bool done = nb ::cast<bool >(future.attr (" done" )());
46
+ bool done = py ::cast<bool >(future.attr (" done" )());
47
47
48
48
if (!done) {
49
49
auto set_result = future.attr (" set_result" );
@@ -52,7 +52,7 @@ static void set_future_result(nb::object future, double link_beat) {
52
52
}
53
53
54
54
struct Scheduler {
55
- Scheduler (ableton::Link& link, nb ::object loop) : m_link(link), m_loop(loop) {
55
+ Scheduler (ableton::Link& link, py ::object loop) : m_link(link), m_loop(loop) {
56
56
start ();
57
57
}
58
58
@@ -86,13 +86,13 @@ struct Scheduler {
86
86
87
87
for (auto it = m_events.begin (); it != m_events.end ();) {
88
88
if (link_beat > it->link_beat ) {
89
- nb ::gil_scoped_acquire acquire;
89
+ py ::gil_scoped_acquire acquire;
90
90
91
- bool loop_is_running = nb ::cast<bool >(m_loop.attr (" is_running" )());
91
+ bool loop_is_running = py ::cast<bool >(m_loop.attr (" is_running" )());
92
92
93
93
if (loop_is_running) {
94
94
auto loop_call_soon_threadsafe = m_loop.attr (" call_soon_threadsafe" );
95
- loop_call_soon_threadsafe (nb ::cpp_function (&set_future_result), it->future , it->link_beat );
95
+ loop_call_soon_threadsafe (py ::cpp_function (&set_future_result), it->future , it->link_beat );
96
96
}
97
97
98
98
it = m_events.erase (it);
@@ -111,7 +111,7 @@ struct Scheduler {
111
111
}
112
112
}
113
113
114
- void schedule_sync (nb ::object future, double beat, double offset, double origin) {
114
+ void schedule_sync (py ::object future, double beat, double offset, double origin) {
115
115
SchedulerSyncEvent event = {
116
116
.future = future,
117
117
.beat = beat,
@@ -121,7 +121,7 @@ struct Scheduler {
121
121
};
122
122
123
123
// prevent occasional GIL deadlocks when calling link.sync()
124
- nb ::gil_scoped_release release;
124
+ py ::gil_scoped_release release;
125
125
126
126
m_events_mutex.lock ();
127
127
m_events.push_back (std::move (event));
@@ -151,11 +151,11 @@ struct Scheduler {
151
151
std::atomic<double > m_link_quantum{1 };
152
152
153
153
ableton::Link& m_link;
154
- nb ::object m_loop;
154
+ py ::object m_loop;
155
155
};
156
156
157
157
struct Link {
158
- Link (double bpm, nb ::object loop)
158
+ Link (double bpm, py ::object loop)
159
159
: m_link(bpm), m_loop(loop), m_scheduler(m_link, m_loop) {}
160
160
161
161
std::size_t num_peers () {
@@ -254,71 +254,71 @@ struct Link {
254
254
m_scheduler.reschedule_sync_events (beat);
255
255
}
256
256
257
- void set_num_peers_callback (nb::callable callback) {
257
+ void set_num_peers_callback (py::function callback) {
258
258
m_link.setNumPeersCallback ([this , callback](std::size_t num_peers) {
259
259
// ensure the callback isn't called when the runtime is finalizing
260
260
if (!_Py_IsFinalizing ()) {
261
- nb ::gil_scoped_acquire acquire;
261
+ py ::gil_scoped_acquire acquire;
262
262
263
263
auto loop_call_soon_threadsafe = this ->m_loop .attr (" call_soon_threadsafe" );
264
264
loop_call_soon_threadsafe (callback, num_peers);
265
265
}
266
266
});
267
267
}
268
268
269
- void set_tempo_callback (nb::callable callback) {
269
+ void set_tempo_callback (py::function callback) {
270
270
m_link.setTempoCallback ([this , callback](double tempo) {
271
271
// ensure the callback isn't called when the runtime is finalizing
272
272
if (!_Py_IsFinalizing ()) {
273
- nb ::gil_scoped_acquire acquire;
273
+ py ::gil_scoped_acquire acquire;
274
274
275
275
auto loop_call_soon_threadsafe = this ->m_loop .attr (" call_soon_threadsafe" );
276
276
loop_call_soon_threadsafe (callback, tempo);
277
277
}
278
278
});
279
279
}
280
280
281
- void set_start_stop_callback (nb::callable callback) {
281
+ void set_start_stop_callback (py::function callback) {
282
282
m_link.setStartStopCallback ([this , callback](bool playing) {
283
283
// ensure the callback isn't called when the runtime is finalizing
284
284
if (!_Py_IsFinalizing ()) {
285
- nb ::gil_scoped_acquire acquire;
285
+ py ::gil_scoped_acquire acquire;
286
286
287
287
auto loop_call_soon_threadsafe = this ->m_loop .attr (" call_soon_threadsafe" );
288
288
loop_call_soon_threadsafe (callback, playing);
289
289
}
290
290
});
291
291
}
292
292
293
- nb ::object sync (double beat, double offset, double origin) {
293
+ py ::object sync (double beat, double offset, double origin) {
294
294
auto future = m_loop.attr (" create_future" )();
295
295
m_scheduler.schedule_sync (future, beat, offset, origin);
296
296
return future;
297
297
}
298
298
299
299
ableton::Link m_link;
300
- nb ::object m_loop;
300
+ py ::object m_loop;
301
301
Scheduler m_scheduler;
302
302
};
303
303
304
- NB_MODULE (aalink, m) {
305
- nb ::class_<Link>(m, " Link" )
306
- .def (nb ::init<double , nb ::object>(), nb ::arg (" bpm" ), nb ::arg (" loop" ))
307
- .def_prop_ro (" num_peers" , &Link::num_peers)
308
- .def_prop_ro (" beat" , &Link::beat)
309
- .def_prop_ro (" phase" , &Link::phase)
310
- .def_prop_ro (" time" , &Link::time )
311
- .def_prop_rw (" quantum" , &Link::quantum, &Link::set_quantum)
312
- .def_prop_rw (" enabled" , &Link::enabled, &Link::set_enabled)
313
- .def_prop_rw (" start_stop_sync_enabled" , &Link::start_stop_sync_enabled, &Link::set_start_stop_sync_enabled)
314
- .def_prop_rw (" tempo" , &Link::tempo, &Link::set_tempo)
315
- .def_prop_rw (" playing" , &Link::playing, &Link::set_playing)
304
+ PYBIND11_MODULE (aalink, m) {
305
+ py ::class_<Link>(m, " Link" )
306
+ .def (py ::init<double , py ::object>(), py ::arg (" bpm" ), py ::arg (" loop" ))
307
+ .def_property_readonly (" num_peers" , &Link::num_peers)
308
+ .def_property_readonly (" beat" , &Link::beat)
309
+ .def_property_readonly (" phase" , &Link::phase)
310
+ .def_property_readonly (" time" , &Link::time )
311
+ .def_property (" quantum" , &Link::quantum, &Link::set_quantum)
312
+ .def_property (" enabled" , &Link::enabled, &Link::set_enabled)
313
+ .def_property (" start_stop_sync_enabled" , &Link::start_stop_sync_enabled, &Link::set_start_stop_sync_enabled)
314
+ .def_property (" tempo" , &Link::tempo, &Link::set_tempo)
315
+ .def_property (" playing" , &Link::playing, &Link::set_playing)
316
316
.def (" request_beat" , &Link::request_beat)
317
317
.def (" force_beat" , &Link::force_beat)
318
318
.def (" request_beat_at_start_playing_time" , &Link::request_beat_at_start_playing_time)
319
319
.def (" set_is_playing_and_request_beat_at_time" , &Link::set_is_playing_and_request_beat_at_time)
320
320
.def (" set_num_peers_callback" , &Link::set_num_peers_callback)
321
321
.def (" set_tempo_callback" , &Link::set_tempo_callback)
322
322
.def (" set_start_stop_callback" , &Link::set_start_stop_callback)
323
- .def (" sync" , &Link::sync , nb ::arg (" beat" ), nb ::arg (" offset" ) = 0 , nb ::arg (" origin" ) = 0 );
323
+ .def (" sync" , &Link::sync , py ::arg (" beat" ), py ::arg (" offset" ) = 0 , py ::arg (" origin" ) = 0 );
324
324
}
0 commit comments