[linux-audio-dev] XAP: Pitch control

Steve Harris S.W.Harris at ecs.soton.ac.uk
Tue Dec 10 07:06:01 UTC 2002


On Tue, Dec 10, 2002 at 03:56:32 +0100, David Olofson wrote:
> > > 	linear_pitch = note_pitch * (12.0 / 16.0);
> > >
> > > That is, "stretch" the scale so you need 16.0 note_pitch units to
> > > span one octave. Now, all of a sudden, your synths - apparently
> > > written for 12tET - can play 16tET. They don't know it, or
> > > understand it, but they're playing the right notes.
> >
> > Sure, I just think the factor of 12 is ugly.
> 
> Well, so do I... 1/12 is just as bad IMHO, but hopefully, we'll only 
> see that in note editors, appregiators and that kind of places. (And 
> we could actually wrap it in macros, to keep people from having bad 
> ideas... *heh*)

OK, heres a concrete example of how 12/octave will suck:

Imagines a (farily common) setup, an external LFO feeding the ampltitude
and pitch inputs of a monosynth (realisticly the LFO would be in another
synth and it would be controlling more than synth, but this just makes the
example simpler).

[LFO]---+----->[         ]
        |      [         ]
        '----->[Monosynth]----->[JACK]
               [         ]
[Keybd]------->[         ]
 
OK, there are two things that users will expect in a system like this, 1)
that an unattenuated LFO will modulate up/down by one octave (thats easy
we just give the range of the LFO as 12.0), 2) that LFOs and oscillators
will modulate together sensibly.

2) is harder I think the only way of making it work is to make the audio
range the same as the LFO range (thats what they do in CV systems), so we
set the system 0dB level to 12.0, it means we have to scale going in and
out of laldspa/jack, but thats not he end of the world.

So, the pseudocode for these plugins looks like:

	LFO {
		out = sin(freq) * 12.0;
	}

	Keybd {
		out = midinumber + offset;
	}

	Monosynth {
		out = sin(base + 2^((pm + pitch) / 12.0)) * am * 12.0;
	}

	JACK {
		jack_out = in / 12.0;
	}

OTOH the 1.0/octave equivalent looks like:

	LFO {
		out = sin(freq);
	}

	Keybd {
		out = midinumber/12 + offset;
	}

	Monosynth {
		out = sin(base + 2^(pm + pitch)) * am;
	}

	JACK {
		jack_out = in;
	}

I know which I prefer. There are other solutions to the sclaing problem,
but AFAICT they all involve actualy using 1.0/octave really and just
scaling it up and down every time you want to use it. Pointless.

> It's a matter of "packing" the 1.0/note note_pitch into something 
> that's physically equivalent to 1.0/octave when dealing with 12tET, 
> just so you don't have to use scale converters at all for 12tET.

Except that its a factor if 12, not a factor of 1. Factors of 1 are really
easy to deal with ;)
 
> Right. Nor does 12.0 / octave. One looks nice in syths and various 
> event processors, and the other looks nice in note/scale oriented 
> things. Both result in note_pitch and linear_pitch being the same 
> value for the same actual pitch in 12tET, so you *only* need to mess 
> with scale converters when you actually want non-12tET.

12/octrave does /not/ look nice in synths, you need to remove the factor
of 12 to convert the pitch into a frequency.

- Steve 



More information about the Linux-audio-dev mailing list