Divide 2 ints and get fractional output?


#1

I'd like to divide one int by another and get a fractional output.

Application - I'm playing through a table, continuously looping. I have an int (called ctr) that is counting up as we play through. When ctr=0, we are at the beginning of the table; when ctr=length we are at the end of the table.

In this case, length would be the size of table allocated (say 262,144) divided by 16 (audio-rate is 16x k-rate) = 16,384

Now say I want to generate a fractional value for our current position inside the table.
I would normally do
(ctr / 16,384) * 64.0
which should give me an input I could send to the 'pos' input on the table/record object, matching the table/play's position in the table as it plays back.

This would let me do overdubbing to the loop... we want to start the recorder at the same position as current playback.

How would you go about this?


#2

generally we avoid floating point maths for efficiency, and try to work it in binary.

so... 16385 = 2^14 and 64 = 2^6 so 14-6 = 8 so you just need to rotate right 8... math >> 8 (or 16384/256 = div 256)
the floats will keep there fractional data.

(sorry, this only answers the immediate question, not really got time time think about your use-case and if this is correct e.g. what you are doing with your table)

btw @johannes we really should have a ROT(<</>> ) left/right taking N as input, so you can arbitrarily shift , also we need to update tables such that they have a length output.
actually generally, we need to have attr exposed, so that a patch can be written and we you dont have to start altering other parts of a patch if you change them ... e.g. in above case if you chance the size of a table, you should be able to calculate the shift required. (the compiler should automatically optimise when it sees the constant values being used)


#3

I think the best way to handle this use case would be adding a "current position" output to table/play, that could be wired into table/record.

Yeah, sometimes it would be useful to expose attributes as inlets/outlets for initialization code. Or use expressions in attributes that reference other attributes. But this is not so easy...


#4

Yes, that would be ideal!

Not understanding... the counter is an int. There's no integer version of the shift operators. Even if there was... in this case, the dividend is always smaller than the divisor, so output would just be zero, right?
If I send an int input into the fractional version of rightshift, it's not covering the whole range (0-64.0) but just a small part of it. I assume this is because of the way it's converting the int to fractional. It seems like conv/to_f doesn't scale the input value to the -64 - +64 range of fractional values.

I thought about this - this case is a good example of where this would be nice. You'd like changing the table size to be easy & not require tweaking other parts of the patch.

Thx for the help. Hope I'm not being obtuse. What I have working is already pretty amazing!


#5

Im assuming you are going to convert to a float, as you said you wanted a fraction output, and pos requires a float. (table/play) (or 0...1 for table/read)

as Johannes said this would be easier to do if the table had a concept of a current position (or perhaps both a read and rite playhead)


#6

I'm missing something about type conversion. I have an int that is counting up from 0 to, say, 5,000. If I send that as input to conv/to_f, the output value doesn't smoothly count up over part of the range of a fractional number. Probably everything above 64 just converts to 64.0?
How do you convert larger ints to float, but keeping the values scaled within the 0.0 - 64.0 range?


#7

This is currently not supported without making custom objects or a "complex" network of objects.

Maybe - don't know enough context - use a lfo/saw or lfo/saw lin, rather than a counter?
If the 5000 steps serve to make an almost smooth ramp, it is better use lfo or envelope objects.


#8

ah, good point ... you can't, the floating is a fixed format it can actually go to -1023 to 1023 , anything else fed into it will wrap. so , this turns into a bit of a chicken and egg situation...

really we need an object thats a bit more flexible in converting ints to floats ... so I created a new object...

oneliner_ik.axo (738 Bytes)

now use the line:

outlet_out = inlet_in << 13

this actually just works with the raw format of integers and floats to bypass the problem,
we use 13 since we need to rotate >> 8 and then rotate << 21 to convert to a float.

seems to work as far as i test it.

@johannes until we have more flexible oneliners probably this one might be useful for these kind of integer conversions.


#9

I downloaded this object and copied it to objects/conv/oneliner_ik.axo
When I open the Axoloti app, it says "search path : objects"... then it prints the path to that object in red.
It's not loading the object but there's no error message or anything. What'd I do wrong?


#10

Try putting in objects/patch with other oneliners
I'd have though this would just be a warning about uuid at worst... post the error I'm intrigued, I'll later see if I can reproduce.


#11

Same thing - it just prints the name of the oneliner in red, and it's not available when I try to add a new object.


#12

ok , fixed , re-download (I've changed the file above)

very strange issue, was missing description tag... but this worked fine in the 'development area' but not when moved outside...no idea why it worked where it did...
anyway, Ive taken the opportunity to improve the logging, so that when the error occurs, it will print an exact description of what the issue ... so next release it will be clearer if we get similar errors :smile:

(btw, I was wrong, the oneliners are in the script folder)

also, i noticed if its in the wrong folder you will get a warning about the uuid, it will work anyway...
hopefully you shouldn't get this, if you put in objects/scripts


#13

Yes - from an initial quick test this appears to be working beautifully. I'll see if I can implement loop overdubbing & (if successful) I'll start a new thread with the looper patch.
Thank you for the help!


#14

It works. Thanks again for the assistance.
Here is the new thread with the patch:
stereo looper w/ overdub patch


#15

hi Johannes,
I'm working on these loopers...one looper will record a 'master-loop',
while others can be 'slaved'..
right now,I'm at the point that I can sync them via absolute position in samples
(---I'm a max/msp gen~ programmer...)
here's an example patch:
looper_OD_mono_SIG.axp (8.6 KB)

syncing them via relative position would be much more elegant,though...
because one could hook up a phasor,right..
so,how can I convert the playback position in samples to playback postion
relative to the buffer's (or the loop's) size?

cheers,robert