Frequencies are beating: How to avoid this?

Hi

So, let’s say I have a SynthDef I am using with a MIDI keyboard:

MIDIClient.init;

MIDIIn.connectAll;



(
SynthDef(\test, {

	arg out=0, freq=300, gate=1;

	var snd, sndenv;

	sndenv = EnvGen.ar(Env.adsr(0.03,0.1,0.9,0.2,curve:-2),gate:gate, doneAction:2);

	snd = Saw.ar(freq,0.2);

	snd = snd*sndenv;

	Out.ar(out,snd!2);

}).add;
)

(
var notes;

notes = Array.newClear(128);

MIDIdef.noteOn(\test_on, { arg veloc, num, chan, src;
	notes[num] = Synth(\test, [
		\freq, num.midicps,
	]);
});


MIDIdef.noteOff(\test_off, { arg veloc, num, chan, src;
    notes[num].release;
});
)

Especially when I play keys which are close to each other I can hear a lot of frequency beating and with other SynthDefs even more.
Is there anything I could do to avoid beating?

The beating that you hear is an acoustic phenomenon, not specific to SC. It’s a function of the fundamental frequencies and spectra of the notes you’re playing.

For more information: https://en.m.wikipedia.org/wiki/Beat_(acoustics)

Yeah, I am aware of this. But when I compare it to my hardware Synthesizer I don’t hear that much beating.

Maybe I perceive things a little wrong. I just wonder whether I could do something to reduce the effect of beating within SC.

Fair enough. Assuming we’re comparing an unfiltered saw wave from your synth with one from SC, it’s tough to say for sure without knowing how your synth generates saw waves.

Anything that influences the fundamental frequency (for example, VCO v/octave scaling) or spectrum (any nonlinearities in filters/mixers/vcas your oscillator might be passing through, any particular means of limiting aliasing in any digital oscillator such as Saw.ar) could affect the quality of the beating you hear.

Off the top of my head, if it’s the rhythmic patterns of the beating that you’re trying to control, you might experiment with non-equal temperaments when converting midi note numbers to frequencies.

If it’s some aliasing-related artifact, you might try a UGen with a different approach to antialiasing, like SawDPW, DPW4Saw, or BlitB3Saw from SC3plugins.

If it’s a function of SC sounding “brighter” than you’re accustomed to (sometimes a factor when you’re comparing hardware and software), you might try a bit of subtle filtering near the top of the audible frequency range. In an analog synthesizer, even if a VCO is going through a wide open LPF there’s still often a slight softening of the high frequencies, and any mixers, VCAs, etc in the signal path will all have some amount of subtle nonlinearity.

Hope that helps!

1 Like

+1 for looking at other tunings.

Whole number frequency ratios don’t beat.

Every ratio in our equal tempered system is irrational. The thirds are all too wide. Major triads just sound nasty.

This is one of the reason that guitar based rock songs different - guitarists tune from string to string using harmonics and beats. So intervals at the same fret are pure. Intervals between frets are equally tempered so you end up with a hybrid, but the net result is less beating than a keyboard playing the same pitches

European Classical music through the 19th c was written for and heard on tunings that had at least some sweet triads, and in which every key in fact sounded different…

Look at Bach’s well tempered clavier: the prelude in C relies on the beauty of the home key chords: the prelude in C# relies on scale patterns (iirc!) because the c# triad sounded nasty in the Werkmeister III tuning that Bach (perhaps!) used…

Ugliness in the tuning system is clearer when you use purer timbres

Happily SC has convenient facilities for experimenting with tunings see Scale

Lots of great info here, but I also doubt that OP’s question about the difference between the sound of SC and some hardware synth is a matter of tuning in that sense.

Assuming we’re talking about an analog synth, tuning is almost always rigorously equal tempered (1/12 volt per semitone) and in practice any deviations from pure 12TET are due to miscalibration of the expo converters in VCOs, resulting in more or less stretched octaves. (Not that you can’t exploit this in the same way a piano tuner would, but that’s a different story!)

A lot of them try to, but in doing so they accumulate a couple cents error per pair of adjacent strings and the end result can be pretty nasty! As a guitarist I think it’s more accurate to say that tuning a guitar is a compromise between a lot of factors (physical and aesthetic) and everyone learns to balance those factors to suit their own ears as they learn the instrument.

Depends on what you mean by “purer.” To my ears, complex chords in equal temperament often sound better with timbres that have fewer upper partials (one of the reasons you find so many “rolled off” guitar/rhodes/organ/etc sounds in jazz), while unfiltered saw waves work magic in simple integer ratios.

Much as I do love Bach (and Harry Partch!), chromaticism has given us plenty of great music as well! I like to think of all these approaches to tuning as different historically/culturally contingent abstractions on top of physical acoustics, each with its own range of musical possibilities.

Absolutely agreed. Love that it’s part of the default Event pitch model as well.

Cool, thanks for both of your input :slight_smile:

I am sorry, I can’t really make it work.
What I try looks like this:

(
var notes;

notes = Array.newClear(128);

t = Tuning.just;

MIDIdef.noteOn(\test_on, { arg veloc, num, chan, src;
	notes[num] = Synth(\test, [
		\freq, Scale.lydian(t).num.midicps,
	]);
});


MIDIdef.noteOff(\test_off, { arg veloc, num, chan, src;
    notes[num].release;
});
)

It obviously doesn’t work. I considered this:
https://doc.sccode.org/Classes/Scale.html
But I don’t quite know where to go.


Ok, found this:

Now it looks like this and works:

(
var notes, scale;

notes = Array.newClear(128);
scale = Scale.chromatic.tuning_(\just).postln;


MIDIdef.noteOn(\test_on, { arg veloc, num, chan, src;
	notes[num] = Synth(\test, [
		\freq, num.degreeToKey(scale).midicps,
	]);
});


MIDIdef.noteOff(\test_off, { arg veloc, num, chan, src;
    notes[num].release;
});
)