コード例 #1
0
ファイル: waveformeditor.py プロジェクト: datamail321/kunquat
    def __init__(self):
        super().__init__()
        self._prewarp_list = WarpList('pre', self._get_base_wave,
                                      self._get_update_signal_type)
        self._base_func_selector = KqtComboBox()
        self._postwarp_list = WarpList('post', self._get_base_wave,
                                       self._get_update_signal_type)
        self._waveform = Waveform()

        pw_layout = QVBoxLayout()
        pw_layout.setSpacing(0)
        pw_layout.addWidget(self._prewarp_list)
        pw_layout.addWidget(self._base_func_selector)
        pw_layout.addWidget(self._postwarp_list)

        ed_layout = QHBoxLayout()
        ed_layout.setSpacing(0)
        ed_layout.addLayout(pw_layout)
        ed_layout.addWidget(self._waveform)

        v = QVBoxLayout()
        v.setContentsMargins(0, 0, 0, 0)
        v.setSpacing(2)
        v.addWidget(HeaderLine('Waveshaping'))
        v.addLayout(ed_layout)
        self.setLayout(v)
コード例 #2
0
ファイル: padsynthproc.py プロジェクト: JoelDreaver/kunquat
    def __init__(self):
        super().__init__()
        self._sample_size = KqtComboBox()
        self._sample_count = QSpinBox()
        self._sample_count.setRange(1, 128)
        self._range_min = SamplePitchRangeMinEditor()
        self._range_max = SamplePitchRangeMaxEditor()
        self._centre_pitch = SampleCentrePitchEditor()

        self.add_to_updaters(self._range_min, self._range_max,
                             self._centre_pitch)

        h = QHBoxLayout()
        h.setContentsMargins(0, 0, 0, 0)
        h.setSpacing(2)
        h.addWidget(QLabel('Sample size:'))
        h.addWidget(self._sample_size)
        h.addWidget(QLabel('Sample count:'))
        h.addWidget(self._sample_count)
        h.addWidget(QLabel('Pitch range:'))
        h.addWidget(self._range_min)
        h.addWidget(self._range_max)
        h.addWidget(QLabel('Centre pitch:'))
        h.addWidget(self._centre_pitch)
        self.setLayout(h)
コード例 #3
0
ファイル: expressions.py プロジェクト: JoelDreaver/kunquat
    def __init__(self):
        super().__init__()
        self._expr_names = KqtComboBox()

        h = QHBoxLayout()
        h.setContentsMargins(0, 0, 0, 0)
        h.setSpacing(4)
        h.addWidget(QLabel('Default note expression:'))
        h.addWidget(self._expr_names, 1)
        self.setLayout(h)
コード例 #4
0
    def __init__(self):
        super().__init__()
        self._au_id = None
        self._proc_id = None
        self._ui_model = None
        self._updater = None

        self._prewarp_list = WarpList(
                'pre', self._get_base_wave, self._get_update_signal_type)
        self._base_func_selector = KqtComboBox()
        self._postwarp_list = WarpList(
                'post', self._get_base_wave, self._get_update_signal_type)
        self._waveform = Waveform()

        pw_layout = QVBoxLayout()
        pw_layout.setSpacing(0)
        pw_layout.addWidget(self._prewarp_list)
        pw_layout.addWidget(self._base_func_selector)
        pw_layout.addWidget(self._postwarp_list)

        ed_layout = QHBoxLayout()
        ed_layout.setSpacing(0)
        ed_layout.addLayout(pw_layout)
        ed_layout.addWidget(self._waveform)

        v = QVBoxLayout()
        v.setContentsMargins(0, 0, 0, 0)
        v.setSpacing(2)
        v.addWidget(HeaderLine('Waveshaping'))
        v.addLayout(ed_layout)
        self.setLayout(v)
コード例 #5
0
    def __init__(self):
        super().__init__()
        self._au_id = None
        self._proc_id = None
        self._ui_model = None
        self._updater = None

        self._sample_size = KqtComboBox()
        self._sample_count = QSpinBox()
        self._sample_count.setRange(1, 128)
        self._range_min = SamplePitchRangeMinEditor()
        self._range_max = SamplePitchRangeMaxEditor()
        self._centre_pitch = SampleCentrePitchEditor()

        h = QHBoxLayout()
        h.setContentsMargins(0, 0, 0, 0)
        h.setSpacing(2)
        h.addWidget(QLabel('Sample size:'))
        h.addWidget(self._sample_size)
        h.addWidget(QLabel('Sample count:'))
        h.addWidget(self._sample_count)
        h.addWidget(QLabel('Pitch range:'))
        h.addWidget(self._range_min)
        h.addWidget(self._range_max)
        h.addWidget(QLabel('Centre pitch:'))
        h.addWidget(self._centre_pitch)
        self.setLayout(h)
コード例 #6
0
ファイル: waveformeditor.py プロジェクト: JoelDreaver/kunquat
    def __init__(self, warp_type, index, get_base_wave,
                 get_update_signal_type):
        super().__init__()
        self._warp_type = warp_type
        self._index = index
        self._get_base_wave = get_base_wave
        self._get_update_signal_type = get_update_signal_type

        self._down_button = ProcessorIconButton()
        self._up_button = ProcessorIconButton()
        self._func_selector = KqtComboBox()
        self._slider = QSlider(Qt.Horizontal)
        self._slider.setSizePolicy(QSizePolicy.MinimumExpanding,
                                   QSizePolicy.Preferred)
        self._value_display = QLabel()
        self._remove_button = ProcessorIconButton()

        self.add_to_updaters(self._down_button, self._up_button,
                             self._remove_button)

        self._slider.setRange(-self._ARG_SCALE, self._ARG_SCALE)

        self._up_button.setEnabled(self._index != 0)

        fm = QFontMetrics(QFont())
        value_width = fm.boundingRect('{}'.format(-1.0 /
                                                  self._ARG_SCALE)).width()
        value_width += 10
        self._value_display.setFixedWidth(value_width)

        h = QHBoxLayout()
        h.setContentsMargins(0, 0, 0, 0)
        h.setSpacing(2)
        h.addWidget(self._down_button)
        h.addWidget(self._up_button)
        h.addWidget(self._func_selector)
        h.addWidget(self._slider)
        h.addWidget(self._value_display)
        h.addWidget(self._remove_button)
        self.setLayout(h)
コード例 #7
0
    def __init__(self):
        super().__init__()
        self._au_id = None
        self._ui_model = None
        self._updater = None

        self._expr_names = KqtComboBox()

        h = QHBoxLayout()
        h.setContentsMargins(0, 0, 0, 0)
        h.setSpacing(4)
        h.addWidget(QLabel('Default note expression:'))
        h.addWidget(self._expr_names, 1)
        self.setLayout(h)
コード例 #8
0
    def __init__(self):
        super().__init__()
        self._au_id = None
        self._proc_id = None
        self._ui_model = None
        self._updater = None

        self._signal_type = KqtComboBox()
        for info in self._SIGNAL_INFO:
            _, text = info
            self._signal_type.addItem(text)

        v = QHBoxLayout()
        v.setContentsMargins(4, 4, 4, 4)
        v.addWidget(HeaderFrame('Signal type', self._signal_type))
        self.setLayout(v)
コード例 #9
0
    def __init__(self, warp_type, index, get_base_wave, get_update_signal_type):
        super().__init__()
        self._au_id = None
        self._proc_id = None
        self._ui_model = None
        self._updater = None

        self._warp_type = warp_type
        self._index = index
        self._get_base_wave = get_base_wave
        self._get_update_signal_type = get_update_signal_type

        self._down_button = SmallButton()
        self._up_button = SmallButton()
        self._func_selector = KqtComboBox()
        self._slider = QSlider(Qt.Horizontal)
        self._slider.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Preferred)
        self._value_display = QLabel()
        self._remove_button = SmallButton()

        self._slider.setRange(-self._ARG_SCALE, self._ARG_SCALE)

        self._up_button.setEnabled(self._index != 0)

        fm = QFontMetrics(QFont())
        value_width = fm.boundingRect('{}'.format(-1.0 / self._ARG_SCALE)).width()
        value_width += 10
        self._value_display.setFixedWidth(value_width)

        h = QHBoxLayout()
        h.setContentsMargins(0, 0, 0, 0)
        h.setSpacing(2)
        h.addWidget(self._down_button)
        h.addWidget(self._up_button)
        h.addWidget(self._func_selector)
        h.addWidget(self._slider)
        h.addWidget(self._value_display)
        h.addWidget(self._remove_button)
        self.setLayout(h)
コード例 #10
0
ファイル: padsynthproc.py プロジェクト: JoelDreaver/kunquat
class SampleConfigEditor(QWidget, ProcessorUpdater):
    def __init__(self):
        super().__init__()
        self._sample_size = KqtComboBox()
        self._sample_count = QSpinBox()
        self._sample_count.setRange(1, 128)
        self._range_min = SamplePitchRangeMinEditor()
        self._range_max = SamplePitchRangeMaxEditor()
        self._centre_pitch = SampleCentrePitchEditor()

        self.add_to_updaters(self._range_min, self._range_max,
                             self._centre_pitch)

        h = QHBoxLayout()
        h.setContentsMargins(0, 0, 0, 0)
        h.setSpacing(2)
        h.addWidget(QLabel('Sample size:'))
        h.addWidget(self._sample_size)
        h.addWidget(QLabel('Sample count:'))
        h.addWidget(self._sample_count)
        h.addWidget(QLabel('Pitch range:'))
        h.addWidget(self._range_min)
        h.addWidget(self._range_max)
        h.addWidget(QLabel('Centre pitch:'))
        h.addWidget(self._centre_pitch)
        self.setLayout(h)

    def _on_setup(self):
        self.register_action('signal_au', self._update_sample_params)
        self.register_action(self._get_update_signal_type(),
                             self._update_sample_params)
        self.register_action('signal_style_changed', self._update_style)

        for sample_length in self._get_params().get_allowed_sample_lengths():
            self._sample_size.addItem(str(sample_length),
                                      userData=sample_length)

        self._sample_size.currentIndexChanged.connect(self._change_sample_size)

        self._sample_count.valueChanged.connect(self._change_sample_count)

        self._update_style()
        self._update_sample_params()

    def _get_update_signal_type(self):
        return 'signal_padsynth_{}'.format(self._proc_id)

    def _get_params(self):
        return utils.get_proc_params(self._ui_model, self._au_id,
                                     self._proc_id)

    def _update_style(self):
        style_mgr = self._ui_model.get_style_manager()
        self.layout().setSpacing(
            style_mgr.get_scaled_size_param('small_padding'))

    def _update_sample_params(self):
        params = self._get_params()

        old_block = self._sample_size.blockSignals(True)
        new_sample_size = params.get_sample_length()
        if (self._sample_size.itemData(self._sample_size.currentIndex()) !=
                new_sample_size):
            self._sample_size.setCurrentIndex(
                self._sample_size.findData(new_sample_size))
        self._sample_size.blockSignals(old_block)

        old_block = self._sample_count.blockSignals(True)
        new_sample_count = params.get_sample_count()
        if self._sample_count.value() != new_sample_count:
            self._sample_count.setValue(new_sample_count)
        self._sample_count.blockSignals(old_block)

    def _change_sample_size(self, index):
        sample_size = self._sample_size.itemData(index)
        self._get_params().set_sample_length(sample_size)
        self._updater.signal_update(self._get_update_signal_type())

    def _change_sample_count(self, count):
        params = self._get_params()
        params.set_sample_count(count)
        self._updater.signal_update(self._get_update_signal_type())
コード例 #11
0
ファイル: expressions.py プロジェクト: JoelDreaver/kunquat
class DefaultNoteExpr(QWidget, AudioUnitUpdater):
    def __init__(self):
        super().__init__()
        self._expr_names = KqtComboBox()

        h = QHBoxLayout()
        h.setContentsMargins(0, 0, 0, 0)
        h.setSpacing(4)
        h.addWidget(QLabel('Default note expression:'))
        h.addWidget(self._expr_names, 1)
        self.setLayout(h)

    def _on_setup(self):
        self.register_action(self._get_list_update_signal_type(),
                             self._update_contents)
        self.register_action(self._get_default_update_signal_type(),
                             self._update_contents)
        self.register_action('signal_style_changed', self._update_style)

        self._expr_names.currentIndexChanged.connect(self._change_expression)

        self._update_style()
        self._update_contents()

    def _get_list_update_signal_type(self):
        return 'signal_expr_list_{}'.format(self._au_id)

    def _get_default_update_signal_type(self):
        return 'signal_expr_default_{}'.format(self._au_id)

    def _get_audio_unit(self):
        module = self._ui_model.get_module()
        au = module.get_audio_unit(self._au_id)
        return au

    def _update_style(self):
        style_mgr = self._ui_model.get_style_manager()
        self.layout().setSpacing(
            style_mgr.get_scaled_size_param('medium_padding'))

    def _update_contents(self):
        au = self._get_audio_unit()
        names = sorted(au.get_expression_names())
        selection = au.get_default_note_expression()

        old_block = self._expr_names.blockSignals(True)
        self._expr_names.setEnabled(len(names) > 0)
        self._expr_names.set_items(chain(['(none)'], (name for name in names)))
        try:
            self._expr_names.setCurrentIndex(names.index(selection) + 1)
        except ValueError:
            self._expr_names.setCurrentIndex(0)
        self._expr_names.blockSignals(old_block)

    def _change_expression(self, item_index):
        au = self._get_audio_unit()
        if item_index == 0:
            au.set_default_note_expression('')
        else:
            expr_name = self._expr_names.itemText(item_index)
            au.set_default_note_expression(expr_name)
コード例 #12
0
class WarpEditor(QWidget):

    _ARG_SCALE = 1000

    def __init__(self, warp_type, index, get_base_wave, get_update_signal_type):
        super().__init__()
        self._au_id = None
        self._proc_id = None
        self._ui_model = None
        self._updater = None

        self._warp_type = warp_type
        self._index = index
        self._get_base_wave = get_base_wave
        self._get_update_signal_type = get_update_signal_type

        self._down_button = SmallButton()
        self._up_button = SmallButton()
        self._func_selector = KqtComboBox()
        self._slider = QSlider(Qt.Horizontal)
        self._slider.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Preferred)
        self._value_display = QLabel()
        self._remove_button = SmallButton()

        self._slider.setRange(-self._ARG_SCALE, self._ARG_SCALE)

        self._up_button.setEnabled(self._index != 0)

        fm = QFontMetrics(QFont())
        value_width = fm.boundingRect('{}'.format(-1.0 / self._ARG_SCALE)).width()
        value_width += 10
        self._value_display.setFixedWidth(value_width)

        h = QHBoxLayout()
        h.setContentsMargins(0, 0, 0, 0)
        h.setSpacing(2)
        h.addWidget(self._down_button)
        h.addWidget(self._up_button)
        h.addWidget(self._func_selector)
        h.addWidget(self._slider)
        h.addWidget(self._value_display)
        h.addWidget(self._remove_button)
        self.setLayout(h)

    def set_au_id(self, au_id):
        self._au_id = au_id

    def set_proc_id(self, proc_id):
        self._proc_id = proc_id

    def set_ui_model(self, ui_model):
        self._ui_model = ui_model
        self._updater = ui_model.get_updater()
        self._updater.register_updater(self._perform_updates)

        icon_bank = self._ui_model.get_icon_bank()
        self._down_button.setIcon(QIcon(icon_bank.get_icon_path('arrow_down_small')))
        self._up_button.setIcon(QIcon(icon_bank.get_icon_path('arrow_up_small')))
        self._remove_button.setIcon(QIcon(icon_bank.get_icon_path('delete_small')))

        base_wave = self._get_base_wave()

        func_names = base_wave.get_warp_func_names(self._warp_type)
        self._func_selector.set_items(name for name in func_names)

        self._update_all()

        QObject.connect(self._down_button, SIGNAL('clicked()'), self._moved_down)
        QObject.connect(self._up_button, SIGNAL('clicked()'), self._moved_up)
        QObject.connect(
                self._func_selector,
                SIGNAL('currentIndexChanged(int)'),
                self._func_selected)
        QObject.connect(self._slider, SIGNAL('valueChanged(int)'), self._slider_adjusted)
        QObject.connect(self._remove_button, SIGNAL('clicked()'), self._removed)

    def unregister_updaters(self):
        self._updater.unregister_updater(self._perform_updates)

    def _perform_updates(self, signals):
        update_signals = set(['signal_au', self._get_update_signal_type()])
        if not signals.isdisjoint(update_signals):
            self._update_all()

    def _update_all(self):
        base_wave = self._get_base_wave()

        warp_func_count = base_wave.get_warp_func_count(self._warp_type)

        if self._index >= warp_func_count:
            # We have been removed
            return

        self._down_button.setEnabled(self._index < warp_func_count - 1)

        name, arg = base_wave.get_warp_func(self._warp_type, self._index)

        old_block = self._func_selector.blockSignals(True)
        for i in range(self._func_selector.count()):
            if self._func_selector.itemText(i) == name:
                self._func_selector.setCurrentIndex(i)
                break
        self._func_selector.blockSignals(old_block)

        old_block = self._slider.blockSignals(True)
        int_val = int(round(arg * self._ARG_SCALE))
        self._slider.setValue(int_val)
        self._slider.blockSignals(old_block)

        self._value_display.setText(str(float(arg)))

    def _moved_down(self):
        base_wave = self._get_base_wave()
        base_wave.move_warp_func(self._warp_type, self._index, self._index + 1)
        self._updater.signal_update(set([self._get_update_signal_type()]))

    def _moved_up(self):
        base_wave = self._get_base_wave()
        base_wave.move_warp_func(self._warp_type, self._index, self._index - 1)
        self._updater.signal_update(set([self._get_update_signal_type()]))

    def _set_warp(self):
        base_wave = self._get_base_wave()
        name = str(self._func_selector.currentText())
        arg = self._slider.value() / float(self._ARG_SCALE)
        base_wave.set_warp_func(self._warp_type, self._index, name, arg)
        self._updater.signal_update(set([self._get_update_signal_type()]))

    def _func_selected(self, index):
        self._set_warp()

    def _slider_adjusted(self, int_val):
        self._set_warp()

    def _removed(self):
        base_wave = self._get_base_wave()
        base_wave.remove_warp_func(self._warp_type, self._index)
        self._updater.signal_update(set([self._get_update_signal_type()]))
コード例 #13
0
ファイル: waveformeditor.py プロジェクト: kagu/kunquat
class WaveformEditor(QWidget, ProcessorUpdater):

    def __init__(self):
        super().__init__()
        self._prewarp_list = WarpList(
                'pre', self._get_base_wave, self._get_update_signal_type)
        self._base_func_selector = KqtComboBox()
        self._postwarp_list = WarpList(
                'post', self._get_base_wave, self._get_update_signal_type)
        self._waveform = Waveform()

        pw_layout = QVBoxLayout()
        pw_layout.setSpacing(0)
        pw_layout.addWidget(self._prewarp_list)
        pw_layout.addWidget(self._base_func_selector)
        pw_layout.addWidget(self._postwarp_list)

        ed_layout = QHBoxLayout()
        ed_layout.setSpacing(0)
        ed_layout.addLayout(pw_layout)
        ed_layout.addWidget(self._waveform)

        self._header = HeaderLine('Waveshaping')

        v = QVBoxLayout()
        v.setContentsMargins(0, 0, 0, 0)
        v.setSpacing(2)
        v.addWidget(self._header)
        v.addLayout(ed_layout)
        self.setLayout(v)

    def _on_setup(self):
        self.add_to_updaters(self._prewarp_list, self._postwarp_list)
        self.register_action('signal_au', self._update_all)
        self.register_action(self._get_update_signal_type(), self._update_all)
        self.register_action('signal_style_changed', self._update_style)

        self._update_style()
        self._update_all()

        self._base_func_selector.currentIndexChanged.connect(self._base_func_selected)

    def _update_style(self):
        style_mgr = self._ui_model.get_style_manager()

        self._header.update_style(style_mgr)
        self.layout().setSpacing(style_mgr.get_scaled_size_param('small_padding'))

        def get_colour(name):
            return QColor(style_mgr.get_style_param(name))

        disabled_colour = QColor(get_colour('bg_colour'))
        disabled_colour.setAlpha(0x7f)

        config = {
            'bg_colour': get_colour('waveform_bg_colour'),
            'centre_line_colour': get_colour('waveform_centre_line_colour'),
            'waveform_colour': get_colour('waveform_zoomed_out_colour'),
            'disabled_colour': disabled_colour,
            'line_thickness' : style_mgr.get_scaled_size(0.1),
        }

        self._waveform.set_config(config)

    def _update_all(self):
        base_wave = self._get_base_wave()

        selected_base_func = base_wave.get_waveform_func()
        enable_warps = (selected_base_func != None)

        self._prewarp_list.setEnabled(enable_warps)

        old_block = self._base_func_selector.blockSignals(True)
        func_names = list(base_wave.get_waveform_func_names())
        if not selected_base_func:
            func_names.append('Custom')
        self._base_func_selector.set_items(func_names)
        self._base_func_selector.setCurrentIndex(
                self._base_func_selector.findText(selected_base_func or 'Custom'))
        self._base_func_selector.blockSignals(old_block)

        self._postwarp_list.setEnabled(enable_warps)

        self._waveform.set_waveform(base_wave.get_waveform())

    def _base_func_selected(self, index):
        base_wave = self._get_base_wave()
        func_names = base_wave.get_waveform_func_names()
        base_wave.set_waveform_func(func_names[index])
        self._updater.signal_update(self._get_update_signal_type())

    # Protected interface

    def _get_base_wave(self):
        raise NotImplementedError

    def _get_update_signal_type(self):
        raise NotImplementedError
コード例 #14
0
class WaveformEditor(QWidget):

    def __init__(self):
        super().__init__()
        self._au_id = None
        self._proc_id = None
        self._ui_model = None
        self._updater = None

        self._prewarp_list = WarpList(
                'pre', self._get_base_wave, self._get_update_signal_type)
        self._base_func_selector = KqtComboBox()
        self._postwarp_list = WarpList(
                'post', self._get_base_wave, self._get_update_signal_type)
        self._waveform = Waveform()

        pw_layout = QVBoxLayout()
        pw_layout.setSpacing(0)
        pw_layout.addWidget(self._prewarp_list)
        pw_layout.addWidget(self._base_func_selector)
        pw_layout.addWidget(self._postwarp_list)

        ed_layout = QHBoxLayout()
        ed_layout.setSpacing(0)
        ed_layout.addLayout(pw_layout)
        ed_layout.addWidget(self._waveform)

        v = QVBoxLayout()
        v.setContentsMargins(0, 0, 0, 0)
        v.setSpacing(2)
        v.addWidget(HeaderLine('Waveshaping'))
        v.addLayout(ed_layout)
        self.setLayout(v)

    def set_au_id(self, au_id):
        self._au_id = au_id
        self._prewarp_list.set_au_id(au_id)
        self._postwarp_list.set_au_id(au_id)

    def set_proc_id(self, proc_id):
        self._proc_id = proc_id
        self._prewarp_list.set_proc_id(proc_id)
        self._postwarp_list.set_proc_id(proc_id)

    def set_ui_model(self, ui_model):
        self._ui_model = ui_model
        self._prewarp_list.set_ui_model(ui_model)
        self._postwarp_list.set_ui_model(ui_model)

        self._updater = ui_model.get_updater()
        self._updater.register_updater(self._perform_updates)
        self._update_style()
        self._update_all()

        QObject.connect(
                self._base_func_selector,
                SIGNAL('currentIndexChanged(int)'),
                self._base_func_selected)

    def unregister_updaters(self):
        self._updater.unregister_updater(self._perform_updates)
        self._prewarp_list.unregister_updaters()
        self._postwarp_list.unregister_updaters()

    def _perform_updates(self, signals):
        update_signals = set(['signal_au', self._get_update_signal_type()])
        if not signals.isdisjoint(update_signals):
            self._update_all()
        if 'signal_style_changed' in signals:
            self._update_style()

    def _update_style(self):
        style_manager = self._ui_model.get_style_manager()
        if not style_manager.is_custom_style_enabled():
            self._waveform.set_config({})
            return

        def get_colour(name):
            return QColor(style_manager.get_style_param(name))

        disabled_colour = QColor(get_colour('bg_colour'))
        disabled_colour.setAlpha(0x7f)

        config = {
            'bg_colour': get_colour('waveform_bg_colour'),
            'centre_line_colour': get_colour('waveform_centre_line_colour'),
            'waveform_colour': get_colour('waveform_zoomed_out_colour'),
            'disabled_colour': disabled_colour,
        }

        self._waveform.set_config(config)

    def _update_all(self):
        base_wave = self._get_base_wave()

        selected_base_func = base_wave.get_waveform_func()
        enable_warps = (selected_base_func != None)

        self._prewarp_list.setEnabled(enable_warps)

        old_block = self._base_func_selector.blockSignals(True)
        func_names = list(base_wave.get_waveform_func_names())
        if not selected_base_func:
            func_names.append('Custom')
        self._base_func_selector.set_items(func_names)
        self._base_func_selector.setCurrentIndex(
                self._base_func_selector.findText(selected_base_func or 'Custom'))
        self._base_func_selector.blockSignals(old_block)

        self._postwarp_list.setEnabled(enable_warps)

        self._waveform.set_waveform(base_wave.get_waveform())

    def _base_func_selected(self, index):
        base_wave = self._get_base_wave()
        func_names = base_wave.get_waveform_func_names()
        base_wave.set_waveform_func(func_names[index])
        self._updater.signal_update(set([self._get_update_signal_type()]))

    # Protected interface

    def _get_base_wave(self):
        raise NotImplementedError

    def _get_update_signal_type(self):
        raise NotImplementedError
コード例 #15
0
class DefaultNoteExpr(QWidget):

    def __init__(self):
        super().__init__()
        self._au_id = None
        self._ui_model = None
        self._updater = None

        self._expr_names = KqtComboBox()

        h = QHBoxLayout()
        h.setContentsMargins(0, 0, 0, 0)
        h.setSpacing(4)
        h.addWidget(QLabel('Default note expression:'))
        h.addWidget(self._expr_names, 1)
        self.setLayout(h)

    def set_au_id(self, au_id):
        self._au_id = au_id

    def set_ui_model(self, ui_model):
        self._ui_model = ui_model
        self._updater = ui_model.get_updater()
        self._updater.register_updater(self._perform_updates)

        QObject.connect(
                self._expr_names,
                SIGNAL('currentIndexChanged(int)'),
                self._change_expression)

        self._update_contents()

    def unregister_updaters(self):
        self._updater.unregister_updater(self._perform_updates)

    def _get_list_update_signal_type(self):
        return 'signal_expr_list_{}'.format(self._au_id)

    def _get_default_update_signal_type(self):
        return 'signal_expr_default_{}'.format(self._au_id)

    def _perform_updates(self, signals):
        update_signals = set([
            self._get_list_update_signal_type(), self._get_default_update_signal_type()])
        if not signals.isdisjoint(update_signals):
            self._update_contents()

    def _get_audio_unit(self):
        module = self._ui_model.get_module()
        au = module.get_audio_unit(self._au_id)
        return au

    def _update_contents(self):
        au = self._get_audio_unit()
        names = sorted(au.get_expression_names())
        selection = au.get_default_note_expression()

        old_block = self._expr_names.blockSignals(True)
        self._expr_names.setEnabled(len(names) > 0)
        self._expr_names.set_items(chain(['(none)'], (name for name in names)))
        try:
            self._expr_names.setCurrentIndex(names.index(selection) + 1)
        except ValueError:
            self._expr_names.setCurrentIndex(0)
        self._expr_names.blockSignals(old_block)

    def _change_expression(self, item_index):
        au = self._get_audio_unit()
        if item_index == 0:
            au.set_default_note_expression('')
        else:
            expr_name = self._expr_names.itemText(item_index)
            au.set_default_note_expression(expr_name)
コード例 #16
0
class Signals(QWidget):

    _SIGNAL_INFO = [
        ('voice', 'Voice signals'),
        ('mixed', 'Mixed signals'),
    ]

    def __init__(self):
        super().__init__()
        self._au_id = None
        self._proc_id = None
        self._ui_model = None
        self._updater = None

        self._signal_type = KqtComboBox()
        for info in self._SIGNAL_INFO:
            _, text = info
            self._signal_type.addItem(text)

        v = QHBoxLayout()
        v.setContentsMargins(4, 4, 4, 4)
        v.addWidget(HeaderFrame('Signal type', self._signal_type))
        self.setLayout(v)

    def set_au_id(self, au_id):
        self._au_id = au_id

    def set_proc_id(self, proc_id):
        self._proc_id = proc_id

    def set_ui_model(self, ui_model):
        self._ui_model = ui_model
        self._updater = ui_model.get_updater()
        self._updater.register_updater(self._perform_updates)
        self._update_settings()

        QObject.connect(
                self._signal_type,
                SIGNAL('currentIndexChanged(int)'),
                self._signal_type_changed)

    def unregister_updaters(self):
        self._updater.unregister_updater(self._perform_updates)

    def _get_update_signal_type(self):
        return '_'.join(('signal_proc_signals', self._proc_id))

    def _get_connections_signal_type(self):
        return '_'.join(('signal_connections', self._au_id))

    def _perform_updates(self, signals):
        update_signals = set([
            self._get_update_signal_type(), self._get_connections_signal_type()])
        if not signals.isdisjoint(update_signals):
            self._update_settings()

    def _update_settings(self):
        module = self._ui_model.get_module()
        au = module.get_audio_unit(self._au_id)
        proc = au.get_processor(self._proc_id)

        # Don't try to update if we have been removed
        if not proc.get_existence():
            return

        connections = au.get_connections()
        signal_type = proc.get_signal_type()

        # Update signal type selector
        old_block = self._signal_type.blockSignals(True)
        type_names = [info[0] for info in self._SIGNAL_INFO]
        index = type_names.index(signal_type)
        assert 0 <= index < len(self._SIGNAL_INFO)
        self._signal_type.setCurrentIndex(index)
        self._signal_type.blockSignals(old_block)

    def _signal_type_changed(self, index):
        module = self._ui_model.get_module()
        au = module.get_audio_unit(self._au_id)
        proc = au.get_processor(self._proc_id)

        new_signal_type = self._SIGNAL_INFO[index][0]

        update_signals = set([
            self._get_update_signal_type(), self._get_connections_signal_type()])

        proc.set_signal_type(new_signal_type)
        self._updater.signal_update(update_signals)
コード例 #17
0
ファイル: waveformeditor.py プロジェクト: kagu/kunquat
class WarpEditor(QWidget, ProcessorUpdater):

    _ARG_SCALE = 1000

    def __init__(self, warp_type, index, get_base_wave, get_update_signal_type):
        super().__init__()
        self._warp_type = warp_type
        self._index = index
        self._get_base_wave = get_base_wave
        self._get_update_signal_type = get_update_signal_type

        self._down_button = ProcessorIconButton()
        self._up_button = ProcessorIconButton()
        self._func_selector = KqtComboBox()
        self._slider = QSlider(Qt.Horizontal)
        self._slider.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Preferred)
        self._value_display = QLabel()
        self._remove_button = ProcessorIconButton()

        self.add_to_updaters(self._down_button, self._up_button, self._remove_button)

        self._slider.setRange(-self._ARG_SCALE, self._ARG_SCALE)

        self._up_button.setEnabled(self._index != 0)

        fm = QFontMetrics(QFont())
        value_width = fm.boundingRect('{}'.format(-1.0 / self._ARG_SCALE)).width()
        value_width += 10
        self._value_display.setFixedWidth(value_width)

        h = QHBoxLayout()
        h.setContentsMargins(0, 0, 0, 0)
        h.setSpacing(2)
        h.addWidget(self._down_button)
        h.addWidget(self._up_button)
        h.addWidget(self._func_selector)
        h.addWidget(self._slider)
        h.addWidget(self._value_display)
        h.addWidget(self._remove_button)
        self.setLayout(h)

    def _on_setup(self):
        self.register_action('signal_au', self._update_all)
        self.register_action(self._get_update_signal_type(), self._update_all)
        self.register_action('signal_style_changed', self._update_style)

        self._down_button.set_icon('arrow_down_small')
        self._up_button.set_icon('arrow_up_small')
        self._remove_button.set_icon('delete_small')

        style_mgr = self._ui_model.get_style_manager()
        for button in (self._down_button, self._up_button, self._remove_button):
            button.set_sizes(
                    style_mgr.get_style_param('list_button_size'),
                    style_mgr.get_style_param('list_button_padding'))

        base_wave = self._get_base_wave()

        func_names = base_wave.get_warp_func_names(self._warp_type)
        self._func_selector.set_items(name for name in func_names)

        self._update_style()
        self._update_all()

        self._down_button.clicked.connect(self._moved_down)
        self._up_button.clicked.connect(self._moved_up)
        self._func_selector.currentIndexChanged.connect(self._func_selected)
        self._slider.valueChanged.connect(self._slider_adjusted)
        self._remove_button.clicked.connect(self._removed)

    def _update_style(self):
        style_mgr = self._ui_model.get_style_manager()
        self.layout().setSpacing(style_mgr.get_scaled_size_param('small_padding'))

    def _update_all(self):
        base_wave = self._get_base_wave()

        warp_func_count = base_wave.get_warp_func_count(self._warp_type)

        if self._index >= warp_func_count:
            # We have been removed
            return

        self._down_button.setEnabled(self._index < warp_func_count - 1)

        name, arg = base_wave.get_warp_func(self._warp_type, self._index)

        old_block = self._func_selector.blockSignals(True)
        for i in range(self._func_selector.count()):
            if self._func_selector.itemText(i) == name:
                self._func_selector.setCurrentIndex(i)
                break
        self._func_selector.blockSignals(old_block)

        old_block = self._slider.blockSignals(True)
        int_val = int(round(arg * self._ARG_SCALE))
        self._slider.setValue(int_val)
        self._slider.blockSignals(old_block)

        self._value_display.setText(str(float(arg)))

    def _moved_down(self):
        base_wave = self._get_base_wave()
        base_wave.move_warp_func(self._warp_type, self._index, self._index + 1)
        self._updater.signal_update(self._get_update_signal_type())

    def _moved_up(self):
        base_wave = self._get_base_wave()
        base_wave.move_warp_func(self._warp_type, self._index, self._index - 1)
        self._updater.signal_update(self._get_update_signal_type())

    def _set_warp(self):
        base_wave = self._get_base_wave()
        name = str(self._func_selector.currentText())
        arg = self._slider.value() / float(self._ARG_SCALE)
        base_wave.set_warp_func(self._warp_type, self._index, name, arg)
        self._updater.signal_update(self._get_update_signal_type())

    def _func_selected(self, index):
        self._set_warp()

    def _slider_adjusted(self, int_val):
        self._set_warp()

    def _removed(self):
        base_wave = self._get_base_wave()
        base_wave.remove_warp_func(self._warp_type, self._index)
        self._updater.signal_update(self._get_update_signal_type())
コード例 #18
0
ファイル: waveformeditor.py プロジェクト: datamail321/kunquat
class WaveformEditor(QWidget, ProcessorUpdater):
    def __init__(self):
        super().__init__()
        self._prewarp_list = WarpList('pre', self._get_base_wave,
                                      self._get_update_signal_type)
        self._base_func_selector = KqtComboBox()
        self._postwarp_list = WarpList('post', self._get_base_wave,
                                       self._get_update_signal_type)
        self._waveform = Waveform()

        pw_layout = QVBoxLayout()
        pw_layout.setSpacing(0)
        pw_layout.addWidget(self._prewarp_list)
        pw_layout.addWidget(self._base_func_selector)
        pw_layout.addWidget(self._postwarp_list)

        ed_layout = QHBoxLayout()
        ed_layout.setSpacing(0)
        ed_layout.addLayout(pw_layout)
        ed_layout.addWidget(self._waveform)

        v = QVBoxLayout()
        v.setContentsMargins(0, 0, 0, 0)
        v.setSpacing(2)
        v.addWidget(HeaderLine('Waveshaping'))
        v.addLayout(ed_layout)
        self.setLayout(v)

    def _on_setup(self):
        self.add_to_updaters(self._prewarp_list, self._postwarp_list)
        self.register_action('signal_au', self._update_all)
        self.register_action(self._get_update_signal_type(), self._update_all)
        self.register_action('signal_style_changed', self._update_style)

        self._update_style()
        self._update_all()

        self._base_func_selector.currentIndexChanged.connect(
            self._base_func_selected)

    def _update_style(self):
        style_mgr = self._ui_model.get_style_manager()
        if not style_mgr.is_custom_style_enabled():
            self._waveform.set_config({})
            return

        def get_colour(name):
            return QColor(style_mgr.get_style_param(name))

        disabled_colour = QColor(get_colour('bg_colour'))
        disabled_colour.setAlpha(0x7f)

        config = {
            'bg_colour': get_colour('waveform_bg_colour'),
            'centre_line_colour': get_colour('waveform_centre_line_colour'),
            'waveform_colour': get_colour('waveform_zoomed_out_colour'),
            'disabled_colour': disabled_colour,
        }

        self._waveform.set_config(config)

    def _update_all(self):
        base_wave = self._get_base_wave()

        selected_base_func = base_wave.get_waveform_func()
        enable_warps = (selected_base_func != None)

        self._prewarp_list.setEnabled(enable_warps)

        old_block = self._base_func_selector.blockSignals(True)
        func_names = list(base_wave.get_waveform_func_names())
        if not selected_base_func:
            func_names.append('Custom')
        self._base_func_selector.set_items(func_names)
        self._base_func_selector.setCurrentIndex(
            self._base_func_selector.findText(selected_base_func or 'Custom'))
        self._base_func_selector.blockSignals(old_block)

        self._postwarp_list.setEnabled(enable_warps)

        self._waveform.set_waveform(base_wave.get_waveform())

    def _base_func_selected(self, index):
        base_wave = self._get_base_wave()
        func_names = base_wave.get_waveform_func_names()
        base_wave.set_waveform_func(func_names[index])
        self._updater.signal_update(self._get_update_signal_type())

    # Protected interface

    def _get_base_wave(self):
        raise NotImplementedError

    def _get_update_signal_type(self):
        raise NotImplementedError
コード例 #19
0
ファイル: waveformeditor.py プロジェクト: datamail321/kunquat
class WarpEditor(QWidget, ProcessorUpdater):

    _ARG_SCALE = 1000

    def __init__(self, warp_type, index, get_base_wave,
                 get_update_signal_type):
        super().__init__()
        self._warp_type = warp_type
        self._index = index
        self._get_base_wave = get_base_wave
        self._get_update_signal_type = get_update_signal_type

        self._down_button = SmallButton()
        self._up_button = SmallButton()
        self._func_selector = KqtComboBox()
        self._slider = QSlider(Qt.Horizontal)
        self._slider.setSizePolicy(QSizePolicy.MinimumExpanding,
                                   QSizePolicy.Preferred)
        self._value_display = QLabel()
        self._remove_button = SmallButton()

        self._slider.setRange(-self._ARG_SCALE, self._ARG_SCALE)

        self._up_button.setEnabled(self._index != 0)

        fm = QFontMetrics(QFont())
        value_width = fm.boundingRect('{}'.format(-1.0 /
                                                  self._ARG_SCALE)).width()
        value_width += 10
        self._value_display.setFixedWidth(value_width)

        h = QHBoxLayout()
        h.setContentsMargins(0, 0, 0, 0)
        h.setSpacing(2)
        h.addWidget(self._down_button)
        h.addWidget(self._up_button)
        h.addWidget(self._func_selector)
        h.addWidget(self._slider)
        h.addWidget(self._value_display)
        h.addWidget(self._remove_button)
        self.setLayout(h)

    def _on_setup(self):
        self.register_action('signal_au', self._update_all)
        self.register_action(self._get_update_signal_type(), self._update_all)

        icon_bank = self._ui_model.get_icon_bank()
        self._down_button.setIcon(
            QIcon(icon_bank.get_icon_path('arrow_down_small')))
        self._up_button.setIcon(
            QIcon(icon_bank.get_icon_path('arrow_up_small')))
        self._remove_button.setIcon(
            QIcon(icon_bank.get_icon_path('delete_small')))

        base_wave = self._get_base_wave()

        func_names = base_wave.get_warp_func_names(self._warp_type)
        self._func_selector.set_items(name for name in func_names)

        self._update_all()

        self._down_button.clicked.connect(self._moved_down)
        self._up_button.clicked.connect(self._moved_up)
        self._func_selector.currentIndexChanged.connect(self._func_selected)
        self._slider.valueChanged.connect(self._slider_adjusted)
        self._remove_button.clicked.connect(self._removed)

    def _update_all(self):
        base_wave = self._get_base_wave()

        warp_func_count = base_wave.get_warp_func_count(self._warp_type)

        if self._index >= warp_func_count:
            # We have been removed
            return

        self._down_button.setEnabled(self._index < warp_func_count - 1)

        name, arg = base_wave.get_warp_func(self._warp_type, self._index)

        old_block = self._func_selector.blockSignals(True)
        for i in range(self._func_selector.count()):
            if self._func_selector.itemText(i) == name:
                self._func_selector.setCurrentIndex(i)
                break
        self._func_selector.blockSignals(old_block)

        old_block = self._slider.blockSignals(True)
        int_val = int(round(arg * self._ARG_SCALE))
        self._slider.setValue(int_val)
        self._slider.blockSignals(old_block)

        self._value_display.setText(str(float(arg)))

    def _moved_down(self):
        base_wave = self._get_base_wave()
        base_wave.move_warp_func(self._warp_type, self._index, self._index + 1)
        self._updater.signal_update(self._get_update_signal_type())

    def _moved_up(self):
        base_wave = self._get_base_wave()
        base_wave.move_warp_func(self._warp_type, self._index, self._index - 1)
        self._updater.signal_update(self._get_update_signal_type())

    def _set_warp(self):
        base_wave = self._get_base_wave()
        name = str(self._func_selector.currentText())
        arg = self._slider.value() / float(self._ARG_SCALE)
        base_wave.set_warp_func(self._warp_type, self._index, name, arg)
        self._updater.signal_update(self._get_update_signal_type())

    def _func_selected(self, index):
        self._set_warp()

    def _slider_adjusted(self, int_val):
        self._set_warp()

    def _removed(self):
        base_wave = self._get_base_wave()
        base_wave.remove_warp_func(self._warp_type, self._index)
        self._updater.signal_update(self._get_update_signal_type())
コード例 #20
0
class SampleConfigEditor(QWidget):

    def __init__(self):
        super().__init__()
        self._au_id = None
        self._proc_id = None
        self._ui_model = None
        self._updater = None

        self._sample_size = KqtComboBox()
        self._sample_count = QSpinBox()
        self._sample_count.setRange(1, 128)
        self._range_min = SamplePitchRangeMinEditor()
        self._range_max = SamplePitchRangeMaxEditor()
        self._centre_pitch = SampleCentrePitchEditor()

        h = QHBoxLayout()
        h.setContentsMargins(0, 0, 0, 0)
        h.setSpacing(2)
        h.addWidget(QLabel('Sample size:'))
        h.addWidget(self._sample_size)
        h.addWidget(QLabel('Sample count:'))
        h.addWidget(self._sample_count)
        h.addWidget(QLabel('Pitch range:'))
        h.addWidget(self._range_min)
        h.addWidget(self._range_max)
        h.addWidget(QLabel('Centre pitch:'))
        h.addWidget(self._centre_pitch)
        self.setLayout(h)

    def set_au_id(self, au_id):
        self._au_id = au_id
        self._range_min.set_au_id(au_id)
        self._range_max.set_au_id(au_id)
        self._centre_pitch.set_au_id(au_id)

    def set_proc_id(self, proc_id):
        self._proc_id = proc_id
        self._range_min.set_proc_id(proc_id)
        self._range_max.set_proc_id(proc_id)
        self._centre_pitch.set_proc_id(proc_id)

    def set_ui_model(self, ui_model):
        self._ui_model = ui_model
        self._updater = ui_model.get_updater()
        self._updater.register_updater(self._perform_updates)
        self._range_min.set_ui_model(ui_model)
        self._range_max.set_ui_model(ui_model)
        self._centre_pitch.set_ui_model(ui_model)

        for sample_length in self._get_params().get_allowed_sample_lengths():
            self._sample_size.addItem(str(sample_length), userData=sample_length)

        QObject.connect(
                self._sample_size,
                SIGNAL('currentIndexChanged(int)'),
                self._change_sample_size)

        QObject.connect(
                self._sample_count,
                SIGNAL('valueChanged(int)'),
                self._change_sample_count)

        self._update_sample_params()

    def unregister_updaters(self):
        self._centre_pitch.unregister_updaters()
        self._range_max.unregister_updaters()
        self._range_min.unregister_updaters()
        self._updater.unregister_updater(self._perform_updates)

    def _get_update_signal_type(self):
        return 'signal_padsynth_{}'.format(self._proc_id)

    def _perform_updates(self, signals):
        update_signals = set(['signal_au', self._get_update_signal_type()])
        if not signals.isdisjoint(update_signals):
            self._update_sample_params()

    def _get_params(self):
        return utils.get_proc_params(self._ui_model, self._au_id, self._proc_id)

    def _update_sample_params(self):
        params = self._get_params()

        old_block = self._sample_size.blockSignals(True)
        new_sample_size = params.get_sample_length()
        if (self._sample_size.itemData(self._sample_size.currentIndex()) !=
                new_sample_size):
            self._sample_size.setCurrentIndex(
                    self._sample_size.findData(new_sample_size))
        self._sample_size.blockSignals(old_block)

        old_block = self._sample_count.blockSignals(True)
        new_sample_count = params.get_sample_count()
        if self._sample_count.value() != new_sample_count:
            self._sample_count.setValue(new_sample_count)
        self._sample_count.blockSignals(old_block)

    def _change_sample_size(self, index):
        sample_size = self._sample_size.itemData(index)
        self._get_params().set_sample_length(sample_size)
        self._updater.signal_update(set([self._get_update_signal_type()]))

    def _change_sample_count(self, count):
        params = self._get_params()
        params.set_sample_count(count)
        self._updater.signal_update(set([self._get_update_signal_type()]))