Changing speed by a "semitone"

dovemouse's icon

Okay,
not reeeally a max related question here but i'm having difficulties.
I want to have a transposition dial in my app that will "speed" the sound file up by a multiple of semitones.
i figured that 1 is normal speed. 2 is double speed and therefore an octave up.
And octave is 12 semitones.
1/12 = 0.833333
So the number of the dial * 0.833 then + 1 so that 0 on the dial will play at normal speed.

Max Patch
Copy patch and select New From Clipboard in Max.

It just doesn't work and i can't think why. It's probably something really obvious that i've missed but any helped would be great.
Thanks.

Gregory Taylor's icon

This is leftover from the code I use for keyboard transposing in my own patches, but it should work fine....

Max Patch
Copy patch and select New From Clipboard in Max.

ch's icon

You can do it like that as well :

Max Patch
Copy patch and select New From Clipboard in Max.

Ch.

Luke Hall's icon

A simple [expr pow(2.,($f1/12))] will do the trick.

lh

dovemouse's icon

Thanks guys.
Ch, your one has a few errors. For example: if you put in 12 it should come out with 2 but its just a smidgen under.

Gregory, that's a nice solution but not as elegant as the final one posted.

Thanks again everyone

Roman Thilenius's icon

thereishopeforus@hotmail.com wrote on Wed, 24 June 2009 14:00A simple [expr pow(2.,($f1/12))] will do the trick.

lh

or

[expr exp(.057762265*($f1-60.))]

where the 60 is the key number (middle C)

-110

-

Peter Castine's icon

The [expr pow(2.,($f1/12))] solution is preferable because expr will perform the internal arithmetic in double-precision whereas values such as 0.057762 in an object or message box are initially parsed in single-precision. It is precisely the single-precision issue that leads to the minuscule (and absolutely inaudible) discrepancy noted in Ch's example.

Of course, the easiest thing to do is to use [mtof]. That's what it's there for.

Roman Thilenius's icon

how would you do a more acccurate conversion for note
to rate? when i made mine last century i tested it against

pow(2.,(($f1-$f2)/12.))

and that gives the same results like using exp()

btw, isnt [mtof] doing the less exact calculation, too?

-110

Roman Thilenius's icon

Roman Thilenius wrote on Wed, 24 June 2009 22:25
pow(2.,(($f1-$f2)/12.))

and that gives the same results like using exp()

wow. uh oh.
of course i couldnt notice the difference when trying
only a few keys upwards. from 3 octaves on i do.

-110

-

Peter Castine's icon

[mtof] is (almost certainly) using an internal double-precision representation of pow(2, 1/12).

When you write 1.059463 (or any other float) in an object box, the object can only get a single-precision value. The content of an object box is passed to the object code in the form of atoms, and these can only contain 32-bit values.

This is all in the SDK documentation.

christiancurtis's icon

Could anyone help me out with the equation going the other way? I want to work out how much I alter the pitch of a file when i play it back over a shorter or longer time frame. For example the sample is 2000 msecs long, but i play i back over 700 msecs. How many semitones have I shifted the pitch?

mzed's icon

Take the ratio of original length to new length and feed it into [expr (log($f1)/0.693147)*12]. For 2000/700, the answer is 18.17.

Max Patch
Copy patch and select New From Clipboard in Max.

christiancurtis's icon

Thanks! Perfect!