Skip to content

Commit

Permalink
Add initial troubleshooting docs and links
Browse files Browse the repository at this point in the history
  • Loading branch information
ideoforms committed Jul 22, 2024
1 parent 52d4932 commit e6317c0
Show file tree
Hide file tree
Showing 12 changed files with 137 additions and 6 deletions.
22 changes: 22 additions & 0 deletions docs/troubleshooting/device_not_found_exception.md
Original file line number Diff line number Diff line change
@@ -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
```
8 changes: 8 additions & 0 deletions docs/troubleshooting/index.md
Original file line number Diff line number Diff line change
@@ -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)
22 changes: 22 additions & 0 deletions docs/troubleshooting/installation.md
Original file line number Diff line number Diff line change
@@ -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.

22 changes: 22 additions & 0 deletions docs/troubleshooting/insufficient_buffer_size_exception.md
Original file line number Diff line number Diff line change
@@ -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
```
20 changes: 20 additions & 0 deletions docs/troubleshooting/node_already_playing_exception.md
Original file line number Diff line number Diff line change
@@ -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.
18 changes: 18 additions & 0 deletions docs/troubleshooting/node_not_playing_exception.md
Original file line number Diff line number Diff line change
@@ -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.
8 changes: 8 additions & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
14 changes: 12 additions & 2 deletions source/include/signalflow/core/exceptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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) {}
};
Expand All @@ -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) {}
};
Expand Down
2 changes: 1 addition & 1 deletion source/src/node/io/input/soundio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
4 changes: 2 additions & 2 deletions source/src/node/io/output/soundio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
2 changes: 1 addition & 1 deletion source/src/node/node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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/");
}

/*--------------------------------------------------------------------------------
Expand Down
1 change: 1 addition & 0 deletions source/src/python/exceptions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ void init_python_exceptions(py::module &m)
py::register_exception<signalflow::graph_not_created_exception>(m, "GraphNotCreatedException");
py::register_exception<signalflow::graph_already_created_exception>(m, "GraphAlreadyCreatedException");
py::register_exception<signalflow::invalid_channel_count_exception>(m, "InvalidChannelCountException");
py::register_exception<signalflow::insufficient_buffer_size_exception>(m, "InsufficientBufferSizeException");
py::register_exception<signalflow::patch_finished_playback_exception>(m, "PatchFinishedPlaybackException");
py::register_exception<signalflow::device_not_found_exception>(m, "DeviceNotFoundException");
py::register_exception<signalflow::audio_io_exception>(m, "AudioIOException");
Expand Down

0 comments on commit e6317c0

Please sign in to comment.