Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Python rust backend #470

Open
wants to merge 38 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
d121c30
wip
SanderVocke Nov 18, 2024
b97eaed
wip
SanderVocke Nov 22, 2024
f08073a
wip
SanderVocke Nov 22, 2024
3123c20
wip
SanderVocke Nov 22, 2024
392c39a
wip
SanderVocke Nov 22, 2024
3dc4e03
wip
SanderVocke Nov 22, 2024
6e13319
wip
SanderVocke Nov 22, 2024
5354550
wip
SanderVocke Nov 22, 2024
22660d8
wip
SanderVocke Nov 24, 2024
3b27bc4
wip
SanderVocke Nov 25, 2024
9576096
wip
SanderVocke Nov 25, 2024
6fdca25
wip
SanderVocke Nov 25, 2024
ef16bec
wip
SanderVocke Nov 25, 2024
5d7b671
refactor: Update BackendLoop to use shoop_py_backend methods instead …
SanderVocke Nov 26, 2024
f3a5d0a
wip
SanderVocke Nov 26, 2024
6b99698
wip
SanderVocke Nov 26, 2024
45a08cb
wip
SanderVocke Nov 26, 2024
6ffe9bf
wip
SanderVocke Nov 26, 2024
f516356
wip
SanderVocke Nov 26, 2024
6f75d29
wip
SanderVocke Nov 27, 2024
f4fe489
feat: Implement Rust methods for MidiChannel based on BackendLoopMidi…
SanderVocke Nov 27, 2024
e2db2d8
refactor: Simplify MidiChannel implementation by removing duplicate code
SanderVocke Nov 27, 2024
16039ee
feat: Implement MidiEvent and MidiChannelState types in midi_channel.rs
SanderVocke Nov 27, 2024
96a5c22
fix: Add missing newline at end of file in midi_channel.rs
SanderVocke Nov 28, 2024
fa61693
feat: Implement PyO3-exposed methods for BackendLoopMidiChannel in mi…
SanderVocke Nov 28, 2024
850b51f
wip
SanderVocke Nov 28, 2024
f392285
refactor: Move MidiEvent struct to its own file for better organization
SanderVocke Nov 28, 2024
a522e3e
feat: Implement conversion from backend_bindings::MidiEvent to MidiEvent
SanderVocke Nov 28, 2024
00c35ae
feat: Add registration function for MidiEvent in midi.rs and mod.rs
SanderVocke Nov 28, 2024
3270410
refactor: Replace direct ffi calls in BackendLoopMidiChannel with Mid…
SanderVocke Nov 28, 2024
6bb7772
wip
SanderVocke Nov 28, 2024
463008d
wip
SanderVocke Nov 28, 2024
a217218
feat: Add methods for audio driver management and external port disco…
SanderVocke Nov 28, 2024
8c87a92
feat: Implement types for Jack and Dummy audio driver settings
SanderVocke Nov 28, 2024
cc25169
feat: Create ExternalPortDescriptor struct to wrap shoop_external_por…
SanderVocke Nov 28, 2024
be3d111
wip
SanderVocke Nov 28, 2024
07e7e09
feat: Add PyO3 wrappers for AudioDriver methods in Python backend
SanderVocke Nov 28, 2024
bedae5c
wip
SanderVocke Nov 28, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ py-build-cmake.cross.toml
Cargo.lock
target
.aider*
.env
10 changes: 5 additions & 5 deletions src/backend/internal/BasicLoop.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ BasicLoop::BasicLoop() :
ma_triggering_now(false),
ma_length(0),
ma_position(0),
ma_maybe_next_planned_mode(LOOP_MODE_INVALID),
ma_maybe_next_planned_mode(LoopMode_Unknown),
ma_maybe_next_planned_delay(-1),
ma_already_triggered(false)
{
Expand Down Expand Up @@ -211,7 +211,7 @@ shoop_shared_ptr<LoopInterface> BasicLoop::get_sync_source(bool thread_safe) {
void BasicLoop::PROC_update_planned_transition_cache() {

ma_maybe_next_planned_mode = mp_planned_states.size() > 0 ?
(shoop_loop_mode_t) mp_planned_states.front() : LOOP_MODE_INVALID;
(shoop_loop_mode_t) mp_planned_states.front() : LoopMode_Unknown;
ma_maybe_next_planned_delay = mp_planned_state_countdowns.size() > 0 ?
mp_planned_state_countdowns.front() : -1;
}
Expand Down Expand Up @@ -261,7 +261,7 @@ void BasicLoop::PROC_handle_transition(shoop_loop_mode_t new_state) {
set_length(0, false);
}
ma_mode = new_state;
if(ma_mode > LOOP_MODE_INVALID) {
if(ma_mode >= LOOP_MODE_INVALID) {
throw_error<std::runtime_error>("invalid mode");
}
if (ma_mode == LoopMode_Stopped) { ma_position = 0; }
Expand Down Expand Up @@ -415,11 +415,11 @@ shoop_loop_mode_t BasicLoop::get_mode() const {
void BasicLoop::get_first_planned_transition(shoop_loop_mode_t &maybe_mode_out, uint32_t &delay_out) {
shoop_loop_mode_t maybe_mode = ma_maybe_next_planned_mode;
int maybe_delay = ma_maybe_next_planned_delay;
if (maybe_delay >= 0 && maybe_mode != LOOP_MODE_INVALID) {
if (maybe_delay >= 0 && maybe_mode != LoopMode_Unknown) {
maybe_mode_out = maybe_mode;
delay_out = maybe_delay;
} else {
maybe_mode_out = LOOP_MODE_INVALID;
maybe_mode_out = LoopMode_Unknown;
delay_out = 0;
}
}
Expand Down
12 changes: 12 additions & 0 deletions src/backend/internal/GraphLoopChannel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,18 @@ void GraphLoopChannel::disconnect_output_port(shoop_shared_ptr<GraphPort> port,
get_backend().set_graph_node_changes_pending();
}

void GraphLoopChannel::disconnect_port(shoop_shared_ptr<GraphPort> port, bool thread_safe) {
auto in_locked = mp_input_port_mapping.lock();
auto out_locked = mp_output_port_mapping.lock();
if (in_locked && in_locked == port) {
mp_input_port_mapping.reset();
} else if (out_locked && out_locked == port) {
mp_output_port_mapping.reset();
} else {
throw std::runtime_error("Attempting to disconnect unconnected port");
}
}

void GraphLoopChannel::disconnect_output_ports(bool thread_safe) {
mp_output_port_mapping.reset();
get_backend().set_graph_node_changes_pending();
Expand Down
1 change: 1 addition & 0 deletions src/backend/internal/GraphLoopChannel.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class GraphLoopChannel: public HasTwoGraphNodes,

void connect_output_port(shoop_shared_ptr<GraphPort> port, bool thread_safe=true);
void connect_input_port(shoop_shared_ptr<GraphPort> port, bool thread_safe=true);
void disconnect_port(shoop_shared_ptr<GraphPort> port, bool thread_safe=true);
void disconnect_output_port(shoop_shared_ptr<GraphPort> port, bool thread_safe=true);
void disconnect_output_ports(bool thread_safe=true);
void disconnect_input_port(shoop_shared_ptr<GraphPort> port, bool thread_safe=true);
Expand Down
39 changes: 38 additions & 1 deletion src/backend/libshoopdaloop_backend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -630,6 +630,20 @@ void disconnect_audio_output (shoopdaloop_loop_audio_channel_t *channel, shoopda
});
}

void disconnect_audio_port (shoopdaloop_loop_audio_channel_t *channel, shoopdaloop_audio_port_t* port) {
return api_impl<void>("disconnect_audio_output", [&]() {
auto _chan = internal_audio_channel(channel);
if (!_chan) { return; }
_chan->get_backend().queue_process_thread_command([=]() {
auto _port = internal_audio_port(port);
auto _channel = internal_audio_channel(channel);
if (_port && _channel) {
_channel->disconnect_port(_port, false);
}
});
});
}

void disconnect_midi_output (shoopdaloop_loop_midi_channel_t *channel, shoopdaloop_midi_port_t* port) {
return api_impl<void>("disconnect_midi_output", [&]() {
auto _chan = internal_midi_channel(channel);
Expand All @@ -644,6 +658,20 @@ void disconnect_midi_output (shoopdaloop_loop_midi_channel_t *channel, shoopdal
});
}

void disconnect_midi_port (shoopdaloop_loop_midi_channel_t *channel, shoopdaloop_midi_port_t* port) {
return api_impl<void>("disconnect_midi_output", [&]() {
auto _chan = internal_midi_channel(channel);
if (!_chan) { return; }
_chan->get_backend().queue_process_thread_command([=]() {
auto _port = internal_midi_port(port);
auto _channel = internal_midi_channel(channel);
if (_port && _channel) {
_channel->disconnect_port(_port, false);
}
});
});
}

void disconnect_audio_outputs (shoopdaloop_loop_audio_channel_t *channel) {
return api_impl<void>("disconnect_audio_outputs", [&]() {
auto _chan = internal_audio_channel(channel);
Expand Down Expand Up @@ -1907,7 +1935,7 @@ void destroy_midi_channel(shoopdaloop_loop_midi_channel_t *d) {

void destroy_shoopdaloop_decoupled_midi_port(shoopdaloop_decoupled_midi_port_t *d) {
return api_impl<void, log_level_debug_trace, log_level_warning>("destroy_shoopdaloop_decoupled_midi_port", [&]() {
logging::log<"Backend.API", log_level_error>(std::nullopt, std::nullopt, "destroy_shoopdaloop_decoupled_midi_port");
logging::log<"Backend.API", log_level_debug>(std::nullopt, std::nullopt, "destroy_shoopdaloop_decoupled_midi_port");
throw std::runtime_error("unimplemented");
});
}
Expand Down Expand Up @@ -2265,6 +2293,15 @@ void destroy_audio_driver_state(shoop_audio_driver_state_t *state) {
});
}

void destroy_audio_driver(shoop_audio_driver_t *driver) {
return api_impl<void, log_level_debug_trace>("destroy_audio_driver", [&]() {
auto _driver = internal_audio_driver(driver);
if (!_driver) { return; }
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: potential memory leak - should delete the driver pointer after closing and removing from active drivers

_driver->close();
g_active_drivers.erase(_driver);
Comment on lines +2300 to +2301
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: close() should be called after removing from g_active_drivers to prevent race conditions if close triggers callbacks

});
}

unsigned get_driver_active(shoop_audio_driver_t *driver) {
return api_impl<unsigned>("get_driver_active", [&]() {
auto _driver = internal_audio_driver(driver);
Expand Down
2 changes: 2 additions & 0 deletions src/backend/libshoopdaloop_backend.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ SHOOP_EXPORT void disconnect_audio_inputs (shoopdaloop_loop_au
SHOOP_EXPORT void disconnect_midi_inputs (shoopdaloop_loop_midi_channel_t *channel);
SHOOP_EXPORT void disconnect_audio_input (shoopdaloop_loop_audio_channel_t *channel, shoopdaloop_audio_port_t* port);
SHOOP_EXPORT void disconnect_midi_input (shoopdaloop_loop_midi_channel_t *channel, shoopdaloop_midi_port_t* port);
SHOOP_EXPORT void disconnect_audio_port (shoopdaloop_loop_audio_channel_t *channel, shoopdaloop_audio_port_t* port);
SHOOP_EXPORT void disconnect_midi_port (shoopdaloop_loop_midi_channel_t *channel, shoopdaloop_midi_port_t* port);
SHOOP_EXPORT shoop_audio_channel_data_t *get_audio_channel_data (shoopdaloop_loop_audio_channel_t *channel);
SHOOP_EXPORT shoop_midi_sequence_t *get_midi_channel_data (shoopdaloop_loop_midi_channel_t *channel);
SHOOP_EXPORT void load_audio_channel_data (shoopdaloop_loop_audio_channel_t *channel, shoop_audio_channel_data_t *data);
Expand Down
Loading
Loading