Ejemplo n.º 1
0
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.passthru_description = node_db.NodeDescription(
            uri='test://passthru',
            type=node_db.NodeDescription.PROCESSOR,
            ports=[
                node_db.PortDescription(
                    name='in:left',
                    direction=node_db.PortDescription.INPUT,
                    types=[node_db.PortDescription.AUDIO],
                ),
                node_db.PortDescription(
                    name='in:right',
                    direction=node_db.PortDescription.INPUT,
                    types=[node_db.PortDescription.AUDIO],
                ),
                node_db.PortDescription(
                    name='out:left',
                    direction=node_db.PortDescription.OUTPUT,
                    types=[node_db.PortDescription.AUDIO],
                ),
                node_db.PortDescription(
                    name='out:right',
                    direction=node_db.PortDescription.OUTPUT,
                    types=[node_db.PortDescription.AUDIO],
                ),
            ],
            processor=node_db.ProcessorDescription(type='builtin://null', ),
        )
Ejemplo n.º 2
0
    def __init__(
            self,
            *,
            host_system: host_system_lib.HostSystem,
            description: node_db.NodeDescription,
            id: str,  # pylint: disable=redefined-builtin
            name: Optional[str] = None,
            initial_state: Optional[audioproc.PluginState] = None) -> None:
        assert isinstance(description, node_db.NodeDescription), description

        self._host_system = host_system
        self.description = node_db.NodeDescription()
        self.description.CopyFrom(description)
        self.name = name or type(self).__name__
        self.id = id
        self.initial_state = initial_state

        self.__realm = None  # type: realm_lib.PyRealm
        self.broken = False
        self.ports = []  # type: List[Port]
        self.inputs = {}  # type: Dict[str, InputPort]
        self.outputs = {}  # type: Dict[str, OutputPort]

        self.__control_values = {
        }  # type: Dict[str, control_value.PyControlValue]
        self.__port_properties = {
        }  # type: Dict[str, node_port_properties_pb2.NodePortProperties]
        self.__parameters = node_parameters_pb2.NodeParameters()

        for port_desc in self.description.ports:
            self.__add_port(self.__create_port(port_desc))
Ejemplo n.º 3
0
    def description(self) -> node_db.NodeDescription:
        node_desc = node_db.NodeDescription()
        node_desc.CopyFrom(node_description.MidiCCtoCVDescription)

        for idx in range(len(self.channels)):
            node_desc.ports.add(
                name='channel%d' % (idx + 1),
                direction=node_db.PortDescription.OUTPUT,
                types=[node_db.PortDescription.ARATE_CONTROL],
            )

        return node_desc
Ejemplo n.º 4
0
    def test_id(self):
        node_description = node_db.NodeDescription(
            uri='test://test',
            type=node_db.NodeDescription.PROCESSOR,
            ports=[],
            processor=node_db.ProcessorDescription(
                type='builtin://null',
            ),
        )

        proc1 = processor.PyProcessor('realm', 'test_node_1', self.host_system, node_description)
        proc2 = processor.PyProcessor('realm', 'test_node_2', self.host_system, node_description)

        self.assertNotEqual(proc1.id, proc2.id)
Ejemplo n.º 5
0
    async def __handle_play_file(
            self, session: Session, request: audioproc_pb2.PlayFileRequest,
            response: empty_message_pb2.EmptyMessage) -> None:
        realm = self.__engine.get_realm('root')

        node_desc = node_db.NodeDescription()
        node_desc.CopyFrom(node_db.Builtins.SoundFileDescription)
        node_desc.sound_file.sound_file_path = request.path

        node = engine.Node.create(host_system=self.__host_system,
                                  id=uuid.uuid4().hex,
                                  description=node_desc)
        realm.graph.add_node(node)
        await realm.setup_node(node)

        sink = realm.graph.find_node('sink')
        sink.inputs['in:left'].connect(node.outputs['out:left'],
                                       node_db.PortDescription.AUDIO)
        sink.inputs['in:right'].connect(node.outputs['out:right'],
                                        node_db.PortDescription.AUDIO)
        realm.update_spec()

        sound_file_complete_uri = 'http://noisicaa.odahoda.de/lv2/processor_sound_file#complete'

        complete = asyncio.Event(loop=self.event_loop)

        def handle_notification(
                notification: engine_notification_pb2.EngineNotification
        ) -> None:
            for node_message in notification.node_messages:
                if node_message.node_id == node.id:
                    msg = lv2.wrap_atom(self.__urid_mapper,
                                        node_message.atom).as_object
                    if msg.get(sound_file_complete_uri, False):
                        complete.set()

        listener = self.__engine.notifications.add(handle_notification)
        try:
            await asyncio.wait_for(complete.wait(),
                                   timeout=10.0,
                                   loop=self.event_loop)
        except asyncio.TimeoutError:
            pass
        listener.remove()

        sink.inputs['in:left'].disconnect(node.outputs['out:left'])
        sink.inputs['in:right'].disconnect(node.outputs['out:right'])
        realm.graph.remove_node(node)
        realm.update_spec()
Ejemplo n.º 6
0
    def test_event_input_port(self):
        self.node_description = node_db.NodeDescription(
            uri='test://test',
            type=node_db.NodeDescription.PROCESSOR,
            ports=[
                node_db.PortDescription(
                    name='in',
                    direction=node_db.PortDescription.INPUT,
                    types=[node_db.PortDescription.EVENTS],
                ),
                node_db.PortDescription(
                    name='out',
                    direction=node_db.PortDescription.OUTPUT,
                    types=[node_db.PortDescription.AUDIO],
                ),
            ],
            processor=node_db.ProcessorDescription(
                type='builtin://csound',
            ),
            csound=node_db.CSoundDescription(
                orchestra=textwrap.dedent("""\
                    sr=44100
                    0dbfs=1
                    ksmps=32
                    nchnls=1

                    gaOut chnexport "out", 2

                    instr 1
                      iPitch = p4
                      iVelocity = p5

                      iFreq = cpsmidinn(iPitch)
                      iVolume = -20 * log10(127^2 / iVelocity^2)

                      gaOut = db(iVolume) * linseg(0, 0.08, 1, 0.1, 0.6, 0.5, 0.0) * poscil(1.0, iFreq)
                    endin
                """),
                score='',
            ),
        )
        self.create_processor()
        self.fill_midi_buffer(
            'in',
            [(0, [0x90, 60, 100]),
             (64, [0x80, 60, 0])])

        self.process_block()
        self.assertBufferIsNotQuiet('out')
Ejemplo n.º 7
0
    def test_csound(self):
        self.node_description = node_db.NodeDescription(
            uri='test://test',
            type=node_db.NodeDescription.PROCESSOR,
            ports=[
                node_db.PortDescription(
                    name='gain',
                    direction=node_db.PortDescription.INPUT,
                    types=[node_db.PortDescription.KRATE_CONTROL],
                ),
                node_db.PortDescription(
                    name='in',
                    direction=node_db.PortDescription.INPUT,
                    types=[node_db.PortDescription.AUDIO],
                ),
                node_db.PortDescription(
                    name='out',
                    direction=node_db.PortDescription.OUTPUT,
                    types=[node_db.PortDescription.AUDIO],
                ),
            ],
            processor=node_db.ProcessorDescription(
                type='builtin://csound',
            ),
            csound=node_db.CSoundDescription(
                orchestra=textwrap.dedent("""\
                    sr=44100
                    0dbfs=1
                    ksmps=32
                    nchnls=1

                    gkGain chnexport "gain", 1
                    gaIn chnexport "in", 1
                    gaOut chnexport "out", 2

                    instr 1
                      gaOut = gkGain * gaIn
                    endin
                """),
                score='i1 0 -1',
            ),
        )
        self.create_processor()
        self.fill_buffer('in', 1.0)
        self.fill_buffer('gain', 0.5)

        self.process_block()
        self.assertBufferAllEqual('out', 0.5)
Ejemplo n.º 8
0
    def description(self) -> node_db.NodeDescription:
        desc = node_db.NodeDescription()
        desc.CopyFrom(node_description.CustomCSoundDescription)

        for port in self.ports:
            port_desc = desc.ports.add(
                name=port.name,
                display_name=port.display_name or port.name,
                types=[port.type],
                direction=port.direction,
                csound_name=port.csound_name,
            )
            if port.type in (node_db.PortDescription.KRATE_CONTROL,
                             node_db.PortDescription.ARATE_CONTROL):
                port_desc.float_value.min = 0.0
                port_desc.float_value.max = 1.0
                port_desc.float_value.default = 0.0

        return desc
Ejemplo n.º 9
0
    def scan(self) -> Iterator[node_db.NodeDescription]:
        rootdir = os.path.join(constants.DATA_DIR, 'csound')
        for dirpath, _, filenames in os.walk(rootdir):
            for filename in filenames:
                if not filename.endswith('.csnd'):
                    continue

                uri = 'builtin://csound/%s' % filename[:-5]

                path = os.path.join(dirpath, filename)
                logger.info("Loading csound node %s from %s", uri, path)

                tree = ElementTree.parse(path)
                root = tree.getroot()
                assert root.tag == 'csound'

                desc = node_db.NodeDescription()
                desc.uri = uri
                desc.supported = True
                desc.node_ui.type = 'builtin://plugin'
                desc.builtin_icon = 'node-type-builtin'
                desc.type = node_db.NodeDescription.PROCESSOR
                desc.processor.type = 'builtin://csound'

                desc.display_name = ''.join(
                    root.find('display-name').itertext())

                desc.has_ui = False

                for port_elem in root.find('ports').findall('port'):
                    port_desc = desc.ports.add()
                    port_desc.name = port_elem.get('name')

                    display_name_elem = port_elem.find('display-name')
                    if display_name_elem is not None:
                        port_desc.display_name = ''.join(
                            display_name_elem.itertext())

                    port_desc.types.append({
                        'audio':
                        node_db.PortDescription.AUDIO,
                        'kratecontrol':
                        node_db.PortDescription.KRATE_CONTROL,
                        'aratecontrol':
                        node_db.PortDescription.ARATE_CONTROL,
                        'events':
                        node_db.PortDescription.EVENTS,
                    }[port_elem.get('type')])

                    port_desc.direction = {
                        'input': node_db.PortDescription.INPUT,
                        'output': node_db.PortDescription.OUTPUT,
                    }[port_elem.get('direction')]

                    if port_desc.direction == node_db.PortDescription.OUTPUT:
                        drywet_elem = port_elem.find('drywet')
                        if drywet_elem is not None:
                            port_desc.drywet_port = drywet_elem.get('port')
                            port_desc.drywet_default = float(
                                drywet_elem.get('default'))

                        bypass_elem = port_elem.find('bypass')
                        if bypass_elem is not None:
                            port_desc.bypass_port = bypass_elem.get('port')

                    if (port_desc.direction == node_db.PortDescription.INPUT
                            and port_desc.types[0]
                            == node_db.PortDescription.EVENTS):
                        csound_elem = port_elem.find('csound')
                        if csound_elem is not None:
                            port_desc.csound_name = csound_elem.get('instr')

                    if (port_desc.direction == node_db.PortDescription.INPUT
                            and port_desc.types[0]
                            in (node_db.PortDescription.KRATE_CONTROL,
                                node_db.PortDescription.ARATE_CONTROL)):
                        float_control_elem = port_elem.find('float-control')
                        if float_control_elem is not None:
                            value_desc = port_desc.float_value
                            min_value = float_control_elem.get('min')
                            if min_value is not None:
                                value_desc.min = float(min_value)
                            max_value = float_control_elem.get('max')
                            if max_value is not None:
                                value_desc.max = float(max_value)
                            default_value = float_control_elem.get('default')
                            if default_value is not None:
                                value_desc.default = float(default_value)

                csound_desc = desc.csound

                orchestra = ''.join(root.find('orchestra').itertext())
                orchestra = orchestra.strip() + '\n'
                csound_desc.orchestra = orchestra

                score = ''.join(root.find('score').itertext())
                score = score.strip() + '\n'
                csound_desc.score = score

                yield desc
Ejemplo n.º 10
0
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# @end:license

from noisicaa import node_db

InstrumentDescription = node_db.NodeDescription(
    uri='builtin://instrument',
    display_name='Instrument',
    type=node_db.NodeDescription.PROCESSOR,
    node_ui=node_db.NodeUIDescription(type='builtin://instrument', ),
    builtin_icon='node-type-builtin',
    processor=node_db.ProcessorDescription(type='builtin://instrument', ),
    ports=[
        node_db.PortDescription(
            name='in',
            direction=node_db.PortDescription.INPUT,
            types=[node_db.PortDescription.EVENTS],
        ),
        node_db.PortDescription(
            name='out:left',
            direction=node_db.PortDescription.OUTPUT,
            types=[node_db.PortDescription.AUDIO],
        ),
        node_db.PortDescription(
            name='out:right',
            direction=node_db.PortDescription.OUTPUT,
            types=[node_db.PortDescription.AUDIO],
        ),
    ])
Ejemplo n.º 11
0
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# @end:license

from noisicaa import node_db

OscilloscopeDescription = node_db.NodeDescription(
    uri='builtin://oscilloscope',
    display_name='Oscilloscope',
    type=node_db.NodeDescription.PROCESSOR,
    node_ui=node_db.NodeUIDescription(
        type='builtin://oscilloscope',
        muteable=False,
    ),
    builtin_icon='node-type-builtin',
    processor=node_db.ProcessorDescription(type='builtin://oscilloscope', ),
    ports=[
        node_db.PortDescription(
            name='in',
            direction=node_db.PortDescription.INPUT,
            types=[
                node_db.PortDescription.ARATE_CONTROL,
                node_db.PortDescription.KRATE_CONTROL,
                node_db.PortDescription.AUDIO,
            ],
        ),
    ])
Ejemplo n.º 12
0
#
# @end:license

from noisicaa import node_db


VUMeterDescription = node_db.NodeDescription(
    uri='builtin://vumeter',
    display_name='VU Meter',
    type=node_db.NodeDescription.PROCESSOR,
    node_ui=node_db.NodeUIDescription(
        type='builtin://vumeter',
    ),
    builtin_icon='node-type-builtin',
    processor=node_db.ProcessorDescription(
        type='builtin://vumeter',
    ),
    ports=[
        node_db.PortDescription(
            name='in:left',
            direction=node_db.PortDescription.INPUT,
            types=[node_db.PortDescription.AUDIO],
        ),
        node_db.PortDescription(
            name='in:right',
            direction=node_db.PortDescription.INPUT,
            types=[node_db.PortDescription.AUDIO],
        ),
    ]
)
Ejemplo n.º 13
0
MixerDescription = node_db.NodeDescription(
    uri='builtin://mixer',
    display_name='Mixer',
    type=node_db.NodeDescription.PROCESSOR,
    node_ui=node_db.NodeUIDescription(type='builtin://mixer', ),
    builtin_icon='node-type-builtin',
    processor=node_db.ProcessorDescription(type='builtin://mixer', ),
    ports=[
        node_db.PortDescription(
            name='in:left',
            direction=node_db.PortDescription.INPUT,
            types=[node_db.PortDescription.AUDIO],
        ),
        node_db.PortDescription(
            name='in:right',
            direction=node_db.PortDescription.INPUT,
            types=[node_db.PortDescription.AUDIO],
        ),
        node_db.PortDescription(
            name='out:left',
            direction=node_db.PortDescription.OUTPUT,
            types=[node_db.PortDescription.AUDIO],
        ),
        node_db.PortDescription(
            name='out:right',
            direction=node_db.PortDescription.OUTPUT,
            types=[node_db.PortDescription.AUDIO],
        ),
        node_db.PortDescription(
            name='gain',
            direction=node_db.PortDescription.INPUT,
            types=[node_db.PortDescription.KRATE_CONTROL],
            float_value=node_db.FloatValueDescription(default=0.0,
                                                      min=-50.0,
                                                      max=20.0),
        ),
        node_db.PortDescription(
            name='pan',
            direction=node_db.PortDescription.INPUT,
            types=[node_db.PortDescription.KRATE_CONTROL],
            float_value=node_db.FloatValueDescription(default=0.0,
                                                      min=-1.0,
                                                      max=1.0),
        ),
        node_db.PortDescription(
            name='lp_cutoff',
            direction=node_db.PortDescription.INPUT,
            types=[node_db.PortDescription.KRATE_CONTROL],
            float_value=node_db.FloatValueDescription(default=20000.0,
                                                      min=1.0,
                                                      max=20000.0),
        ),
        node_db.PortDescription(
            name='hp_cutoff',
            direction=node_db.PortDescription.INPUT,
            types=[node_db.PortDescription.KRATE_CONTROL],
            float_value=node_db.FloatValueDescription(default=1.0,
                                                      min=1.0,
                                                      max=20000.0),
        ),
    ])
Ejemplo n.º 14
0
    def scan(self) -> Iterator[node_db.NodeDescription]:
        # TODO: support configurable searchpaths
        rootdirs = os.environ.get('LADSPA_PATH', '/usr/lib/ladspa')
        for rootdir in rootdirs.split(':'):
            for dirpath, _, filenames in os.walk(rootdir):
                for filename in filenames:
                    if not filename.endswith('.so'):
                        continue

                    path = os.path.join(dirpath, filename)
                    logger.info("Loading LADSPA plugins from %s", path)

                    try:
                        lib = ladspa.Library(path)
                    except ladspa.Error as exc:
                        logger.warning("Failed to load LADSPA library %s: %s",
                                       path, exc)
                        continue

                    for descriptor in lib.descriptors:  # pylint: disable=not-an-iterable
                        uri = 'ladspa://%s/%s' % (filename, descriptor.label)
                        logger.info("Adding LADSPA plugin %s", uri)

                        desc = node_db.NodeDescription()
                        desc.uri = uri
                        desc.supported = True
                        desc.display_name = descriptor.name
                        desc.type = node_db.NodeDescription.PLUGIN
                        desc.node_ui.type = 'builtin://plugin'
                        desc.builtin_icon = 'node-type-ladspa'
                        desc.processor.type = 'builtin://plugin'
                        desc.plugin.type = node_db.PluginDescription.LADSPA
                        desc.has_ui = False

                        ladspa_desc = desc.ladspa
                        ladspa_desc.library_path = path
                        ladspa_desc.label = descriptor.label

                        for port in descriptor.ports:
                            port_desc = desc.ports.add()
                            port_desc.name = port.name

                            if port.direction == ladspa.PortDirection.Input:
                                port_desc.direction = node_db.PortDescription.INPUT
                            elif port.direction == ladspa.PortDirection.Output:
                                port_desc.direction = node_db.PortDescription.OUTPUT
                            else:
                                raise ValueError(port)

                            if port.type == ladspa.PortType.Control:
                                port_desc.types.append(
                                    node_db.PortDescription.KRATE_CONTROL)
                            elif port.type == ladspa.PortType.Audio:
                                port_desc.types.append(
                                    node_db.PortDescription.AUDIO)
                            else:
                                raise ValueError(port)

                            if (port.type == ladspa.PortType.Control
                                    and port.direction
                                    == ladspa.PortDirection.Input):
                                lower_bound = port.lower_bound(44100)
                                upper_bound = port.upper_bound(44100)
                                default = port.default(44100)

                                value_desc = port_desc.float_value
                                # Using a fixed sample rate is pretty ugly...
                                if lower_bound is not None:
                                    value_desc.min = lower_bound
                                if upper_bound is not None:
                                    value_desc.max = upper_bound
                                if default is not None:
                                    value_desc.default = default

                        yield desc
Ejemplo n.º 15
0
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# @end:license

from noisicaa import node_db

MidiCCtoCVDescription = node_db.NodeDescription(
    uri='builtin://midi-cc-to-cv',
    display_name='MIDI CC to Control Value',
    type=node_db.NodeDescription.PROCESSOR,
    node_ui=node_db.NodeUIDescription(type='builtin://midi-cc-to-cv', ),
    builtin_icon='node-type-builtin',
    processor=node_db.ProcessorDescription(type='builtin://midi-cc-to-cv', ),
    ports=[
        node_db.PortDescription(
            name='in',
            direction=node_db.PortDescription.INPUT,
            types=[node_db.PortDescription.EVENTS],
        ),
    ])
Ejemplo n.º 16
0
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# @end:license

from noisicaa import node_db

BeatTrackDescription = node_db.NodeDescription(
    uri='builtin://beat-track',
    display_name='Beat Track',
    type=node_db.NodeDescription.PROCESSOR,
    node_ui=node_db.NodeUIDescription(type='builtin://beat-track', ),
    builtin_icon='track-type-beat',
    processor=node_db.ProcessorDescription(type='builtin://pianoroll', ),
    ports=[
        node_db.PortDescription(
            name='out',
            direction=node_db.PortDescription.OUTPUT,
            types=[node_db.PortDescription.EVENTS],
        ),
    ])
Ejemplo n.º 17
0
 def description(self) -> node_db.NodeDescription:
     node_desc = node_db.NodeDescription()
     node_desc.CopyFrom(node_description.MidiMonitorDescription)
     return node_desc
Ejemplo n.º 18
0
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# @end:license

from noisicaa import node_db

CVMapperDescription = node_db.NodeDescription(
    uri='builtin://cv-mapper',
    display_name='Control Value Mapper (a-rate)',
    type=node_db.NodeDescription.PROCESSOR,
    node_ui=node_db.NodeUIDescription(type='builtin://cv-mapper', ),
    builtin_icon='node-type-builtin',
    processor=node_db.ProcessorDescription(type='builtin://cv-mapper', ),
    ports=[
        node_db.PortDescription(
            name='in',
            direction=node_db.PortDescription.INPUT,
            types=[node_db.PortDescription.ARATE_CONTROL],
        ),
        node_db.PortDescription(
            name='out',
            direction=node_db.PortDescription.OUTPUT,
            types=[node_db.PortDescription.ARATE_CONTROL],
        ),
    ])
Ejemplo n.º 19
0
# @begin:license
#
# Copyright (c) 2015-2019, Benjamin Niemann <*****@*****.**>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# @end:license

from noisicaa import node_db

CustomCSoundDescription = node_db.NodeDescription(
    uri='builtin://custom-csound',
    display_name='Custom CSound',
    type=node_db.NodeDescription.PROCESSOR,
    processor=node_db.ProcessorDescription(type='builtin://custom-csound', ),
    node_ui=node_db.NodeUIDescription(type='builtin://custom-csound', ),
    builtin_icon='node-type-builtin',
)
Ejemplo n.º 20
0
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# @end:license

from noisicaa import node_db

SampleTrackDescription = node_db.NodeDescription(
    uri='builtin://sample-track',
    display_name='Sample Track',
    type=node_db.NodeDescription.PROCESSOR,
    node_ui=node_db.NodeUIDescription(type='builtin://sample-track', ),
    processor=node_db.ProcessorDescription(type='builtin://sample-script', ),
    builtin_icon='track-type-sample',
    ports=[
        node_db.PortDescription(
            name='out:left',
            direction=node_db.PortDescription.OUTPUT,
            types=[node_db.PortDescription.AUDIO],
        ),
        node_db.PortDescription(
            name='out:right',
            direction=node_db.PortDescription.OUTPUT,
            types=[node_db.PortDescription.AUDIO],
        ),
    ])
Ejemplo n.º 21
0
 def description(self) -> node_db.NodeDescription:
     node_desc = node_db.NodeDescription()
     node_desc.CopyFrom(node_description.MetronomeDescription)
     return node_desc
Ejemplo n.º 22
0
#
# @end:license

from noisicaa import node_db


MidiLooperDescription = node_db.NodeDescription(
    uri='builtin://midi-looper',
    display_name='MIDI Looper',
    type=node_db.NodeDescription.PROCESSOR,
    node_ui=node_db.NodeUIDescription(
        type='builtin://midi-looper',
    ),
    builtin_icon='node-type-builtin',
    processor=node_db.ProcessorDescription(
        type='builtin://midi-looper',
    ),
    ports=[
        node_db.PortDescription(
            name='in',
            direction=node_db.PortDescription.INPUT,
            types=[node_db.PortDescription.EVENTS],
        ),
        node_db.PortDescription(
            name='out',
            direction=node_db.PortDescription.OUTPUT,
            types=[node_db.PortDescription.EVENTS],
        ),
    ]
)
Ejemplo n.º 23
0
 def description(self) -> node_db.NodeDescription:
     node_desc = node_db.NodeDescription()
     node_desc.CopyFrom(node_description.CVMapperDescription)
     return node_desc
Ejemplo n.º 24
0
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# @end:license

from noisicaa import node_db

StepSequencerDescription = node_db.NodeDescription(
    uri='builtin://step-sequencer',
    display_name='Step Sequencer',
    type=node_db.NodeDescription.PROCESSOR,
    node_ui=node_db.NodeUIDescription(type='builtin://step-sequencer', ),
    builtin_icon='node-type-builtin',
    processor=node_db.ProcessorDescription(type='builtin://step-sequencer', ),
    ports=[
        node_db.PortDescription(
            name='tempo',
            direction=node_db.PortDescription.INPUT,
            types=[node_db.PortDescription.ARATE_CONTROL],
            float_value=node_db.FloatValueDescription(
                min=0.01,
                max=100.0,
                default=8,
                scale=node_db.FloatValueDescription.LOG),
        ),
    ])
Ejemplo n.º 25
0
 def description(self) -> node_db.NodeDescription:
     node_desc = node_db.NodeDescription()
     node_desc.CopyFrom(node_description.OscilloscopeDescription)
     return node_desc
Ejemplo n.º 26
0
    async def test_processor(self):
        self.host_system.set_block_size(256)
        async with self.create_realm() as realm:
            node_description = node_db.NodeDescription(
                uri='test://test',
                type=node_db.NodeDescription.PROCESSOR,
                processor=node_db.ProcessorDescription(
                    type='builtin://null', ),
                ports=[
                    node_db.PortDescription(
                        name='gain',
                        direction=node_db.PortDescription.INPUT,
                        types=[node_db.PortDescription.KRATE_CONTROL],
                    ),
                    node_db.PortDescription(
                        name='in',
                        direction=node_db.PortDescription.INPUT,
                        types=[node_db.PortDescription.AUDIO],
                    ),
                    node_db.PortDescription(
                        name='out',
                        direction=node_db.PortDescription.OUTPUT,
                        types=[node_db.PortDescription.AUDIO],
                    ),
                ])

            processor = PyProcessor(realm.name, 'amp', self.host_system,
                                    node_description)
            processor.setup()
            realm.add_active_processor(processor)

            spec = PySpec()
            spec.append_buffer(
                'sink:in:left',
                buffers.PyFloatAudioBlockBuffer(node_db.PortDescription.AUDIO))
            spec.append_buffer(
                'sink:in:right',
                buffers.PyFloatAudioBlockBuffer(node_db.PortDescription.AUDIO))
            spec.append_buffer('gain', buffers.PyFloatControlValueBuffer())
            spec.append_buffer(
                'in',
                buffers.PyFloatAudioBlockBuffer(node_db.PortDescription.AUDIO))
            spec.append_buffer(
                'out',
                buffers.PyFloatAudioBlockBuffer(node_db.PortDescription.AUDIO))
            spec.append_processor(processor)
            spec.append_opcode('CONNECT_PORT', processor, 0, 'gain')
            spec.append_opcode('CONNECT_PORT', processor, 1, 'in')
            spec.append_opcode('CONNECT_PORT', processor, 2, 'out')
            spec.append_opcode('CALL', processor)
            realm.set_spec(spec)

            # Initializes the program with the new spec (required for Realm::get_buffer() to work).
            program = realm.get_active_program()

            buf_gain = realm.get_buffer('gain',
                                        buffers.PyFloatControlValueBuffer())
            buf_gain[0] = 0.5

            buf_in = realm.get_buffer(
                'in',
                buffers.PyFloatAudioBlockBuffer(node_db.PortDescription.AUDIO))
            buf_in[0] = 1.0
            buf_in[1] = 2.0
            buf_in[2] = 3.0
            buf_in[3] = 4.0

            realm.process_block(program)
Ejemplo n.º 27
0
 def get_node_description(self, uri: str) -> node_db.NodeDescription:
     desc = node_db.NodeDescription()
     desc.CopyFrom(self.__nodes[uri])
     return desc
Ejemplo n.º 28
0
    def scan(self) -> Iterator[node_db.NodeDescription]:
        world = lilv.World()
        ns = world.ns
        world.load_all()

        plugins = world.get_all_plugins()

        for plugin in plugins:
            logger.info("Adding LV2 plugin %s", plugin.get_uri())

            desc = node_db.NodeDescription()
            desc.uri = str(plugin.get_uri())
            desc.supported = True
            desc.type = node_db.NodeDescription.PLUGIN
            desc.node_ui.type = 'builtin://plugin'
            desc.builtin_icon = 'node-type-lv2'
            desc.processor.type = 'builtin://plugin'
            desc.plugin.type = node_db.PluginDescription.LV2
            desc.display_name = str(plugin.get_name())

            lv2_desc = desc.lv2
            lv2_desc.uri = str(plugin.get_uri())

            for uri in plugin.required_features:
                feature_desc = lv2_desc.features.add()
                feature_desc.required = True
                feature_desc.uri = uri
                if not lv2.supports_plugin_feature(uri):
                    desc.supported = False
                    desc.not_supported_reasons.unsupported_lv2_feature.append(uri)

            for feature_uri in plugin.optional_features:
                feature_desc = lv2_desc.features.add()
                feature_desc.required = False
                feature_desc.uri = feature_uri

            for ui in plugin.get_uis():
                ui_desc = lv2_desc.uis.add()
                ui_desc.supported = True
                ui_desc.uri = ui.uri

                for cl in ui.get_classes():
                    if str(cl) in supported_uis:
                        ui_desc.type_uri = str(cl)

                if not ui_desc.type_uri:
                    ui_desc.supported = False
                    for cl in ui.get_classes():
                        ui_desc.not_supported_reasons.unsupported_lv2_ui_type.append(str(cl))

                for uri in ui.required_features:
                    feature_desc = ui_desc.features.add()
                    feature_desc.required = True
                    feature_desc.uri = uri
                    if not lv2.supports_ui_feature(uri):
                        ui_desc.supported = False
                        ui_desc.not_supported_reasons.unsupported_lv2_feature.append(uri)

                for feature_uri in ui.optional_features:
                    feature_desc = ui_desc.features.add()
                    feature_desc.required = False
                    feature_desc.uri = feature_uri

                if ui_desc.supported:
                    ui_desc.bundle_path = ui.bundle_path
                    ui_desc.binary_path = ui.binary_path
                    if not lv2_desc.ui_uri:
                        lv2_desc.ui_uri = ui.uri

            desc.has_ui = bool(lv2_desc.ui_uri)

            for port in (plugin.get_port_by_index(i) for i in range(plugin.get_num_ports())):
                port_desc = desc.ports.add()
                port_desc.name = str(port.get_symbol())
                port_desc.display_name = str(port.get_name())

                if port.is_a(ns.lv2.InputPort):
                    port_desc.direction = node_db.PortDescription.INPUT
                elif port.is_a(ns.lv2.OutputPort):
                    port_desc.direction = node_db.PortDescription.OUTPUT
                else:
                    raise ValueError(port)

                if port.is_a(ns.lv2.ControlPort):
                    port_desc.types.append(node_db.PortDescription.KRATE_CONTROL)
                elif port.is_a(ns.lv2.AudioPort):
                    port_desc.types.append(node_db.PortDescription.AUDIO)
                elif port.is_a(ns.atom.AtomPort):
                    port_desc.types.append(node_db.PortDescription.EVENTS)
                else:
                    port_desc.types.append(node_db.PortDescription.UNSUPPORTED)

                if port.is_a(ns.lv2.ControlPort):
                #     # if port.has_property(ns.lv2.integer):
                #     #     # TODO: this should be IntParameter
                #     #     parameter_cls = node_db.FloatParameterDescription
                #     # else:
                #     #     parameter_cls = node_db.FloatParameterDescription

                    value_desc = port_desc.float_value
                    default, range_min, range_max = port.get_range()
                    if default is not None:
                        if default.is_int():
                            value_desc.default = int(default)
                        else:
                            value_desc.default = float(default)
                    if range_min is not None:
                        if range_min.is_int():
                            value_desc.min = int(range_min)
                        else:
                            value_desc.min = float(range_min)
                    if range_max is not None:
                        if range_max.is_int():
                            value_desc.max = int(range_max)
                        else:
                            value_desc.max = float(range_max)

            if not desc.supported:
                # TODO: also add unsupported plugins to DB.
                logger.warning(
                    "Not adding LV2 plugin %s:\n%s",
                    plugin.get_uri(),
                    desc.not_supported_reasons)
                continue

            yield desc
Ejemplo n.º 29
0
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# @end:license

from noisicaa import node_db


ControlTrackDescription = node_db.NodeDescription(
    uri='builtin://control-track',
    display_name='Control Track',
    type=node_db.NodeDescription.PROCESSOR,
    node_ui=node_db.NodeUIDescription(
        type='builtin://control-track',
    ),
    builtin_icon='track-type-control',
    processor=node_db.ProcessorDescription(
        type='builtin://cv-generator',
    ),
    ports=[
        node_db.PortDescription(
            name='out',
            direction=node_db.PortDescription.OUTPUT,
            types=[node_db.PortDescription.ARATE_CONTROL],
        ),
    ]
)