Commit Graph

12 Commits (c3e5c3a88dcf7cfac5f13cd67601be0b8c2fe3a5)

Author SHA1 Message Date
Ben Niemann c3e5c3a88d Allow nodes to have dynamic list of ports.
- Currently only used for CustomCSound nodes.
- Bring back node parameters
- Add a ObjectListEditor widget.
2019-04-06 15:58:26 +02:00
Ben Niemann f4ce7f53d2 Rewrite MIDI input.
- A new "MIDI source" node, which can feed MIDI events from any ALSA device into the graph.
- All done rt safe in C++. The older Python implementation in noisicaa.devices has been removed.
- Still quite hacky:
  - It's built into the portaudio backend. There should probably be a separate "ALSA sequencer"
    backend for this, with the option to have an alternative "Jack MIDI" backend. But for that I
    have to figure out how to have separate backends for audio and MIDI and how that interacts
    for all possible combinations.
  - It just blindly connects to all readable MIDI ports, collecting all events. Filtering out
    the events for a specific port (e.g. a MIDI keyboard) happens in the "MIDI source" node.
    The engine should track, which ports are being used and only connect to those.

Squashed commit of the following:

commit c811be510347d1fd23abea081ba0a4d93e8cb6bf
Author: Ben Niemann <>
Date:   Mon Jan 14 03:36:18 2019 +0100

    Move ALSADeviceManager to a separate file.

commit 6e5d9a2c691fdf639f0173b9dd2ebfde7f58f4f4
Author: Ben Niemann <>
Date:   Mon Jan 14 03:25:29 2019 +0100

    Fix/improve tests.

commit 94b4fa253f8a4f8a84d13dd718dbaeac99fee5fe
Author: Ben Niemann <>
Date:   Sun Jan 13 13:57:07 2019 +0100

    Reanimate playback from the instrument library.

commit 17a288980fc361f190876763dbe4a6a6bbd0c2b3
Author: Ben Niemann <>
Date:   Sun Jan 13 12:57:54 2019 +0100

    Remove the now obsolete noisicaa.devices package.

commit aa2f9bbc1ae61295157f66948b276861dee00379
Author: Ben Niemann <>
Date:   Sun Jan 13 12:45:50 2019 +0100

    Strip the PianoWidget down to just the keys.

commit 1c87b29f7abb51defa28b33f902f8de85ae7eb55
Author: Ben Niemann <>
Date:   Sun Jan 13 12:24:57 2019 +0100

    Add piano to MIDI source node.

    - Make BasePipelineGraphNode.pipeline_node_id globally available.
    - Allow sending processor messages from the UI.
    - Pass the MIDI events to the rt thread via a FIFO queue.

commit f19114e966ab2d9261fd3a86b93d2ca88e9f3fba
Author: Ben Niemann <>
Date:   Sun Jan 13 11:29:43 2019 +0100

    Remove the System Out node again.

    And the related Backend::input().
    Not needed after all.

commit a839f259e3b8e338072be9c8b9fa58d8dc0d36a4
Author: Ben Niemann <>
Date:   Sun Jan 13 10:03:33 2019 +0100

    Wire up MIDI source to events from the backend.

    - Make the event buffer accessible via the block context.
    - Backend creates sequence of (uri, midi) tuples.
    - ProcessorMidiSource filters that list and emit list of midi events.

commit 347dc0168b00315eed233fdec40c8a9d6b5ffe41
Author: Ben Niemann <>
Date:   Sun Jan 13 09:21:36 2019 +0100

    Make the main ALSA sequences listen to all output ports again.

    Now also tracking new ports as they appear.

commit 86b6b7a59974c18c6078761fe1010456e5f26e43
Author: Ben Niemann <>
Date:   Sun Jan 13 09:20:52 2019 +0100

    Bug fix.

commit 776dbd4a946ecfa8e178cd7e3e108a4c3519f3cb
Author: Ben Niemann <>
Date:   Sun Jan 13 08:43:47 2019 +0100

    Editor tracks devices in a QAbstractItemModel.

    And MIDI Source node uses that for the port selector combobox.

commit a9c578e377948d187a0ee8ede90c29cc32b337a1
Author: Ben Niemann <>
Date:   Sun Jan 13 08:42:30 2019 +0100

    Also handle port changes somewhat gracefully.

commit f4cd8c7535b36e7c6b9323ff2861d72e376bac08
Author: Ben Niemann <>
Date:   Sun Jan 13 05:34:01 2019 +0100

    Also handle CC events.

commit 1329e51ff9747764a2bb5c6578f3490047cee135
Author: Ben Niemann <>
Date:   Sun Jan 13 04:30:45 2019 +0100

    Device manager that tracks ALSA sequencer clients.

    - Allow backends to post engine notifications.
    - PortAudioBackend runs a separate (non-rt) thread, with a sequencer client just for listening for
      client notifications.
    - Create a DeviceDescription proto for ALSA sequencer clients and post them as engine notifications.

commit 10c5b827de47479e6a8046c44cd32494693c762b
Author: Ben Niemann <>
Date:   Sun Jan 13 01:34:47 2019 +0100

    A MIDI source node, which doesn't really do anything yet.

commit e09a5c70e3b950f3c6e30b81c2e8b67d65a947b3
Author: Ben Niemann <>
Date:   Sat Jan 12 11:51:36 2019 +0100

    Use C string for Spec::get_buffer_idx() to avoid malloc in the audio thread.

commit 24cfffdf60a4ad888e65fe839165666ebef0f9f0
Author: Ben Niemann <>
Date:   Sat Jan 12 08:13:26 2019 +0100

    Add a "System In" node to the graph and wire it up to the MIDI events from the backend.

    Also rename "Audio Out" to "System Out", because that makes more sense, now that there is more than
    audio being passed around.

commit 77be27b0e487b0830d913bdcc54cf56ea35114cf
Author: Ben Niemann <>
Date:   Sat Jan 12 08:10:55 2019 +0100

    Add Backend::input() method to read incoming MIDI events.

    Also switch to an enum for the channel arg.

commit 5c4acefc476ace640d8a0ac40d6816ca48399207
Author: Ben Niemann <>
Date:   Sat Jan 12 08:08:20 2019 +0100

    PortAudioBackend also reads MIDI events into a buffer.

    Very prototypish implementation. It just scans for all available devices and connects to their
    outputs. Still need to think about how to deal with different devices.
2019-01-14 04:02:26 +01:00
Ben Niemann 9fd2fdeb7b Update licenses to 2019. 2019-01-12 01:20:46 +01:00
Ben Niemann 21ec283822 Reorganize code to make creating new node types easier.
Adding new node types required adding bits and pieces in many places, which was tedious and failure
Now it's just cloning the directory of one of the existing nodes and adding a few lines to
'registries' (all in one directory).

- Reanimate custom csound node.
- All nodes can be muted.
2019-01-08 10:11:57 +01:00
Ben Niemann aa380e9c07 Custom UI for mixer nodes and an Instrument node to bring back sample playback.
And various internal changes and cleanups to support this.
2019-01-04 01:31:33 +01:00
Ben Niemann 45f67ea7f6 Make the audio thread (mostly) realtime safe.
- Purge all remaining Python from the critical path.
- Add a "realtime checker", and use it to remove most uses of malloc in the audio thread.
- Make logging from the audio thread realtime safe.
- Add a tool to profile the audio thread.
- Set realtime priority on the audio thread.
2018-12-27 00:34:14 +01:00
Ben Niemann bc8cc6bf71 Upgrade mypy to V0.650
- fix a number of newly reported issues with PyQt5 stubs.
- add empty stub files for all 3rdparty libs without stubs.
- remove local copy of protobuf stubs, the version from the official typeshed is now good enough.
2018-12-21 23:46:36 +01:00
Ben Niemann 29e0b30523 Make noisicaa.audioproc.engine mypy clean.
Mostly by adding stubs for various cython modules.
2018-04-09 06:50:07 +02:00
Ben Niemann b29d0c6fc7 Persist plugin state.
- Now the state of the Helm synth is properly saved, although there is still odd behavior when using
  Helm's preset browser - which I blame Helm for.
- Control value changes are routed through the project process, so the model can be updated.
- Implement the LV2 state feature.
- Also add the concept of generation numbers to control value changes, so delayed updates don't
  cause weird issues with the UI.

Squashed commit of the following:

commit b87929098aeafa3375e209d5eb3362caeccbd6cd
Author: Ben Niemann <>
Date:   Tue Apr 3 02:45:44 2018 +0200

    Change to plugin_state in model are propagated to the plugin host.

commit ae197b6a81a3a0a645cf8440a63b7aee53fab477
Author: Ben Niemann <>
Date:   Tue Apr 3 01:37:46 2018 +0200

    Immediately unload plugin UI when hiding it.

    Currently crashes when closing the app while still waiting for the unload.

commit 12454b02ca8d388537389e9d031295d1f24a7e03
Author: Ben Niemann <>
Date:   Tue Apr 3 01:37:25 2018 +0200

    Larger log files to make debugging easier.

commit 6ccae1f7c89cdd5ef0f699e676af8ea988f03351
Author: Ben Niemann <>
Date:   Mon Apr 2 20:30:59 2018 +0200

    Set the initial plugin state from the state stored in the model.

    - Add PluginHost::set_state() methods and LV2 implementation.
    - Also make PluginHost::get_state() non-abstract.

    Somethings still missing, state isn't the same after reopening a project.

commit 25710a77549501bd80164105b50ab575f5f88c09
Author: Ben Niemann <>
Date:   Mon Apr 2 02:14:24 2018 +0200

    Persist the plugin state in the model.

    - Regularly poll the plugin for its state.
    - If changed, post it back to project process.
    - The callback address to the project process is now set when creating the realm, and the stub
      is created by the PluginHost instance.
    - PluginHostLV2::get_state() does not create an empty lv2 message, if no properties are set.

commit 2fd537a73d77b30fa0b49193522b68ad928616a9
Author: Ben Niemann <>
Date:   Mon Apr 2 02:11:48 2018 +0200

    Move PluginState message to noisicaa.audioproc.public.

commit 252946a849806745a7ae1d529dedf47406b98c6a
Author: Ben Niemann <>
Date:   Sun Apr 1 19:22:02 2018 +0200

    Add API to dump LV2 plugin state into a proto message.

commit 6e0546cd47ce66e8481db2331496d7ba819c48b3
Author: Ben Niemann <>
Date:   Sun Apr 1 19:18:11 2018 +0200

    Two test modules were missing from CMakeLists.txt.

commit fcb94a0f25322b7d60c124bc2af0344a4560e58a
Author: Ben Niemann <>
Date:   Sun Apr 1 16:05:07 2018 +0200

    Control values are tracked as a (value, generation) pair.

    Implements a basic logical clock, so the UI can ignore delayed state updates.

    Also rename the BufferType classes for consistency.

commit 574078a6cd228a0af72d8c06d026ccac822cdcf2
Author: Ben Niemann <>
Date:   Sat Mar 31 13:32:30 2018 +0200

    Post control value changes to the UI.

    Move the control port monitoring to PluginHostLV2, because it's only used by LV2 for now, and
    further improvements will be very LV2 specific.

commit 45b0ca8bf2769b6218ccc1b74aa91015a3c2af91
Author: Ben Niemann <>
Date:   Fri Mar 30 17:52:40 2018 +0200

    PluginHost exposed control value changes via a slot.

    The slot is called in a non-rt context.

commit 31540a7ae5ff1e0f618faf4742628f41acee01ee
Author: Ben Niemann <>
Date:   Fri Mar 30 16:50:01 2018 +0200

    ProjectProcess handles CONTROL_VALUE_CHANGE.

    Constructs and dispatches a SetPipelineGraphControlValue command, which automatically updates the
    audioproc and UI processes with the change.

commit 62b3f9d5ea3a3302f7bf5906c164cf7cbd2ec294
Author: Ben Niemann <>
Date:   Fri Mar 30 16:18:50 2018 +0200

    Some more fixes, because PluginHostProcess doesn't take the audioproc server address anymore.

commit 1a4a687a5eb4a1a8188c0fb18a7f85223f841910
Author: Ben Niemann <>
Date:   Fri Mar 30 15:56:46 2018 +0200

    PluginHostProcess expects a callback address for each UI.

    And uses that to post control value changes.
    Doesn't need the audioproc server address anymore.

commit ed1108e9ea97924204bf88a2d0bbf2594e221dae
Author: Ben Niemann <>
Date:   Fri Mar 30 15:54:52 2018 +0200

    Allow lines with type annotation to exceed max length limit.

commit 07dd43e24f5368a2f1db2feb8a11ba35398b0fa9
Author: Ben Niemann <>
Date:   Thu Mar 29 17:31:01 2018 +0200

    Remove obsolete class.
2018-04-09 04:11:37 +02:00
Ben Niemann f1b2f9031a Implement LV2 instance-access feature for UIs.
- Move noisicaa.lv2.ui_host to noisicaa.audioproc.engine.plugin_ui_host_lv2.
- test-ui-gtk2 test plugin requires instance-access.
- Now Helm UI works!
2018-03-25 16:07:45 +02:00
Ben Niemann 3f38baf788 Convert noisicaa.audioproc.engine.backend_test to pure python. 2018-03-24 09:22:52 +01:00
Ben Niemann 45be492aed Massive refactoring of the audio layer.
- Run all audio in a single process.
  - Instead of a main audio process connected to the backend and one process per opened project.
  - Audio engine is composed of a tree of 'realms', with the top-level realm hooked up to the
    backend, and each project creates a sub-realm.
- Run plugins in a separate process, isolated from the main audio engine.
  - Turns out I really want to support the LV2 instance access feature, so UIs need to run in the
    same process as the plugin itself.
  - So plugins need to be isolated from each other, so they can use different UI toolkits without
    linker symbol clashes. I.e. they can't all run in the main audio process.
- Separate audio processing from the project process.
  - Instead of generating MIDI events from the project and route them to the audio pipeline, have
    processors in the pipeline, which capture the full state of the project and emit events during
    playback. Changes to the project update those processors to keep them in sync.
- Use protocol buffers for a lot of internal messages in non-realtime contexts.
- Very basic support for LV2 plugin UIs.
  - Trying to get that working triggered all those changes above...
- And many, many more changes...
2018-03-21 08:01:20 +01:00