forked from platypush/platypush
- Support for sound "release" (removal from active stream)
- Added `query_ports` method to MIDI plugin
This commit is contained in:
parent
f2d2315610
commit
c445763979
4 changed files with 74 additions and 3 deletions
|
@ -24,13 +24,19 @@ class MidiBackend(Backend):
|
|||
def __init__(self, device_name=None, port_number=None,
|
||||
midi_throttle_time=None, *args, **kwargs):
|
||||
"""
|
||||
:param device_name: Name of the MIDI device. *N.B.* either `device_name` or `port_number` must be set
|
||||
:param device_name: Name of the MIDI device. *N.B.* either
|
||||
`device_name` or `port_number` must be set.
|
||||
Use :method:`platypush.plugins.midi.query_ports` to get the
|
||||
available ports indices and names
|
||||
:type device_name: str
|
||||
|
||||
:param port_number: MIDI port number
|
||||
:type port_number: int
|
||||
|
||||
:param midi_throttle_time: If set, the MIDI events will be throttled - max one per selected time frame (in seconds). Set this parameter if you want to synchronize MIDI events with plugins that normally operate with a lower throughput.
|
||||
:param midi_throttle_time: If set, the MIDI events will be throttled -
|
||||
max one per selected time frame (in seconds). Set this parameter if
|
||||
you want to synchronize MIDI events with plugins that normally
|
||||
operate with a lower throughput.
|
||||
:type midi_throttle_time: int
|
||||
"""
|
||||
|
||||
|
|
|
@ -120,5 +120,20 @@ class MidiPlugin(Plugin):
|
|||
self.release_note(note)
|
||||
|
||||
|
||||
@action
|
||||
def query_ports(self):
|
||||
"""
|
||||
:returns: dict: A list of the available MIDI ports with index and name
|
||||
"""
|
||||
|
||||
in_ports = rtmidi.MidiIn().get_ports()
|
||||
out_ports = rtmidi.MidiOut().get_ports()
|
||||
|
||||
return {
|
||||
'in': { i: port for i, port in enumerate(in_ports) },
|
||||
'out': { i: port for i, port in enumerate(out_ports) },
|
||||
}
|
||||
|
||||
|
||||
# vim:sw=4:ts=4:et:
|
||||
|
||||
|
|
|
@ -214,6 +214,15 @@ class Mix(object):
|
|||
self._sounds.append(Sound.build(sound))
|
||||
|
||||
|
||||
def remove(self, sound_index):
|
||||
if sound_index >= len(self._sounds):
|
||||
self.logger.error('No such sound index: {} in mix {}'.format(
|
||||
sound_index, list(self)))
|
||||
return
|
||||
|
||||
self._sounds.pop(sound_index)
|
||||
|
||||
|
||||
def get_wave(self, t_start=0., t_end=0., normalize_range=(-1.0, 1.0),
|
||||
on_clip='scale', samplerate=Sound._DEFAULT_SAMPLERATE):
|
||||
"""
|
||||
|
|
|
@ -325,7 +325,7 @@ class SoundPlugin(Plugin):
|
|||
if duration is not None else t+blocktime
|
||||
|
||||
data = mix.get_wave(t_start=t, t_end=next_t,
|
||||
samplerate=samplerate)
|
||||
samplerate=samplerate)
|
||||
t = next_t
|
||||
|
||||
if duration is not None and t >= duration:
|
||||
|
@ -706,6 +706,47 @@ class SoundPlugin(Plugin):
|
|||
self.logger.info('Recording paused state toggled')
|
||||
self.recording_paused_changed.set()
|
||||
|
||||
@action
|
||||
def release(self, stream, index=None, midi_note=None, frequency=None):
|
||||
"""
|
||||
Remove a sound from an active stream, either by sound index (use
|
||||
:method:`platypush.sound.plugin.SoundPlugin.query_streams` to get
|
||||
the sounds playing on the active streams), midi_note, frequency
|
||||
or absolute file path.
|
||||
|
||||
:param stream: Stream index
|
||||
:type stream: int
|
||||
|
||||
:param index: Sound index
|
||||
:type index: int
|
||||
|
||||
:param midi_note: MIDI note
|
||||
:type midi_note: int
|
||||
|
||||
:param frequency: Sound frequency
|
||||
:type frequency: float
|
||||
"""
|
||||
|
||||
if index is None and midi_note is None and frequency is None:
|
||||
raise RuntimeError('Please specify either a sound index, ' +
|
||||
'midi_note or frequency to release')
|
||||
|
||||
mix = self.stream_mixes.get(stream)
|
||||
if not mix:
|
||||
raise RuntimeError('No such stream: {}'.format(stream))
|
||||
|
||||
for i, sound in enumerate(mix):
|
||||
if (index is not None and i == index) or \
|
||||
(midi_note is not None
|
||||
and sound.get('midi_note') == midi_note) or \
|
||||
(frequency is not None
|
||||
and sound.get('frequency') == frequency):
|
||||
if len(list(mix)) == 1:
|
||||
# Last sound in the mix
|
||||
self.stop_playback([stream])
|
||||
else:
|
||||
mix.remove(i)
|
||||
|
||||
def _get_playback_state(self, stream_index):
|
||||
with self.playback_state_lock:
|
||||
return self.playback_state[stream_index]
|
||||
|
|
Loading…
Reference in a new issue