Skip to content

Conversation

richinsley
Copy link

This adds an abstract audio device class with a sub-class that creates an audio device using the sounddevice package.

ShadertoyChannelMusic is implemented to pull the audio data from it's given audio device and generates the waveform and fft data.

infer_subclass detects ctype of 'mic' and creates the ShadertoyChannelMusic instance.

An example (shadertoy/examples/shadertoy_mic_input.py) was added that demonstrates how to select and add the audio device to the ShaderToy instance.

@Vipitis
Copy link
Collaborator

Vipitis commented Apr 28, 2025

Hey,

Awesome stuff! Thanks for the contribution.
I am at a conference this week - so will try to have a closer look in the next few days.

Comment on lines +9 to +10
parser.add_argument('--from_id', type=str, default="llSGDh",
help='Shadertoy ID (default: llSGDh) https://www.shadertoy.com/view/llSGDh by iq CC-BY-NC-SA-3.0')
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

having the code directly makes the example available offline for for those without an API key set.

Comment on lines +11 to +14
parser.add_argument('--list-audio-devices', action='store_true',
help='List all available audio input devices and exit')
parser.add_argument('--device-index', type=int, default=None,
help='Audio device index to use (default: system default)')
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the example shouldn't really need interactivity for testing. This cl arg makes sense for cli.py

Comment on lines +21 to +24
if args.list_audio_devices:
print("Available audio input devices:")
print(sd.query_devices())
sys.exit(0)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it should be fine to just print all for the example. Although on my system there were 51 devices - so maybe just print those that work as microphones

return np.zeros(num_samples, dtype=np.float32)

class NoiseAudioDevice(AudioDevice):
"""An AudioDevice that always returns silence."""
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"""An AudioDevice that always returns silence."""
"""An AudioDevice that always returns white noise."""

sample_rate: int = 44100,
buffer_duration_seconds: float = 5.0,
chunk_size: int = 1024,
device_index: int | None = None,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

technically we still support 3.9 which doesn't allow this syntax

@Vipitis
Copy link
Collaborator

Vipitis commented May 7, 2025

Finally had a look at first half of this and tried it out too.

Will have to take a closer look at the update logic after this is rebased with the multipass changes especially around updating. I can think of cases where the input might be used in different passes for example (will look for or write a shadertoy example to test this).

Also I am not 100% sure if this matches the website experience since the website source doesn't give any details :/

Maybe a good time to add the iSampleRate uniform

@Vipitis
Copy link
Collaborator

Vipitis commented Jun 11, 2025

hey @richinsley are you still up for working on this? Otherwise I can work on the rebase.

Also I am not 100% sure if this matches the website experience since the website source doesn't give any details :/

I have been linked the following: https://gist.github.com/soulthreads/2efe50da4be1fb5f7ab60ff14ca434b8 which has some details on the data transformation - my aim is to match the website as closely as possible.

@richinsley
Copy link
Author

@Vipitis absolutely. I got caught up in crunch time at work and haven't had a chance to swing back to this. However I have some time now, so I'll handle the rebase. I'll also go over the link you provided and make those adjustments. I had to make assumptions the first time (particularly with how the FFT was handled)

@richinsley
Copy link
Author

Closing in favor of a new PR with an updated branch

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants