Converting Frequency to Hex for Midi tuning Dump
I have written half of a Max program that generates certain frequencies that I wish to play via Midi keyboard. But I’m stuck at the point where I want to re-tune the MIDI synth on my Mac. I’ve read the page on MIDI.ORG < http://www.midi.org/techspecs/midituning.php> that spells out how to construct the System Exclusive Message, but I can’t understand how to convert frequency to two sets of hexadecimal numbers. First of all "are cents logarithmic?" and how the hell do they come up with "100 cents / 214 = .0061" ?
But I should go back to the beginning, probably, and ask if there is a Max object that already converts frequency to SysEx Hex.
And just by the way, I don’t want to simply use a synthesizer, I need to re-assign midi keys and frequencies. Thanks Jawny
There are 1200 cents in an octave, or 100 in a semitone. But why not work with a pitchbend? The math is a bit simpler and is quickly implemented. You’d have to convert frequency to a midi note number and a certain amount of pitch bend. And xbendout gives you have high precision.
|jawnypants wrote on Mon, 25 May 2009 23:46|
|But I should go back to the beginning, probably, and ask if there is a Max object that already converts frequency to SysEx Hex.|
how the hell do they come up with "100 cents / 214 = .0061" ?
To answer one part of your question, the [sxformat] object in Max will format and send your messages. It will send the values as hex, so you can determine the frequency in decimal (14-bit value sent as two 7-bit values) and it’ll make the hex conversion for you before it sends the data.
100 cents / 214 = 0.0061. Really? Not by my calculator. But it’s true if it’s "2 to the 14th" (14 bytes :: 100 / 16384 = 0.0061.) That’s a definite typo on their site which they should change.
Ahhh, you’re a genius, it must be "two to the fourteenth" and it just doesn’t print well. So I haven’t had time to follow up on the sxformat object, but I know the message is supposed to be sent as three numbers that represent the desired pitch. the first is the highest standard midi key below the pitch you want, then the next two are the "cents". But since the hex number "64" equals 100, and that is easily achievable with one of the two numbers it sends, what is the use of having two hex numbers (128 x 128)to represent those one hundred tones? Ouch, I think I just answered my question, so what you’re saying is that each hex interval = .0061 of a cent.
So let’s say I take the remainder when I convert frequency to midi, then scale the first two decimal places separately… No that only gives me a resolution of 100 (which is okay) but to actually get 16384 (128 x 128)resolution, I actually need to convert all the decimal remainder of the note to base 128, take the two most significant digits and convert them to hex. That’s just insane, am I missing something here?
And btw, I don’t want to use the pitch wheel because any one note can be adjusted on the fly, and the xbend and bendout object affect either all notes or all notes with a similar midi key number, which limits the selection of notes and makes any scale over 12 tones impossible. But a good suggestion, Thanks
jawnypants wrote on Tue, 26 May 2009 09:22
to get 16384 (128 x 128)resolution, I actually need to convert all the decimal remainder of the note to base 128, take the two most significant digits and convert them to hex. That’s just insane, am I missing something here?
No, it’s pretty close, it’s another way to look at the numbers. But you don’t need to go to base 128, technically, because sxformat will take integer values and send hex. You take the decimal remainder (which is float and has a higher precision than 14-bit), scale it to 14-bit integer (0-16383), then find the MSB and LSB with [/ 128] and [% 128] — essentially converting to base 128, but getting the values as base 10 integers (from 0-127 for each "digit"). These are the values your device should be expecting after a Tuning Change command.
See if this works. You’ll have to supply the rest of the sxformat command.
----------begin_max5_patcher---------- 1745.3ocyas0iiZCE94Yk1+CVosRyzlgwWvXnu0aR6J08osusZUEg3jgJ.GA jYmYW0+60F6jRxj.DBDmYkBaLF3v24ymqNe6su4lIyDOyKl.9Yvm.2by2jib S0XpQtYy.2LIM74njvhpINIi+Ewr+YxTy4J4OWVMdhHbdJun.35B2d1UgkQO Fms7uy4Qk5mCB5.mBHT0mAHGBT9GYJ.KGF74MW2iwymyyTW.ZyPKDYkYgo7p G1ujGGlr8ojsNMNKgWVryEDOuZpRg8dDjTexh0kuZ1paeQ7Wqt8HjCMfh7Ya No9BJeYEW+NLYB3yUm5ee6aTGkGl1c.bc5LddSPjFbnvJjxs5KXTc3YGr3uB eTjFdJfA9HfAdqLkyK3Ykgkwhr5pNWTkD4GnN.MerqXsECwxSeL3KNqbxTvj YgYKGWjLPCgX5nfjAr9Bjj.sbQtN.xHQZJWcq1eQcw5UqRdADlubsZBEfEhb vKh04f47mhi3auhj3LdjXcV4tu9Gfa6qI2npCH4Ap1ZPs297kyzSFVGdjyd3 zbdGQyAaQyQX950lcTyM7pDZiFWqPUhl1iCb7Cj+4KGAcX.FMZ.LcGIORjHx a+QdZ5B8pGR.tCphJnf.CFd8gaGr+vru9vc70GtXs2AOqpOHMt9fXVfPstBg L9Jj.l1KCzpJDbiJD8JDB19JD73qPPTlN3W6pQPMF7oVUP7ruFAM9ZDBpxZE AgrpF41LQIHRjqDLvi7b9cMphz5FSnTlXnvnKcLTv9FCkNMBRmbTLJwP8g2+ 6uGTtNSBqfnGkAOyAp4FlM+1h65QLsF8gNACjLtj.UVsXKDXqu+YpTbGakhp FAgK4uVo32HkGUGhkvJSR4kKH6CtgODtEzVABNFtAOMbaTJovQI5KxEofOsn Tj9YoYkjUfEwI7lK8P0qfulVJA3ML4Kt4EeVuYxUIW6iFYh7wJDVwyxjjSCK aDlg5rf0glIyojofYkUb1vAfdmTMu7b7I9Ljei0ZXL3n+Q17NTuPcJTDWGj0 HjzdRHw5f97XiLgb15xRQVGJOfoPXvMetSvSs.BtsQpdEuYzJNEC7me7WKZ5 80udgT8INTSnrWbtCKnmbGDVWoPBzRVy9A4s0u8hU6xLPsi2gWedVNmgmjkr 1JX53vE+PKbQSoGL0h1pjw9FiHRyBIcs9+CNY7g1Hil5sY5bBxgov3fAkLxX W8jwpzajYTxAeGXFOQ7kl8IXBo1j7BV6g0yFDy9VUdjtziVL4EufFwXSZKDC 8rB1FtjWXzAiRNNYgDmMGLOdwBdNOKh+PNOMTNTystCYxAQujFQCrRQNXj9R I8wZwGaqhbDIxdhmWBJEf3rFyFAo8IYrDnrtaMWS3ImUkUMcn1BtlJAK.KZD j2zwSXsJXfgGE5Nws3.C0VunOsc3vhDQXUuk0+mQsK8r5zuAuK8LXe6RuYIL 4ZuK8u6qM2hk53pmiqsRfl16jfH5hz6Yo012KedMgvZhK10Dc7Yrx9Pd2ozg cuKc9KnOBLwedUN3Vu.GvOAtE47fCjxXdXrG8NvOBRDKu86WfdvUBS2cWGrT p8+iInWWlhywPIFc8rUvjpBoLTWdlyihSCSVkDFo2XddsCT5U1LuWiSRnHNU 9.jy12Awnr.ug.BojQxWynYg7iQgI74fmBSVyAhEfNEApoV3ah.0C63uYyJd oMc512hgSI5hOhsVXQy.wx+MScrcanDnAqCbPtxXPcGzHAHGq3kdmrK8Jl5z st1q6ge5tmcLny+lIz928UUz8pz8mBVxKkg+d+r3xc6rY60V2TTXltzcpD+u zcsjz2rrvaB6uCzapCFC8gzgWc7H+4lPYWzNwGfrWO0Hn9hydAZmwi81drKa NZXMzz7kyDhLMr6XnVe2uzXMuDe0m.g1tQW3vai3vZsgC22hDhCzbXD7pgCq QSO7Pmw6IEd1kXi5erVkqBKSpEjzC.T50m3S5PdV5VA2Pkp6J14cH50fUJ0y NOq8xNngZJoiPcv4QnAiG0RD9Z4sZCWs+uFop2Z0I1CoJDqyi1b629a7AT6U eNunLNqxJPsoQ2aVG3WZTZ77UBIy2HJMoAOAoC2EoSsmMNrzAGSoS8CY4pU3 XcR31+U3BIbpVS2tv8Js+ER5TI7.PspWg1A5BthIcUHmaqBWvoJbHeWGOjLy V0u5I8d6ffcc17sgYASm3jplFVmabIAVZqBmUT5cxDc0KfkHjjNoTsjvgaU3 X1S3Z2NicTq6qvFJifHp1nhdGvQP++2FDwl1Iw1NN8TcBscmdLn8Dt1iWvNx Vm7aPsieCbm.NlcPNZmR8.aGgC0YspEnbcxi64aGQMf7v+IZS.iF -----------end_max5_patcher-----------
First of all, thanks for the excellent patchwork you sent; sorry it took so long for me to reply, but I had to upgrade to Max 5 AND I only get to hack at this occasionally.
The patch you wrote apparently works beautifully, I’ve got sxformat set to send a single note tuning change, and I’ve captured its output, which looks correct.
One "last" question, does anyone know the device ID of the built in Apple AU Synth? SXFORMAT needs a number and the only identifier I can find for the AU Synth is "a". I tried getting it using umenu, but it only pulls up the names, not the device ID numbers.
It wouldn’t help you much, as its useless if you don’t have more information about their sysex implementation. I doubt that it has any. Its a plug and play synth, not much to tweak. But who knows…