Science of Chords - sine-wave

I've been doing research on trying to understand the way sounds and sine waves work, particularly with chords. So far, my understanding is as follows:
b(t) = sin(Api(t)) is the base note of the chord at frequency A.
T(t) = sin(5/4piA(t)) is the major third of the base b(t).
D(t) = sin(3/2piA(t)) is the dominant (fifth) of the base b(t).
A(t) = sin(2Api(t)) is the octave.
Each one alone is a separate frequency which is easy for a computer generator to sound. However, the major chord of the note with frequency A is as follows:
Major Chord = b+T+D+A
I was wondering if anyone has a way to make a computer synthesizer play this function so I can hear the result; most programs I have found only take Hz as an input, an while this function has a wavelength, it's different from the simple sine wave with the same wavelength.
Note: will post this in the physics and computer sections as well - just wondering if you musicians know something about this.

It's a bit unclear to me what you're trying to do, so I'm explaining a few things, and giving you a few options to investigate further, depending on what your purpose is.
The de facto means of synthesizing music on computers uses MIDI (Musical Instrument Digital Interface). Because musicians rarely think directly in terms of frequencies or wavelengths (they count steps or half-steps along a scale), MIDI represents each pitch with an integer, that represents a number of half-steps. By default, MIDI assumes these pitches are tuned using a standard called "12-Tone Equal Temperament" (12TET), and, unfortunately, it isn't particularly easy to make it use other tunings.
What does this mean? And why is it a problem? (I'm not sure how much of this you know already, so I apologize if I'm repeating what you know)
In theory what you say about tuning being based on frequency ratios is 100% absolutely correct -- this is a system called Just Tuning. The major third is a 5/4 ratio and the perfect fifth is a 3/2 ratio. However instruments with fixed-pitches (keyboards, fretted instruments, etc...) are rarely tuned that way in practice. Instead, they compromise, by rounding each note in a chromatic scale to the nearest 12th of an octave. Since an adding octave is equivalent to multiplying the initial frequency by 2, adding a 12th of an octave is the equivalent of multiplying the initial frequency by 2^(1/12). This is how all the half steps on a piano are usually tuned.
So instead of the pure ratios, you would actually have:
sin(A pi t)
sin(2^(4/12) A pi t)
sin(2^(7/12) A pi t)
sin(2^(12/12) A pi t)
Note: Compare 2^(4/12) ~ 1.26, with 5/4 = 1.25. Also compare 2^(7/12) ~ 1.498, with 3/2 = 1.5.
These are exactly the frequencies that any MIDI synthesizer will play, given the MIDI notes numbered n, n+4, n+7, and n+12. So, if you are only looking to play a chord, and don't care about the frequency ratios being pure (just), you can just use MIDI.
However, if you are looking for something that will play the actual just ratios, it will be a bit trickier. You might start with looking at some of the things here: https://music.stackexchange.com/questions/351/software-that-allows-playing-in-different-temperaments
If you just want to see what they sound like, you can check out this youtube video:
https://www.youtube.com/watch?v=6NlI4No3s0M
If you can write software, you might try writing your own, but I don't want to go into how to do that if that's not going to be helpful.
I'm not sure what kinds of programs you're describing that "only takes Hz as input". Is this a software library (like an API call?) or something different? There are (obviously) API calls that can send more complex data to the soundcard than a single-frequency wave.
EDIT: I've not used it, but it looks like perhaps this software is capable of doing what you want: https://www.youtube.com/watch?v=z0NZQMiDdNU

I think you are going at the problem from a wrong direction. You are using sinoid signals as the basis of your "chords" and pure intervals.
The output of that is strictly periodic, with a period that is the least common multiple of the individual periods. So basically you have not as much a "chord" but rather a "tone".
Organs use that technique: you can combine an 8" pipe with a 5⅓" pipe in order to arrive at a tone sounding like it came from some funny 16" pipe. That's not a "chord", that's registration. Classical composition theory does not allow quint parallels to avoid that effect: quints must only occur transitorily and more often than not moving in a different direction or out of synch with the base note.
"chords" play with aural ambiguities between tone colors and voices: they excite the same region in your inner ear. However, real "chords" and choral effects also have beatings and interferences from non-ideal frequency ratios, and the tones they are made of have harmonics of their own, making it possible to discern them as independent entities.
The experienced music listener perceives all that as an independent phenomenon. However, if you start with pure sinoids or highly frequency-locked comparatively pure sources like snare-less organ pipes, this becomes hard to do.
So I'm not sure you are doing yourself a favor by looking at sinoids. It's like trying to understand a painting based on primary color components. It's more of a reproduction toolkit than anything tied to higher-level perception.

A very low-barrier way to play is to use wavepot
The code to do what you ask in your question is
var A = 440
export function dsp(t) {
var b = Math.sin(t * Math.PI * 2 * A);
var T = Math.sin(t * Math.PI * 2 * 5/4 * A);
var D = Math.sin(t * Math.PI * 2 * 3/2 * A);
var O = Math.sin(t * Math.PI * 2 * 2 * A);
return (b + T + D+ O) * 1/4
}
which is at this link.
Note that this might not sound much like a chord to you due to the fact that sine waves have no harmonics. Here is the same example, but using a saw-tooth waveform, which has many harmonics.
var A = 440
//function f(x){return Math.sin(x) }
function f(x){return 2 * ( (x/(2*Math.PI) % 1) -.5) } //sawtooth
export function dsp(t) {
var b = f(t * Math.PI * 2 * A);
var T = f(t * Math.PI * 2 * 5/4 * A);
var D = f(t * Math.PI * 2 * 3/2 * A);
var O = f(t * Math.PI * 2 * 2 * A);
return (b + T + D+ O) * 1/4
}

Related

Compiler Type Promotion of Right Hand Side expressions automatically in an Assignment Statement

Why does a compiler not type promote all evaluations of expressions in the right hand side of an assignment expression to at least the left hand sides type level?
e.g.
"double x = (88.0 - 32) * 5 / 9" converts to Celsius from Fahrenheit correctly but...
"double x = (88.0 - 32) * (5 / 9)" will not.
My question is not why the second example does not return the desired result. My question is why does the compiler not type promote the evaluation of (5/9) to that of a double.
Why does a compiler not type promote all evaluations of expressions in
the right hand side of an assignment expression to at least the left
hand sides type level?
Very good question. Actually,let's suppose for sometime that the compiler does this automatically. Now, taking your example :-
double x = 88.0 - 32 * 5 / 9
Now the RHS part of this assignment can be converted into double completely for all tokens(lexemes) in several of ways. I am adding some of them :-
88.0 - 32 * (double)(5 / 9)
88.0 - 32 * 5 / 9 // default rule
88.0 - (double)(32 * 5) / 9
Individually type-casting to double every token which doesn't seem to be a double entity.
Several other ways.
This turns to combinatorial problem like "In how many ways a given expression can be reduced to double(whatever type)?"
But, the compiler designers wouldn't take such a pain in their *** to convert each of the tokens to the desired highest type(double here) considering the exhaustive use of memory. Also it appears like an unnatural rationale behind it doing this way for no reason because users could better perform the operation by manually giving some hints to the compiler that it has to typecast using the way coded by the user.
Being everything automatic conversion is not going to yield you the result always, as sometimes what a user wants may not be achieved with this kind of rationale of automatic type promotion, BUT, the vice-versa of type-promoting will serve in a much better way as is done by the compilers today. Current rule for type-casting is serving all the purposes correctly, though with some extra effort, but, FLAWLESSLY.

Iteration to find number (from exponential function)

I finally got the formula for the distance from a curve to a point running:
approx = 2 * (b * (Math.Log(a) * (Math.Log(k) * Math.Pow(k, (b * cycleX))) * Math.Pow(a, (Math.Pow(k, (b * cycleX)))) * (Math.Pow(a, (Math.Pow(k, (b * cycleX))))) - points[i].Y) + cycleX - points[i].X);
So, as approx goes closer to 0, the cycleX gives me the right coordinate from which to calculate the distance to the point.
The only issue here is defining a way to modify cycleX. I tried using a series of if's, but with them sometimes approx ends up jumping on to positive numbers (coming from negatives). What should I do to get the right modification to the value of cycleX?
Note: It usually needs to come down to 0.0001 to get something within the range of -1 to 1.
For this kind of problem, it's often useful to know about Newton's method:
Of course, the forumula for that is
Of course, besides the fact that for some functions this quite unstable (I don't expect yours to be, though), implemented purely for your case, it would mean you would need to calculate yet another derivative (of your derivative)! However, I think for your case, you might be able to just approximate the derivative.
You didn't mention the language your implementation would eventually be in, so I'll just use javascript for convenience.
To estimate your derivative, simply choose a deltaX that would be convenient.
So if you have a function
var df = function (cycleX) {
return 2 * (b * (Math.log(a) * (Math.log(k) * Math.pow(k, (b * cycleX))) * Math.pow(a, (Math.pow(k, (b * cycleX)))) * (Math.pow(a, (Math.pow(k, (b * cycleX))))) - Y) + cycleX - X);
};
you can estimate it's derivative via
y = df(cycleX);
y1 = (df(cycleX + deltaX) - y) / deltaX;
And then proceed via.
cycleXnew = cycleX - y / y1;
And then it's just a matter of looping until it converges (or not).
See example jsFiddle: http://jsfiddle.net/jfcox/3wRtj/
Edit: I give no guarantees as to how fast it might converge or even how well an estimated derivative would work with respect to Newton's method. For the parameters I've tried given your function f(x) = a^(k^(bx)), it seems to work well, but I haven't tried much.
Edit II. Of course, the above jsFiddle also assumes only a single solution that we'd need to search for.

audio sequencer with swing (shuffle) Obj-C

I'm working on a drum computer with sequencer for the iPad. The drum computer is working just fine and writing the sequencer wasn't that much of a problem either. However, the sequencer is currently only capable of a straight beat (each step has equal duration). I would like to add a swing (or shuffle as some seem to call it) option, but I'm having trouble figuring out how.
'Swing' according to Wikipedia
Straight beat (midi, low volume)
Beat with Swing (midi, low volume)
If I understand correctly, swing is pretty much achieved by offsetting the eights notes between the 1-2-3-4 with a configurable amount. So instead of
1 + 2 + 3 + 4 +
it becomes something like
1 +2 +3 +4 +
The linked midi files illustrate this better...
However, the sequencer works with 1/16th or even 1/32th steps, so if the 2/8th (4/16th) note is offset, how would that affect the 5/16th note.
I'm probably not approaching this the correct way. Any pointers?
Sequencer code
This is the basics of how I implemented the sequencer. I figured altering the stepDuration at certain points should give me the swing effect I want, but how?
#define STEPS_PER_BAR 32
// thread
- (void) sequencerLoop
{
while(isRunning)
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
// prepare for step
currentStep++;
if(currentStep >= STEPS_PER_BAR * activePatternNumBars)
currentStep = 0;
// handle the step/tick
...
//calculate the time to sleep until the next step
NSTimeInterval stepDuration = (60.0f / (float)bpm) / (STEPS_PER_BAR / 4);
nextStepStartTime = nextStepStartTime + stepDuration;
NSTimeInterval now = [NSDate timeIntervalSinceReferenceDate];
// sleep if there is time left
if(nextStepStartTime > now)
[NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceReferenceDate:nextStepStartTime]];
else {
NSLog(#"WARNING: sequencer loop is lagging behind");
}
[pool release];
}
}
Edit: added code
I'm not familiar with the sequencer on iOS, but usually sequencers subdivide steps or beats into "ticks", so the way to do this would be to shift the notes that don't fall right on a beat back by a few "ticks" durring playback. So if the user programmed:
1 + 2 + 3 + 4 +
Instead of playing it back like that, you shift any notes falling on the "and" back by however many ticks (depending on exactly where it falls, how much "swing" was used, and how many "ticks" per beat)
1 + 2 + 3 + 4 +
Sorry if that's not much help, or if I'm not much more than restating the question, but the point is you should be able to do this, probably using something called "ticks". You may need to access another layer of the API to do this.
Update:
So say there are 32 ticks per beat. That means the "+" in the diagram above is tick # 16 -- that's what needs to be shifted. (that's not really a lot of resolution, so having more ticks is better).
Lets call the amount we move it, the "swing factor", s. For no swing, s = 1, for "infinite" swing, s=2. You probably want to use a value like 1.1 or 1.2. For simplicity, we'll use linear interpolation to determine the new position. (As a side note, for more on linear interpolation and how it pertains to audio, I wrote a little tutorial) we need to break the time before and after 16 into two sections, since the time before is going to be stretched and the time after is going to be compressed.
if( tick <= 16 )
tick *= s; //stretch
else
tick = (2-s)*tick + 32*(s-1) //compress
How you deal with rounding is up to you. Obviously, you'll want to do this on playback only and not store the new values, since you won't be able to recover the original value exactly due to rounding.
Change the number of steps to 12 instead of 16. Then each beat has 3 steps instead of 4. Triplets instead of 16th notes. Put sounds on the first and third triplet and it swings. Musicians playing swing use the second triplet also.
Offsetting the notes to create a shuffle does not give you access to the middle triplet.

Comparing a saved movement with other movement with Kinect

I need to develop an application where a user (physiotherapist) will perform a movement in front of the Kinect, I'll write the data movement in the database and then the patient will try to imitate this motion. The system will calculate the similarity between the movement recorded and executed.
My first idea is, during recording (each 5 second, by example), to store the position (x, y, z) of the points and then compare them in the execution time(by patient).
I know that this approach is too simple, because I imagine that in people of different sizes the skeleton is recognized differently, so the comparison is not reliable.
My question is about the best way to compare a saved motion with a movement executed (on the fly).
I have done this, where a doctors frame is projected onto the patients frame, but with the whole skeleton this doesn't work so well because of different bone heights :/. The code can be found here. It is in beta 2 code, the more current version can be found here, although it is not currently working perfectly
As for comparing, do something like this
for (int i = 0; i < patientList.Count; i++)
{
int diff = (int)Math.Abs(patientList[i] - doctorList[i]);
if (diff < 100) //or whatever number you want
{
Debug.WriteLine("Good Job");
}
}
I have abandoned the idea of a whole figure because of the bone heights mentioned by Fixus, so my current program looks some thing like:
EDIT
This is the concept of camparing two movements with kinect and calculate a similarity between the two movements I explain in depth.
Suppose I have the following 2 points, point A (0, 0, 0) and point B (1, 1, 1). Now I want to find the difference from point A to B, so I would subtract all of the X, Y, and Z numbers, so the difference is 1 X 1 Y 1 Z. That is the simple stuff. Now to implement it. The code I have written above, I would implement like this.
//get patient hand coordinates
double patienthandX = Canvas.GetLeft(patienthand);
double patienthandY = Canvas.GetTop(patienthand);
//get doctor hand coordinates
double doctorhandX = Canvas.GetLeft(doctorhand);
double doctorhandY = Canvas.GetTop(doctorhand);
//compare difference for each x and y
//take Absolute value so that it is positive
double diffhandX = Math.Abs(patienthandX - doctorhandX);
double diffhandY = Math.Abs(patienthandY - doctorhandY);
Now here comes another issue. The doctor coordinates are always the same, but what if the patient isn't standing where the doctor coordinates were recorded? Now we implement more simple math. Take this simple example. suppose I want point A(8, 2) to move to point B(4, 12). You multiply the x and y's of A to get to B. So I would multiply the X by .5, and the Y by 6. So for Kinect, I would put a element on the patients hip, then compare this to the doctors hip. Then multiply all of the doctor joints by that number to achieve the doctor joints on top of the patients (more or less). For example
double whatToMultiplyX = (double) doctorhipX / patienthipX;
double whatToMultiplyY = (double) doctorhipY / patienthipY;
This is all pretty simple, but bringing it together is the harder part. So far we, 1) Scale the doctor frames on top of the patient frames, 2) Calculate the difference. 3) Compare the difference throughout the entire rep. and 4) Reset for the next rep. This seems simple but it is not. To calculate the entire difference for the rep, do something like this:
//get patient hand coordinates
double patienthandX = Canvas.GetLeft(patienthand);
double patienthandY = Canvas.GetTop(patienthand);
//get doctor hand coordinates
double doctorhandX = Canvas.GetLeft(doctorhand);
double doctorhandY = Canvas.GetTop(doctorhand);
//compare difference for each x and y
//take Absolute value so that it is positive
double diffhandX = Math.Abs(patienthandX - doctorhandX);
double diffhandY = Math.Abs(patienthandY - doctrorhandY);
//+= so that it keeps adding to it.
totaldiffhandX += diffhandX;
totaldiffhandY += diffhandY;
Now we can compare, and say:
if (totaldiffhandX < 1000 && totaldiffhandY < 1000) //keep numbers pretty high since it is an entire rep
{
//reset difference
totaldiffhandX = 0;
totaldiffhandY = 0;
//tell the patient good job
Debug.WriteLine("Good Job");
}
This is pretty easy, but keep in mind you must do this for every single joint's x and y. Otherwise it will not work. Hope this Helps.
First of all remember that people are diffrent. Every person has diffrent height, width, weight, diffrent bones length etc etc
You`re code probably will never work cause of this.
Secondly you need to think more geometrically. Don`t think about points only, think with vectors, their directions. Each movement is movent of some vectors in some directions.
Then the proportion. You need to configure application for each user.
You have some pattern. The patter is your physiotherapist. You need to remember not only his movements but also his body. Arm length, leg length, distances etc. Each user that will be using your app also need to me mesured. Having all this data you can compare movement by scaling sizes and comparing directions of movent
Of course remember that there are some very simple moves like for example. They can be recognized by simple mathematic by checking actual position of the hand and checking direction of the movement. You need for this 3 control points and you`re at home :)
Gesture recognizing isn`t a simple thing

Getting any point along an NSBezier path

For a program I'm writing, I need to be able to trace a virtual line (that is not straight) that an object must travel along. I was thinking to use NSBezierPath to draw the line, but I cannot find a way to get any point along the line, which I must do so I can move the object along it.
Can anyone suggest a way to find a point along an NSBezierPath? If thats not possible, can anyone suggest a method to do the above?
EDIT: The below code is still accurate, but there are much faster ways to calculate it. See Introduction to Fast Bezier and Even Faster Bezier.
There are two ways to approach this. If you just need to move something along the line, use a CAKeyframeAnimation. This is pretty straightforward and you never need to calculate the points.
If on the other hand you actually need to know the point for some reason, you have to calculate the Bézier yourself. For an example, you can pull the sample code for Chapter 18 from iOS 5 Programming Pushing the Limits. (It is written for iOS, but it applies equally to Mac.) Look in CurvyTextView.m.
Given control points P0_ through P3_, and an offset between 0 and 1 (see below), pointForOffset: will give you the point along the path:
static double Bezier(double t, double P0, double P1, double P2,
double P3) {
return
pow(1-t, 3) * P0
+ 3 * pow(1-t, 2) * t * P1
+ 3 * (1-t) * pow(t, 2) * P2
+ pow(t, 3) * P3;
}
- (CGPoint)pointForOffset:(double)t {
double x = Bezier(t, P0_.x, P1_.x, P2_.x, P3_.x);
double y = Bezier(t, P0_.y, P1_.y, P2_.y, P3_.y);
return CGPointMake(x, y);
}
NOTE: This code violates one of my cardinal rules of always using accessors rather than accessing ivars directly. It's because in it's called many thousands of times, and eliminating the method call has a significant performance impact.
"Offset" is not a trivial thing to work out. It does not proceed linearly along the curve. If you need evenly spaced points along the curve, you'll need to calculate the correct offset for each point. This is done with this routine:
// Simplistic routine to find the offset along Bezier that is
// aDistance away from aPoint. anOffset is the offset used to
// generate aPoint, and saves us the trouble of recalculating it
// This routine just walks forward until it finds a point at least
// aDistance away. Good optimizations here would reduce the number
// of guesses, but this is tricky since if we go too far out, the
// curve might loop back on leading to incorrect results. Tuning
// kStep is good start.
- (double)offsetAtDistance:(double)aDistance
fromPoint:(CGPoint)aPoint
offset:(double)anOffset {
const double kStep = 0.001; // 0.0001 - 0.001 work well
double newDistance = 0;
double newOffset = anOffset + kStep;
while (newDistance <= aDistance && newOffset < 1.0) {
newOffset += kStep;
newDistance = Distance(aPoint,
[self pointForOffset:newOffset]);
}
return newOffset;
}
I leave Distance() as an exercise for the reader, but it's in the example code of course.
The referenced code also provides BezierPrime() and angleForOffset: if you need those. Chapter 18 of iOS:PTL covers this in more detail as part of a discussion on how to draw text along an arbitrary path.