From e6317c02305a12de8ed2553a6ab8289291902be9 Mon Sep 17 00:00:00 2001 From: Daniel Jones Date: Mon, 22 Jul 2024 21:45:09 +0100 Subject: [PATCH] Add initial troubleshooting docs and links --- .../device_not_found_exception.md | 22 +++++++++++++++++++ docs/troubleshooting/index.md | 8 +++++++ docs/troubleshooting/installation.md | 22 +++++++++++++++++++ .../insufficient_buffer_size_exception.md | 22 +++++++++++++++++++ .../node_already_playing_exception.md | 20 +++++++++++++++++ .../node_not_playing_exception.md | 18 +++++++++++++++ mkdocs.yml | 8 +++++++ source/include/signalflow/core/exceptions.h | 14 ++++++++++-- source/src/node/io/input/soundio.cpp | 2 +- source/src/node/io/output/soundio.cpp | 4 ++-- source/src/node/node.cpp | 2 +- source/src/python/exceptions.cpp | 1 + 12 files changed, 137 insertions(+), 6 deletions(-) create mode 100644 docs/troubleshooting/device_not_found_exception.md create mode 100644 docs/troubleshooting/index.md create mode 100644 docs/troubleshooting/installation.md create mode 100644 docs/troubleshooting/insufficient_buffer_size_exception.md create mode 100644 docs/troubleshooting/node_already_playing_exception.md create mode 100644 docs/troubleshooting/node_not_playing_exception.md diff --git a/docs/troubleshooting/device_not_found_exception.md b/docs/troubleshooting/device_not_found_exception.md new file mode 100644 index 00000000..0408b95e --- /dev/null +++ b/docs/troubleshooting/device_not_found_exception.md @@ -0,0 +1,22 @@ +# Troubleshooting: DeviceNotFoundException + +## Example + +``` +signalflow.DeviceNotFoundException: Could not find device name: Scarlett 2i2 +``` + +## Description + +This exception occurs because the audio device specified in the configuration could not be found, or no audio devices at all could be found. + +## Solution + +Check that the device name that you have selected exists, and is connected to your computer and powered on. + + - SignalFlow selects its output device based on the device that you have selected in your `~/.signalflow/config`, in the environmental variable `SIGNALFLOW_OUTPUT_DEVICE_NAME` (or `SIGNALFLOW_INPUT_DEVICE_NAME` for input devices), or in the `config` property passed to the `AudioGraph` + - A list of all available devices can be found by running the terminal command `signalflow list-output-device-names` +``` +[audio] +output_buffer_size = 8192 +``` diff --git a/docs/troubleshooting/index.md b/docs/troubleshooting/index.md new file mode 100644 index 00000000..5391e9b3 --- /dev/null +++ b/docs/troubleshooting/index.md @@ -0,0 +1,8 @@ +# Troubleshooting + +## Exceptions + +- [InsufficientBufferSizeException](insufficient_buffer_size_exception.md) +- [DeviceNotFoundException](device_not_found_exception.md) +- [NodeNotPlayingException](node_not_playing_exception.md) +- [NodeAlreadyPlayingException](node_already_playing_exception.md) diff --git a/docs/troubleshooting/installation.md b/docs/troubleshooting/installation.md new file mode 100644 index 00000000..fb893272 --- /dev/null +++ b/docs/troubleshooting/installation.md @@ -0,0 +1,22 @@ +# Troubleshooting: Installation problems + +## General Python installation guidelines + +- You should a version of Python that is separate from the system Python, either using Homebrew or Python.org installers +- You should also ideally create a virtual environment to avoid conflicts with other local Python installs + +## On macOS + +Please follow the [installation guidelines for macOS](../installation/macos/index.md). Some general recommendations: + + - macOS 10.15 (Catalina) or above is required + - Python 3.8 or above is required + +## On Linux + +Unfortunately, Pipewire is not currently supported due to lack of support from the [libsoundio](https://github.com/andrewrk/libsoundio) subsystem that SignalFlow relies on for cross-platform audio I/O. + +## On Windows + +If `pip install signalflow` returns `ERROR: No matching distribution found for signalflow`, please note that SignalFlow for Windows currently only supports Python 3.12. + diff --git a/docs/troubleshooting/insufficient_buffer_size_exception.md b/docs/troubleshooting/insufficient_buffer_size_exception.md new file mode 100644 index 00000000..ab04438e --- /dev/null +++ b/docs/troubleshooting/insufficient_buffer_size_exception.md @@ -0,0 +1,22 @@ +# Troubleshooting: InsufficientBufferSizeException + +## Example + +``` +Exception in AudioGraph: Node audioout-soundio cannot render because output +buffer size is insufficient (8192 samples requested, buffer size = 2048). +Increase the buffer size. +``` + +## Description + +This exception occurs because the audio hardware is requesting more samples than a node has currently allocated. This allocation is controlled by SignalFlow's `output_buffer_size` config parameter. + +## Solution + +Increase the `output_buffer_size` within your [SignalFlow configuration](../graph/config.md). This can be done by adding the below to your `~/.signalflow/config` file: + +``` +[audio] +output_buffer_size = 8192 +``` diff --git a/docs/troubleshooting/node_already_playing_exception.md b/docs/troubleshooting/node_already_playing_exception.md new file mode 100644 index 00000000..ed7b9428 --- /dev/null +++ b/docs/troubleshooting/node_already_playing_exception.md @@ -0,0 +1,20 @@ +# Troubleshooting: NodeAlreadyPlayingException + +## Example + +``` +signalflow.NodeAlreadyPlayingException: Node cannot be played as it is already +playing +``` + +## Description + +This exception occurs when `play()` is called on a `Node` object that is already playing. + +## Solution + +Calling `play()` on a `Node` object simply connects the output of that node to the output endpoint of the audio graph, which means that frames will be requested from it in future audio I/O blocks. + +Calling `play()` a second time therefore has no effect, because the `Node` is already connected. + +If you want to play a particular sound twice, you should instead create two copies of the `Patch` and play them individually. \ No newline at end of file diff --git a/docs/troubleshooting/node_not_playing_exception.md b/docs/troubleshooting/node_not_playing_exception.md new file mode 100644 index 00000000..d0e78f11 --- /dev/null +++ b/docs/troubleshooting/node_not_playing_exception.md @@ -0,0 +1,18 @@ +# Troubleshooting: NodeNotPlayingException + +## Example + +``` +signalflow.NodeNotPlayingException: Node cannot be played as it is already +playing +``` + +## Description + +This exception occurs when `stop()` is called on a `Node` object that has not yet been played. + +## Solution + +Calling `stop()` on a `Node` object that is not connected to an output is invalid, and should be avoided. + +If you want to check whether a `Node` is connected before stopping it, you can check the boolean `is_playing` property. \ No newline at end of file diff --git a/mkdocs.yml b/mkdocs.yml index 3f140cdd..cef7f598 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -113,6 +113,14 @@ nav: - Accessing a buffer's contents: buffer/access.md - Operators: buffer/operators.md - Properties: buffer/properties.md + - Troubleshooting: + - Troubleshooting: troubleshooting/index.md + - Installation problems: troubleshooting/installation.md + - Exceptions: + - InsufficientBufferSizeException: troubleshooting/insufficient_buffer_size_exception.md + - DeviceNotFoundException: troubleshooting/device_not_found_exception.md + - NodeNotPlayingException: troubleshooting/node_not_playing_exception.md + - NodeAlreadyPlayingException: troubleshooting/node_already_playing_exception.md - Reference library: - "Reference library": library/index.md - "Analysis": library/analysis/index.md diff --git a/source/include/signalflow/core/exceptions.h b/source/include/signalflow/core/exceptions.h index 446f0f80..3f73cd39 100644 --- a/source/include/signalflow/core/exceptions.h +++ b/source/include/signalflow/core/exceptions.h @@ -35,6 +35,16 @@ struct invalid_channel_count_exception : public std::runtime_error : std::runtime_error(message) {} }; +struct insufficient_buffer_size_exception : public std::runtime_error +{ + using std::runtime_error::runtime_error; + + insufficient_buffer_size_exception() + : std::runtime_error("Node cannot render because output buffer size is insufficient. Increase the buffer size. More information: https://signalflow.dev/troubleshooting/insufficient_buffer_size_exception/") {} + insufficient_buffer_size_exception(const char *message) + : std::runtime_error(message) {} +}; + struct device_not_found_exception : public std::runtime_error { using std::runtime_error::runtime_error; @@ -80,7 +90,7 @@ struct node_already_playing_exception : public std::runtime_error using std::runtime_error::runtime_error; node_already_playing_exception() - : std::runtime_error("Node cannot be played as it is already playing") {} + : std::runtime_error("Node cannot be played as it is already playing. More information: https://signalflow.dev/troubleshooting/node_already_playing_exception/") {} node_already_playing_exception(const char *message) : std::runtime_error(message) {} }; @@ -90,7 +100,7 @@ struct node_not_playing_exception : public std::runtime_error using std::runtime_error::runtime_error; node_not_playing_exception() - : std::runtime_error("Node cannot be stopped as it is not playing") {} + : std::runtime_error("Node cannot be stopped as it is not playing. More information: https://signalflow.dev/troubleshooting/node_not_playing_exception/") {} node_not_playing_exception(const char *message) : std::runtime_error(message) {} }; diff --git a/source/src/node/io/input/soundio.cpp b/source/src/node/io/input/soundio.cpp index 380046ec..eb2dca1a 100644 --- a/source/src/node/io/input/soundio.cpp +++ b/source/src/node/io/input/soundio.cpp @@ -100,7 +100,7 @@ int AudioIn_SoundIO::init() int default_in_device_index = soundio_default_input_device_index(this->soundio); if (default_in_device_index < 0) - throw device_not_found_exception("No input devices found."); + throw device_not_found_exception("No input devices found. More information: https://signalflow.dev/troubleshooting/device_not_found_exception/"); this->device = soundio_get_input_device(this->soundio, default_in_device_index); if (!device) diff --git a/source/src/node/io/output/soundio.cpp b/source/src/node/io/output/soundio.cpp index 6d747d6f..2dee13f3 100644 --- a/source/src/node/io/output/soundio.cpp +++ b/source/src/node/io/output/soundio.cpp @@ -186,14 +186,14 @@ int AudioOut_SoundIO::init() int default_out_device_index = soundio_default_output_device_index(this->soundio); if (default_out_device_index < 0) - throw device_not_found_exception("No audio devices were found"); + throw device_not_found_exception("No audio devices were found. More information: https://signalflow.dev/troubleshooting/device_not_found_exception/"); if (!this->device_name.empty()) { int index = soundio_get_device_by_name(this->soundio, this->device_name.c_str()); if (index == -1) { - throw device_not_found_exception("Could not find device name: " + this->device_name); + throw device_not_found_exception("Could not find device name: " + this->device_name + ". More information: https://signalflow.dev/troubleshooting/device_not_found_exception/"); } this->device = soundio_get_output_device(this->soundio, index); } diff --git a/source/src/node/node.cpp b/source/src/node/node.cpp index d68f3e01..1ca95ecd 100644 --- a/source/src/node/node.cpp +++ b/source/src/node/node.cpp @@ -86,7 +86,7 @@ void Node::_process(Buffer &out, int num_frames) { if (&out == &this->out && num_frames > this->output_buffer_length) { - throw std::runtime_error("Node " + this->name + " cannot render because output buffer size is insufficient (" + std::to_string(num_frames) + " samples requested, buffer size = " + std::to_string(this->output_buffer_length) + "). Increase the buffer size."); + throw insufficient_buffer_size_exception("Node " + this->name + " cannot render because output buffer size is insufficient (" + std::to_string(num_frames) + " samples requested, buffer size = " + std::to_string(this->output_buffer_length) + "). Increase the buffer size. More information: https://signalflow.dev/troubleshooting/insufficient_buffer_size_exception/"); } /*-------------------------------------------------------------------------------- diff --git a/source/src/python/exceptions.cpp b/source/src/python/exceptions.cpp index 724e8704..e1d5a3a7 100644 --- a/source/src/python/exceptions.cpp +++ b/source/src/python/exceptions.cpp @@ -8,6 +8,7 @@ void init_python_exceptions(py::module &m) py::register_exception(m, "GraphNotCreatedException"); py::register_exception(m, "GraphAlreadyCreatedException"); py::register_exception(m, "InvalidChannelCountException"); + py::register_exception(m, "InsufficientBufferSizeException"); py::register_exception(m, "PatchFinishedPlaybackException"); py::register_exception(m, "DeviceNotFoundException"); py::register_exception(m, "AudioIOException");