Hi there, i’m doing my bachelor thesis on square wave conversion and audio output using a Tesla Coil.
A Tesla Coil needs pure Square Waves as an output because of it’s design and i’m currently looking into using Sonic Pi to generate a square wave from my already existing frequency and Amplitude (that i generate by playing an instrument, doesn’t really matter though).
When i used things like “use_synth :square” with the ‘play’ keyword and also the “synth :square note: etc.” the sound i got didn’t really sound like a true square wave.
Is sonic pi suited to generate Square waves without additional effects, reverbs etc. or should i rather steer clear of it? I already got a conversion working in Python but Sonic Pi seemed like the cleaner solution thats why i’m asking.
This is my current code, not sure if it helps (hope i format this right otherwise, sry):
live_loop :listen do
use_real_time
use_synth :square
freq, amp = sync "/osc*/sound"
if freq > 0
midiNote = hz_to_midi(freq)
end
#synth :square, note: midiNote, amp: amp
play midiNote, amp: amp
end
Can you explain why it doesn’t sound like a true square wave?
Is it possibly because you can hear the low pass filter that’s part of that vast majority of Sonic Pi’s synths. The default is 100 which cuts off a lot of the very harsh aspects of the timbre. You can disable that by setting it to a much higher value:
It’s a bit tough to describe but i’ll try my best.
So if you look up square wave music like the mp3 i attached in this message via a wetransfer link you can hear that it’s like “clearcut” sound with no reverbs, oscialltions etc. because the Tesla coil (and other things) can’t deal with anything other than 1 or 0.
When i try to use the code i sent above (even with your cutoff) it sounds like it has a lot of reverb or even “effects” in it.
To explain further i built a Theremin using 2 ultrasound sensors (theremin is the instrument where you play using the distance of your hands to the instrument maybe you know it) and i mapped the distance to hz frequencies. If i now play the instrument and go from a high frequency to a low frequency the Sonic Pi output sounds like (for lack of a better description) wind chimes that are being hit or something like that.
I’m really sorry for not explaining better but the sound simply seems like it has a lot of effects in it i guess and that lead me to assume maybe its just sounding like a square wave while still being a sine wave or something like that. Maybe the problem is also that the code is just wrong because when i stay at the same frequency for a time it’s not really just a single sound but rather a kind of oscillation.
I am very knew to this kind of topic so i might also be completely wrong but i hope you got what my problem is or know a solution (if there is any)
I think part of the effect (as well as the cutoff mentioned by Sam) might be the way the amplitude decays over time due to the release opt defaulting to 1.
If you set release to 0 and use sustain to control the length instead, I think it sounds a lot closer:
live_loop :listen do
use_real_time
use_synth :square
freq, amp = sync "/osc*/sound"
if freq > 0
midiNote = hz_to_midi(freq)
end
#synth :square, note: midiNote, amp: amp
play midiNote, amp: amp, cutoff: 130, release: 0, sustain: 0.5
end
Hm honestly not a big difference in the sound. I think it might sound a bit less bumpy now but still with a lot of reverb i think.
Do you think it might also be a problem with the number of OSC messages i’m sending it? I am updating the sound every 0.1 seconds with a pyTime.sleep(0.1) in my python script that sends the freq and amp.
i read somewhere that there is something like a synth instance with a control keyword that updates the sound smoothly might that be a solution? or is it probably not that at all?
Thanks!
Oh, if the loop is updating 10 times a second, each one will be creating a new synth without stopping the old one, so you’ll get loads of sounds playing at the same time, creating weird effects.
Creating a single synth and using control should definitely help. Something like:
synth = play 0, amp: 1, cutoff: 130, release: 0, sustain: 60, slide: 0.1
live_loop :listen do
use_real_time
freq, amp = sync "/osc*/sound"
if freq > 0
midiNote = hz_to_midi(freq)
end
control synth, note: midiNote, amp: amp
end
Note that you need to give the initial play a duration, and it will stop after that amount of time. I gave it 60 seconds, but you can increase that if needed.
You can also play around with the slide option to adjust how quickly the synth slides up to the new values.
Interesting i’ll try it out now thanks!
is there also a way to make it last indefinitely? i would like to play the instrument for as long as i like. I could of course also just do like a million seconds or something haha
wow this worked really well, sounds pretty good now!
The only last thing thats bothering me a little bit is there is a notable delay to my hand movements and the reaction of the output.
For example if i move my hand up it takes half a second to change the pitch. Is that what you meant with the slide option? Altough this problem was already present even before i used slide:
Is it just inevitable because i’m sending data via OSC and then again via bluetooth to the output so theres bound to be delay?
The slide parameter might have some effect on the delay (it will take longer to reach the final note, although it should start changing at the same time). However I suspect this delay is a combination of the delays from all the parts, and it will be difficult to reduce it much.
I don’t think there’s a way to make a synth play indefinitely in Sonic Pi, but there’s nothing stopping you making it a million (or more) seconds .