Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
SanderVocke committed Nov 26, 2024
1 parent f3a5d0a commit 6b99698
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 86 deletions.
78 changes: 11 additions & 67 deletions src/python/shoopdaloop/lib/backend_wrappers.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,15 @@ class PortConnectability(Enum):
class BackendResult(Enum):
Success = bindings.Success
Failure = bindings.Failure
class LoopMode(Enum):
Unknown = bindings.LoopMode_Unknown
Stopped = bindings.LoopMode_Stopped
Playing = bindings.LoopMode_Playing
Recording = bindings.LoopMode_Recording
Replacing = bindings.LoopMode_Replacing
PlayingDryThroughWet = bindings.LoopMode_PlayingDryThroughWet
RecordingDryIntoWet = bindings.LoopMode_RecordingDryIntoWet

class PyLoopMode(Enum):
Unknown = int(shoop_py_backend.LoopMode.Unknown)
Stopped = int(shoop_py_backend.LoopMode.Stopped)
Playing = int(shoop_py_backend.LoopMode.Playing)
Recording = int(shoop_py_backend.LoopMode.Recording)
Replacing = int(shoop_py_backend.LoopMode.Replacing)
PlayingDryThroughWet = int(shoop_py_backend.LoopMode.PlayingDryThroughWet)
RecordingDryIntoWet = int(shoop_py_backend.LoopMode.RecordingDryIntoWet)

class ChannelMode(Enum):
Disabled = bindings.ChannelMode_Disabled
Expand Down Expand Up @@ -568,63 +569,6 @@ def reset_state_tracking(self):
if self.available():
bindings.reset_midi_channel_state_tracking(self.get_backend_obj())

class BackendLoop:
def __init__(self, backend_session):
self._obj = shoop_py_backend.Loop(backend_session._obj)

def available(self):
return self.get_backend_obj()

def get_backend_obj(self):
return self._obj

def add_audio_channel(self, mode : Type['ChannelMode']) -> 'BackendLoopAudioChannel':
return BackendLoopAudioChannel(self._obj.add_audio_channel(mode.value))

def add_midi_channel(self, mode : Type['ChannelMode']) -> 'BackendLoopMidiChannel':
return BackendLoopMidiChannel(self._obj.add_midi_channel(mode.value))

def transition(self,
to_state : Type['LoopMode'],
maybe_cycles_delay : int,
maybe_to_sync_at_cycle : int):
self._obj.transition(to_state.value, maybe_cycles_delay, maybe_to_sync_at_cycle)

# Static version for multiple loops
def transition_multiple(loops, to_state : Type['LoopMode'],
maybe_cycles_delay : int,
maybe_to_sync_at_cycle : int):
if len(loops) == 0:
return
loop_objs = [l._obj for l in loops]
shoop_py_backend.transition_multiple_loops(
loop_objs,
to_state.value,
maybe_cycles_delay,
maybe_to_sync_at_cycle)
del loop_objs

def get_state(self):
return self._obj.get_state()

def set_length(self, length):
self._obj.set_length(length)

def set_position(self, position):
self._obj.set_position(position)

def clear(self, length):
self._obj.clear(length)

def set_sync_source(self, loop):
self._obj.set_sync_source(loop._obj if loop else None)

def adopt_ringbuffer_contents(self, reverse_start_cycle, cycles_length, go_to_cycle, go_to_mode):
_reverse_start_cycle = (-1 if reverse_start_cycle == None else reverse_start_cycle)
_cycles_length = (-1 if cycles_length == None else cycles_length)
_go_to_cycle = (-1 if go_to_cycle == None else go_to_cycle)
self._obj.adopt_ringbuffer_contents(reverse_start_cycle, cycles_length, go_to_cycle, go_to_mode)

class BackendAudioPort:
def __init__(self,
obj):
Expand Down Expand Up @@ -935,9 +879,9 @@ def get_state(self):
return rval
return BackendSessionState()

def create_loop(self) -> Type['BackendLoop']:
def create_loop(self):
if self.active():
return BackendLoop(self)
return shoop_py_backend.Loop(self._obj)
return None

def create_fx_chain(self, chain_type : Type['FXChainType'], title: str) -> Type['BackendFXChain']:
Expand Down
4 changes: 2 additions & 2 deletions src/python/shoopdaloop/lib/js_constants.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from PySide6.QtQml import QJSValue

from .backend_wrappers import LoopMode, ChannelMode, AudioDriverType, PortDirection, FXChainType, PortDataType, PortConnectability, DontWaitForSync, DontAlignToSyncImmediately
from .backend_wrappers import PyLoopMode, ChannelMode, AudioDriverType, PortDirection, FXChainType, PortDataType, PortConnectability, DontWaitForSync, DontAlignToSyncImmediately
from .types import KeyEventType

# Create a QJSValue which contains a multitude of ShoopDaLoop constant
Expand All @@ -17,7 +17,7 @@ def add_enum(name, enum):

rval.setProperty(name, enum_object)

add_enum('LoopMode', LoopMode)
add_enum('LoopMode', PyLoopMode)
add_enum('ChannelMode', ChannelMode)
add_enum('AudioDriverType', AudioDriverType)
add_enum('PortDirection', PortDirection)
Expand Down
16 changes: 8 additions & 8 deletions src/python/shoopdaloop/lib/mode_helpers.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
from .backend_wrappers import *
from shoop_py_backend import LoopMode

def is_playing_mode(mode):
return mode in [LoopMode.Playing.value, LoopMode.PlayingDryThroughWet.value]
return mode in [int(LoopMode.Playing), int(LoopMode.PlayingDryThroughWet)]

def is_recording_mode(mode):
return mode in [LoopMode.Recording.value, LoopMode.RecordingDryIntoWet.value]
return mode in [int(LoopMode.Recording), int(LoopMode.RecordingDryIntoWet)]

def is_running_mode(mode):
return mode in [
LoopMode.Playing.value,
LoopMode.Replacing.value,
LoopMode.Recording.value,
LoopMode.RecordingDryIntoWet.value,
LoopMode.PlayingDryThroughWet.value
int(LoopMode.Playing),
int(LoopMode.Replacing),
int(LoopMode.Recording),
int(LoopMode.RecordingDryIntoWet),
int(LoopMode.PlayingDryThroughWet)
]
4 changes: 2 additions & 2 deletions src/python/shoopdaloop/lib/q_objects/ControlHandler.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

from ..logging import Logger
from ..lua_qobject_interface import lua_passthrough, qt_typename, lua_int, lua_bool, lua_str, lua_float, lua_callable
from ..backend_wrappers import LoopMode, DontAlignToSyncImmediately, DontWaitForSync
from ..backend_wrappers import PyLoopMode, DontAlignToSyncImmediately, DontWaitForSync

def as_loop_selector(lua_val):
def iscoords(l):
Expand Down Expand Up @@ -197,7 +197,7 @@ def generate_loop_mode_constants():
# RecordingDryIntoWet
# @shoop_lua_enum_docstring.end
rval = []
for i in list(LoopMode):
for i in list(PyLoopMode):
rval.append(['LoopMode_' + i.name, i.value])
return rval

Expand Down
17 changes: 10 additions & 7 deletions src/python/shoopdaloop/lib/q_objects/Loop.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
from ..findChildItems import findChildItems
from .Logger import Logger

from shoop_py_backend import Loop as BackendLoop
from shoop_py_backend import LoopMode, transition_multiple_loops

import traceback

# Wraps a back-end loop.
Expand All @@ -30,8 +33,8 @@ class Loop(FindParentBackend):
def __init__(self, parent=None):
super(Loop, self).__init__(parent)
self._position = 0
self._mode = LoopMode.Unknown.value
self._next_mode = LoopMode.Unknown.value
self._mode = int(LoopMode.Unknown)
self._next_mode = int(LoopMode.Unknown)
self._next_transition_delay = -1
self._length = self._new_length = 0
self._sync_source = None
Expand Down Expand Up @@ -248,7 +251,7 @@ def updateOnOtherThread(self):
self._display_midi_events_triggered = (sum([c._n_events_triggered for c in midi_chans]) if len(midi_chans) > 0 else 0)

if prev_mode != self._mode:
self.logger.debug(lambda: 'mode -> {}'.format(LoopMode(self._mode)))
self.logger.debug(lambda: 'mode -> {}'.format(PyLoopMode(self._mode)))
self.modeChangedUnsafe.emit(self._mode)
if prev_length != self._length:
self.logger.trace(lambda: 'length -> {}'.format(self._length))
Expand All @@ -257,7 +260,7 @@ def updateOnOtherThread(self):
self.logger.trace(lambda: 'pos -> {}'.format(self._position))
self.positionChangedUnsafe.emit(self._position)
if prev_next_mode != self._next_mode:
self.logger.debug(lambda: 'next mode -> {}'.format(LoopMode(self._next_mode)))
self.logger.debug(lambda: 'next mode -> {}'.format(PyLoopMode(self._next_mode)))
self.nextModeChangedUnsafe.emit(self._next_mode)
if prev_next_delay != self._next_transition_delay:
self.logger.debug(lambda: 'next transition -> {}'.format(self._next_transition_delay))
Expand Down Expand Up @@ -313,7 +316,7 @@ def transition_multiple(self, loops, mode, maybe_delay, maybe_align_to_sync_at):
def transition_multiple_impl(self, loops, mode, maybe_delay, maybe_align_to_sync_at):
if self._initialized:
backend_loops = [l._backend_loop for l in loops]
BackendLoop.transition_multiple(backend_loops, LoopMode(mode), maybe_delay, maybe_align_to_sync_at)
transition_multiple_loops(backend_loops, mode, maybe_delay, maybe_align_to_sync_at)

@ShoopSlot('QVariant', 'QVariant', 'QVariant', int)
def adopt_ringbuffers(self, reverse_start_cycle, cycles_length, go_to_cycle, go_to_mode):
Expand All @@ -335,13 +338,13 @@ def clear(self, length):
def add_audio_channel(self, mode):
if self.initialized:
self.logger.debug(lambda: 'add audio channel')
return self._backend_loop.add_audio_channel(ChannelMode(mode))
return BackendLoopAudioChannel(self._backend_loop.add_audio_channel(mode))

@ShoopSlot(int, result=BackendLoopMidiChannel)
def add_midi_channel(self, mode):
if self.initialized:
self.logger.debug(lambda: 'add midi channel')
return self._backend_loop.add_midi_channel(ChannelMode(mode))
return BackendLoopMidiChannel(self._backend_loop.add_midi_channel(mode))

@ShoopSlot(list)
def load_audio_data(self, sound_channels):
Expand Down

0 comments on commit 6b99698

Please sign in to comment.