I’m trying to create an audio oscillator using a GLSL TOP for a much bigger project, feeding its output through a TOP to CHOP and into an Audio Device Out CHOP.
While it generates sound, I’m encountering a distinct audible "blip"in the first frame when the main timeline loops. Additionally, the audio quality sounds low bit rate even though I’m using 32-bit float precision throughout and I have set the choptotop sample rate to 48000 and have set 48000 up as a vector sample rate in the GLSL.
Finally, the oscillator output completely drops to zero at higher frequencies (around 4600Hz) and requires a manual reset by lowering the frequency. Any ideas on what might be causing these persistent issues? Thanks!
toptochop_example.2.toe (5.2 KB)
Hi there!
The ‘blip’ visible in the trailCHOP is because the trailCHOP trails a 1 sample chop. If you supply a chop with multiply samples, it quickly goes through all first samples and then trails the last one. So that’s the reason why you see crazy high frequencies in the trailCHOP in the beginning. This is not being send to the audioCHOP.
I can’t check the audio here since I have no speakers currently, but what I suspect is your buffer_width is causing the glitch. I think this should be your sample_rate / your frame rate. So in case of 60fps: 48000/60 = 800 samples. However if you have some frameloss this buffer should also reflect that. So perhaps you can get that 60 value from: absTime.stepSeconds
I’m not 100% sure that works, but as far as I know this stepSeconds should reflect the time the last frame got processed.
So something like:buffer_width = 48000*absTime.stepSeconds
Hope this helps. I’m no audio expert myself, so I might be wrong here 
Cheers,
tim
Hey Tim,
Thanks for the pointer on absTime.stepSeconds for the buffer_width. I’ve implemented that exactly, and also swapped to mod() in the GLSL shader for phase wrapping, as high frequencies were causing values to zero out.
But honestly, the problems are still exactly the same.
The ‘blip’ in the Trail CHOP viewer is definitely still there, looking like those rapid, small wavelength oscillations right at the timeline loop. I added the trail chop so that I could see what I was hearing. I feel like the blip is a high sample rate and the rest of the timeline is occupied by a very low sample rate. “It quickly goes through all first samples and then trails the last one.” Yes, it sounds something like that.
And the u_frequency issue hasn’t gone away: if I push it above roughly 4600Hz, the wave just completely flatlines in all CHOPs (all values go to 0), and I have to drag the frequency way back down to the hundreds before it even starts producing a signal again. The mod() function was supposed to sort out large numbers for sin(), so I’m not sure why it’s still dying.
So, if buffer_width = sample_rate * absTime.stepSeconds is indeed the correct way to handle the timing and keep the samples continuous, I wonder what else could be causing the persistent low quality audio and this hard cutoff for higher frequencies? Are there other settings or global preferences I’m missing, or is this pointing to a performance bottleneck that this dynamic buffer width isn’t fixing?
Cheers,
Hi Luke,
Ah sorry, at the moment of checking I didn’t had any audio, but now testing it again I see what you mean. I’ve been trying to find a solution how to stream those frame buffers right from a shader to an audio out, but have failed as well. 
I think the thing that’s happening is that when you supply the audiodeviceout CHOP with a non timesliced chop, it tries to play it as if it was a full wave file. But since it’s only 800 samples long, it’s like 0.02 seconds of audio.. I was trying to make the data similar, as if you would timeslice a patternCHOP, by adding a shiftCHOP set to ‘relative to current frame’. It did help a little bit (the chop looks similar), but is not timesliced so also didn’t work..
I’ve looked up an old patch where I thought I did something similar but found out what I was doing is creating a shader that contains 5 seconds of audio (so like 24000 pixels), but I’m not sure that’s what you’re after.
So question to the reader (or derivative :)), anyone an idea how to solve this? Attached my try and as you can see in the infoCHOPs one is timesliced, the other not. When adding a timesliceCHOP to it, it kills the signal.
Cheers,
tim
ps. I noticed some chunky signal coming out of the shader due to the fact the timer was big. Since you multiply with a big frequency I think you get rounding errors using a 32bit float. So I looped the timer to 1 second as well so the signal stays smooth
toptochop_example.3.toe (7.1 KB)
Hey there,
Can you tell us what you are trying to achieve? Maybe there´s an easier way to achieve this thatn using glsl…
If you add an audiooscillattorCHOP to generate a reference signal and set it to 48kHz with the project still running at default 60fps it will hold 800 samples (not 48 000 and not 1024). You can see that it creates Time Slices:

This makes sense, as I guess Touchdesigner is inherently framebased and “wants” to do calculations per frame and not asynchronously from that? Please correct me if I´m wrong here!
Using you patch I could get rid of the “blips” by doing the following:
- Set the glslTOP resolutionw to
op('audio_settings')['sample_rate'] / project.cookRate
or 800 when running at 48kHz with stable 60fps.
- As the audiooscillatorCHOP cycles through its TimeSlices frame by frame I used two shiftCHOPs. The first only shifts by 1 sample (static, as the audiooscillator samples seem to start at 1 indices, not 0). The second uses this expression:
absTime.frame % project.cookRate
to jump forward one frame for each frame that touchdesigner calculates.
I get really close to the output of the audiooscillatorCHOP:

The Time Slice is set to “No” and I dont know how to change it. As I havnt really worked with Audio in Touchdesigner maybe someone else can tell how to fix this and if it is needed.
However, I believe the glsl-shader would need some work… The picture below shows two consecutive images and you can see that they dont form an ongoing sinewave:
cache1 is set to show the last frame, while sine_oscillator shows the current frame. The right bar in cache1 is cutoff but the “rest” of it doesnt appear in the sine_oscillator.
I hope I could help a bit and didnt confuse you too much - it´s getting late here… Feel free to ask if I made something not clear enough.
toptochop_example_v2.toe (11.0 KB)