Midi to (float) frequency cenversation using mtofextended


#1

Hi,
For some kind of thesis I'm currently working on physical modelling algorithms (mainly Digital Waveguide) and I'm trying to implement some of this on a Axoloti board. It works quite well so far but since I code everything in float, I sometimes struggle with conversions to fixed point.
Basically I want to convert a pitch parameter (which should be a midi note) to the corresponding frequency in float. I want to use MTOFEXTENDED() for that to avoid a power calculation but I wasn't able to get good results there. Here is my piece of code:

uint32_t p = midi_note*(1<<27);
MTOFEXTENDED(p, freq);
freq_float = freq*(float)(1.0f/(1<<27))*sample_rate;
LogTextMessage("freq = %f \n", freq_float);

So in the first line I want to convert a midi note (integer range 0 to 127) to q5.27 fixed point, then I call mtofextended and in the third line I convert to float and multiply with the sampling frequency to get from a phase increment to an actual frequency. As an output I just get super high numbers, which don't make sense at all. Can anyone tell me what I'm getting wrong here? Is mtofextended probably expecting an other fixed point format than q5.27?
Thanks in advance for your help!
Best, Flori


#2

I'd expect the phase increment to be q0.32, i.e. a phase increment of 0x80000000 means half the sample rate. Are your numbers 32 times too high?


#3

Hey, thanks for your reply. When I divide the result by 32 I get numbers between 0 an 24000, what makes kind of sense, so the output seems to be q0.32. But it doesn't represent the numbers of the input midi notes at all, so the input seems to be not q5.27 but something different. I will probably try some formats till it works, thanks for your help so far!
Is there actually some kind of documentation for built-in functions like mtof and others including input and output datatypes? I couldn't find anything like this.


#4

I solved it!
MTOFEXTENDED() seems to expect signed q11.21 values with an offset of 64. So here is my piece of code converting a midi note to a float frequency.

uint32_t p = (midi_note - 64)*(1<<21);
MTOFEXTENDED(p, freq);
freq_float = freq*(1.f/(4*(float)(1<<30)))*sample_rate;

Thanks for your advice again with the q0.32 output, it helped a lot. Still there is my question if there is some kind of documentation for these functions? Probably it is also because I did not work a lot with fixed point math so far, but it would be great not to guess all parameter formats :slight_smile:


#5

great! glad you got it sorted. yeah fixed point numbers can be a pain sometimes, and documentation is sparse... maybe here: https://sebiik.github.io/community.axoloti.com.backup/t/coding-axoloti-objects/2606

also, do you plan to release your axoloti work as objects?


#6

Yes I found that post as well but it just mentioned some lookup-table functions without specifying their parameters. I thought there could be probably something a bit more detailed especially about the datatypes that are used internally.

Yes for sure I could release what I'm working on, if there would be an interest in the community :slight_smile:
How would that work?


#7

unfortunately i don't think that exists, at least no resource that i would be aware of. for your mentioned problem i would have probably looked at some midi in objects code to see how incoming midi notes are converted, and since you can see (with a disp/dial or similar) what range midi notes cover (-64 to 63) you can figure out the scaling and the math from there. at least this is how i did it.

as for releasing there are two ways i guess, the "better" approach would be to become a contributor and upload your stuff: https://sebiik.github.io/community.axoloti.com.backup/t/contributor-access/1039

it may take some time until you get the access, so the second way would be to just embed your objects into patches and share the patch in a forum post. if you use includes though, that won't work...