Re: [math-fun] MIDI fun with Lisp, Macsyma & Trigonometry
As is usual in these kinds of things, a little insight makes up for lots of calculation. My original parameterization is misleading. Instead of a+b*sin(w*t), a>b>0, for instantaneous frequency, when the max frequency is a+b and the min frequency is a-b, the appropriate parameterization should be the _ratio_ of the min & max. More particularly, if min=a-b and max=a+b, then min/max=(a-b)/(a+b)=q, for some parameter 0<q<1. Furthermore, by using cos(w*t) instead of sin(w*t), we get the max frequency at t=0. We now have a relatively trivial mapping of unit circle to the unit circle: 2*atan(sqrt(q)*tan(alpha/2)), which happens to be a Mobius mapping. The derivative of this mapping wrt alpha gives us the expansion and/or contraction ratio at various points around the circle. The points on this unit circle are squeezed by sqrt(q) near alpha=0 and expanded by sqrt(q) near alpha=pi, and the ratio of these is sqrt(q)^2=q. So there is a geometric version of this problem: position the unit circle on the complex plane & consider the projection of the point -1+0i through a point P on the unit circle onto the vertical line at +1+0i. We stretch this vertical line by sqrt(q) & backproject to find the intersection of the circle again. That intersection is the location of P', the image of P under this mapping.
Date: Thu, 02 Jul 2009 05:02:41 -0700 From: Henry Baker <hbaker1@pipeline.com>
I ran into unexpected difficulties trying to program what I thought would have been a simple, straightforward MIDI file.
But the difficulties at least rewarded me with some successful Macsyma interactions.
I was trying to write a simple program to compose a MIDI (music) file that would have a simple ticking metronome clock that varied its tempo in a strictly sinusoidal pattern for one full period of the sinusoid.
In particular, if we define the "instantaneous frequency" as being proportional to the inverse of the period between ticks, then a plot of the frequency w.r.t. time should provide points that lie on one full period of a sine wave.
We can thus describe the frequency function as freq(t)=a+b*sin(w*t), where a>b>0.
All you need to know about MIDI for this problem is that the output for this file basically consists of a sequence of numbers that describe the length of time to delay until the next tick, so the MIDI file is simply a sequence of _periods_.
The major problem is to compute the locations of the ticks along the real time line, or more elegantly, around the unit circle.
[It is relatively easy to get confused in solving this problem and inadvertently produce "phase modulation" instead of "frequency modulation". Although they might sound similar, they aren't the same.]
There may be an elegant geometric way to see the answer to this problem, but I couldn't come up with it offhand.
I'm not going to give away the answer here, in case someone wants to use this as an math/programming exercise, but I learned some interesting trig & Macsyma lessons.
The main question that one would want to answer is "how many ticks do you need?" Obviously, the "average" frequency is "a", but knowing the average frequency isn't the same as knowing the average period. The answer is very elegant, but at least to my current level of understanding, not a priori obvious.
The cool thing about this problem is that almost everything about this problem is solveable in closed form using Macsyma, but it pushes Macsyma's trig capabilities to the limit (pun intended). In particular, it is possible to develop a closed form formula period(i) that gives you the delays for each integer i. Or more elegantly, there is a closed form mapping between equally-spaced points around the unit circle and the distorted version of the "same" points around the unit circle s.t. their periods satisfy the constraint above.
There are also some programming difficulties encountered with different branches of the various inverse trig functions involved in the solution of this problem. Thus, although the formula still "works", one must deal with certain branch issues that screw up the simple programming of this closed form solution.
In working with Macsyma on this problem, I became quite fond of the "trigrat" simplification function, which is now my new best friend.
--
[I'll probably now be embarrassed by someone on this list who comes up with a much more elegant "geometric" solution than mine.]
participants (1)
-
Henry Baker