Csound Csound-dev Csound-tekno Search About

[Csnd] conditional, nearest quantising

Date2012-12-15 15:40
Frompeiman khosravi
Subject[Csnd] conditional, nearest quantising
Dear all,

I was wondering if there is a simple method for quantising an arbitrary input value to a 'grid' defined in a table. 

Thanks
Peiman   

Date2012-12-15 15:53
FromJustin Smith
SubjectRe: [Csnd] conditional, nearest quantising
I would write a line of code or maybe UDO that maps from input value to 0-1, then use that number to do a non-interpolated table lookup (where the table has the quantized results you want)

something like this (this is untested code) - this should get you a series of values in the set (1 2 3 4) with equal probability of each at any time

iquant ftgentmp 0, 0, 5, 2, 1, 2, 3, 4, 4 ; guard point?
kinput noise 0dbfs, 0
kinput limit kinput, 0, 1 ; just to be safe
klookup = (kinput + 0dbfs)/(2*0dbfs) ; number between 0 and 1
kquant table klookup, iquant, 1


On Sat, Dec 15, 2012 at 7:40 AM, peiman khosravi <peimankhosravi@gmail.com> wrote:
Dear all,

I was wondering if there is a simple method for quantising an arbitrary input value to a 'grid' defined in a table. 

Thanks
Peiman   


Date2012-12-15 15:54
FromJustin Smith
SubjectRe: [Csnd] conditional, nearest quantising
oops, it should have been:

iquant ftgentmp 0, 0, 5, 2, 1, 2, 3, 4, 4 ; guard point?
kinput noise 0dbfs, 0
klookup = (kinput + 0dbfs)/(2*0dbfs) ; number between 0 and 1
klookup limit klookup, 0, 1 ; just to be safe
kquant table klookup, iquant, 1

like I said, untested code


On Sat, Dec 15, 2012 at 7:53 AM, Justin Smith <noisesmith@gmail.com> wrote:
I would write a line of code or maybe UDO that maps from input value to 0-1, then use that number to do a non-interpolated table lookup (where the table has the quantized results you want)

something like this (this is untested code) - this should get you a series of values in the set (1 2 3 4) with equal probability of each at any time

iquant ftgentmp 0, 0, 5, 2, 1, 2, 3, 4, 4 ; guard point?
kinput noise 0dbfs, 0
kinput limit kinput, 0, 1 ; just to be safe
klookup = (kinput + 0dbfs)/(2*0dbfs) ; number between 0 and 1
kquant table klookup, iquant, 1


On Sat, Dec 15, 2012 at 7:40 AM, peiman khosravi <peimankhosravi@gmail.com> wrote:
Dear all,

I was wondering if there is a simple method for quantising an arbitrary input value to a 'grid' defined in a table. 

Thanks
Peiman   



Date2012-12-15 16:01
Frompeiman khosravi
SubjectRe: [Csnd] conditional, nearest quantising
Nice idea. Let me test it out and get back to you.

Thanks
Peiman

On 15 December 2012 15:54, Justin Smith <noisesmith@gmail.com> wrote:
oops, it should have been:

iquant ftgentmp 0, 0, 5, 2, 1, 2, 3, 4, 4 ; guard point?
kinput noise 0dbfs, 0
klookup = (kinput + 0dbfs)/(2*0dbfs) ; number between 0 and 1
klookup limit klookup, 0, 1 ; just to be safe
kquant table klookup, iquant, 1

like I said, untested code


On Sat, Dec 15, 2012 at 7:53 AM, Justin Smith <noisesmith@gmail.com> wrote:
I would write a line of code or maybe UDO that maps from input value to 0-1, then use that number to do a non-interpolated table lookup (where the table has the quantized results you want)

something like this (this is untested code) - this should get you a series of values in the set (1 2 3 4) with equal probability of each at any time

iquant ftgentmp 0, 0, 5, 2, 1, 2, 3, 4, 4 ; guard point?
kinput noise 0dbfs, 0
kinput limit kinput, 0, 1 ; just to be safe
klookup = (kinput + 0dbfs)/(2*0dbfs) ; number between 0 and 1
kquant table klookup, iquant, 1


On Sat, Dec 15, 2012 at 7:40 AM, peiman khosravi <peimankhosravi@gmail.com> wrote:
Dear all,

I was wondering if there is a simple method for quantising an arbitrary input value to a 'grid' defined in a table. 

Thanks
Peiman   




Date2012-12-15 16:04
Frompeiman khosravi
SubjectRe: [Csnd] conditional, nearest quantising
Hi Justin,

Could you please explain this bit? 

klookup = (kinput + 0dbfs)/(2*0dbfs) ; number between 0 and 1

Thanks
Peiman

On 15 December 2012 16:01, peiman khosravi <peimankhosravi@gmail.com> wrote:
Nice idea. Let me test it out and get back to you.

Thanks
Peiman


On 15 December 2012 15:54, Justin Smith <noisesmith@gmail.com> wrote:
oops, it should have been:

iquant ftgentmp 0, 0, 5, 2, 1, 2, 3, 4, 4 ; guard point?
kinput noise 0dbfs, 0
klookup = (kinput + 0dbfs)/(2*0dbfs) ; number between 0 and 1
klookup limit klookup, 0, 1 ; just to be safe
kquant table klookup, iquant, 1

like I said, untested code


On Sat, Dec 15, 2012 at 7:53 AM, Justin Smith <noisesmith@gmail.com> wrote:
I would write a line of code or maybe UDO that maps from input value to 0-1, then use that number to do a non-interpolated table lookup (where the table has the quantized results you want)

something like this (this is untested code) - this should get you a series of values in the set (1 2 3 4) with equal probability of each at any time

iquant ftgentmp 0, 0, 5, 2, 1, 2, 3, 4, 4 ; guard point?
kinput noise 0dbfs, 0
kinput limit kinput, 0, 1 ; just to be safe
klookup = (kinput + 0dbfs)/(2*0dbfs) ; number between 0 and 1
kquant table klookup, iquant, 1


On Sat, Dec 15, 2012 at 7:40 AM, peiman khosravi <peimankhosravi@gmail.com> wrote:
Dear all,

I was wondering if there is a simple method for quantising an arbitrary input value to a 'grid' defined in a table. 

Thanks
Peiman   





Date2012-12-15 16:10
FromJustin Smith
SubjectRe: [Csnd] conditional, nearest quantising
if 0dbfs was for example 8, kinput would be a number between -8 and 8

if kinput is between -8 and 8, a value of 0 should map to .5 on a 0 to 1 scale

(0 + 8)/(2*8) = 8/16 = 0.5

so regardless of 0dbfs, that line of code will come up with a mapping of the input (between -0dbfs and 0dbfs) to a number between 0 and 1

of course you can adapt this to your own needs depending on how the number is generated



On Sat, Dec 15, 2012 at 8:04 AM, peiman khosravi <peimankhosravi@gmail.com> wrote:
Hi Justin,

Could you please explain this bit? 

klookup = (kinput + 0dbfs)/(2*0dbfs) ; number between 0 and 1

Thanks
Peiman

On 15 December 2012 16:01, peiman khosravi <peimankhosravi@gmail.com> wrote:
Nice idea. Let me test it out and get back to you.

Thanks
Peiman


On 15 December 2012 15:54, Justin Smith <noisesmith@gmail.com> wrote:
oops, it should have been:

iquant ftgentmp 0, 0, 5, 2, 1, 2, 3, 4, 4 ; guard point?
kinput noise 0dbfs, 0
klookup = (kinput + 0dbfs)/(2*0dbfs) ; number between 0 and 1
klookup limit klookup, 0, 1 ; just to be safe
kquant table klookup, iquant, 1

like I said, untested code


On Sat, Dec 15, 2012 at 7:53 AM, Justin Smith <noisesmith@gmail.com> wrote:
I would write a line of code or maybe UDO that maps from input value to 0-1, then use that number to do a non-interpolated table lookup (where the table has the quantized results you want)

something like this (this is untested code) - this should get you a series of values in the set (1 2 3 4) with equal probability of each at any time

iquant ftgentmp 0, 0, 5, 2, 1, 2, 3, 4, 4 ; guard point?
kinput noise 0dbfs, 0
kinput limit kinput, 0, 1 ; just to be safe
klookup = (kinput + 0dbfs)/(2*0dbfs) ; number between 0 and 1
kquant table klookup, iquant, 1


On Sat, Dec 15, 2012 at 7:40 AM, peiman khosravi <peimankhosravi@gmail.com> wrote:
Dear all,

I was wondering if there is a simple method for quantising an arbitrary input value to a 'grid' defined in a table. 

Thanks
Peiman   






Date2012-12-15 16:13
Frompeiman khosravi
SubjectRe: [Csnd] conditional, nearest quantising
Thanks Justin,

This is great. I need to convert input frequency values to 8th tone scale degrees and then do some more mapping from there. I think it should be easy enough if I start from your example.

Thanks again,
Peiman 

On 15 December 2012 16:10, Justin Smith <noisesmith@gmail.com> wrote:
between


Date2012-12-15 16:38
FromJustin Smith
SubjectRe: [Csnd] conditional, nearest quantising
There are opcodes designed for this sort of thing (octcps for example), which would be easier than table lookup (though of course table lookup is more general). It may work best to convert via octcps and then use that as the table lookup index.

speaking of more general, here is a demo of an opcode that does the range mapping with arbitrary ranges

usage looks like this (you can type in instrument invocations at the command line to test it, I recommend the rlwrap program for this, to allow scrolling and editing history):

i 1 0 1 0 -8 8 0 1
 ...
map 0.000000 from (-8.000000 : 8.000000) to (0.000000 : 1.000000) = 0.500000

it even works when the ranges get reversed
i 1 0 1 0.25 0 1 0 -1
...
map 0.250000 from (0.000000 : 1.000000) to (0.000000 : -1.000000) = -0.250000


<CsoundSynthesizer>
<CsOptions>
-Lstdin
-n
</CsOptions>
<CsInstruments>

opcode mapto, k, kkkkk
kin, ki_min, ki_max, ko_min, ko_max xin
ko_offset = ko_min
ki_offset = ki_min
ko_range = ko_max - ko_min
ki_range = ki_max - ki_min
kscale = ko_range / ki_range
kres = (kin - ki_offset)*kscale+ko_offset
xout kres
endop

        instr 1
kout mapto p4, p5, p6, p7, p8
printf "map %f from (%f : %f) to (%f : %f) = %f\n", 1, p4, p5, p6, p7, p8, kout
        endin


</CsInstruments>
<CsScore>

i 1 100000 0 0 0 0 0 0

</CsScore>
</CsoundSynthesizer>



On Sat, Dec 15, 2012 at 8:13 AM, peiman khosravi <peimankhosravi@gmail.com> wrote:
Thanks Justin,

This is great. I need to convert input frequency values to 8th tone scale degrees and then do some more mapping from there. I think it should be easy enough if I start from your example.

Thanks again,
Peiman 

On 15 December 2012 16:10, Justin Smith <noisesmith@gmail.com> wrote:
between



Date2012-12-15 17:00
FromJustin Smith
SubjectRe: [Csnd] conditional, nearest quantising
since this is an interesting question to me, I just put together this opcode that quantizes to n pitches to the octave:

<CsoundSynthesizer>
<CsOptions>
-Lstdin
-n
</CsOptions>
<CsInstruments>

;; qnth - arguments are value to quantize, and number of tones per octave
;; (ie. for a standard piano scale, 12, for quarter tones, 24, etc.)
opcode qnth, k, kk
kcps, kquant xin
koct = octcps(kcps)
kquantized = round(koct*kquant)/kquant
;printk2 kquantized
xout cpsoct(kquantized)
endop


        instr 1
kout qnth p4, p5
printk2 kout
        endin


</CsInstruments>
<CsScore>

i 1 100000 0 0

</CsScore>
</CsoundSynthesizer>



On Sat, Dec 15, 2012 at 8:38 AM, Justin Smith <noisesmith@gmail.com> wrote:
There are opcodes designed for this sort of thing (octcps for example), which would be easier than table lookup (though of course table lookup is more general). It may work best to convert via octcps and then use that as the table lookup index.

speaking of more general, here is a demo of an opcode that does the range mapping with arbitrary ranges

usage looks like this (you can type in instrument invocations at the command line to test it, I recommend the rlwrap program for this, to allow scrolling and editing history):

i 1 0 1 0 -8 8 0 1
 ...
map 0.000000 from (-8.000000 : 8.000000) to (0.000000 : 1.000000) = 0.500000

it even works when the ranges get reversed
i 1 0 1 0.25 0 1 0 -1
...
map 0.250000 from (0.000000 : 1.000000) to (0.000000 : -1.000000) = -0.250000


<CsoundSynthesizer>
<CsOptions>
-Lstdin
-n
</CsOptions>
<CsInstruments>

opcode mapto, k, kkkkk
kin, ki_min, ki_max, ko_min, ko_max xin
ko_offset = ko_min
ki_offset = ki_min
ko_range = ko_max - ko_min
ki_range = ki_max - ki_min
kscale = ko_range / ki_range
kres = (kin - ki_offset)*kscale+ko_offset
xout kres
endop

        instr 1
kout mapto p4, p5, p6, p7, p8
printf "map %f from (%f : %f) to (%f : %f) = %f\n", 1, p4, p5, p6, p7, p8, kout
        endin


</CsInstruments>
<CsScore>

i 1 100000 0 0 0 0 0 0

</CsScore>
</CsoundSynthesizer>



On Sat, Dec 15, 2012 at 8:13 AM, peiman khosravi <peimankhosravi@gmail.com> wrote:
Thanks Justin,

This is great. I need to convert input frequency values to 8th tone scale degrees and then do some more mapping from there. I think it should be easy enough if I start from your example.

Thanks again,
Peiman 

On 15 December 2012 16:10, Justin Smith <noisesmith@gmail.com> wrote:
between




Date2012-12-15 18:34
FromLouis Cohen
SubjectRe: [Csnd] conditional, nearest quantising
I wrote and use this UDO often. This assumes that the table starts with an entry count, then contains  entries, all sorted. The table can be pretty big because the UDO uses a binary search to find the closest match.

I hope it's useful. 

-Lou


opcode		findentry, k, kk	;finds nearest table entry to the input value, using binary search
ktestvalue, ktable	xin	;get input value, table number
;does not test for illegal table number, but if table number == -1, returns the input value
kreturn	= ktestvalue
if(ktable=-1)then
	kgoto		returnvalue
endif
kentrycount	tablekt 0, ktable
;assumes table is sorted order, table values are in entries 1 through kentrycount
klorangestart		=	1
klorangeend		=	int(kentrycount/2)
khirangestart		=	klorangeend + 1
khirangeend		=	kentrycount
whichrange:
	;is ktestvalue in bottom half of range?
	klowest		tablekt	klorangestart, ktable	;lowest value in range
	khighest		tablekt	klorangeend, ktable
	ktopofbottom	=	khighest
	if(klowest<=ktestvalue && ktestvalue<=khighest)then
		;ktestvalue is somewhere in this range.
		;divide the lower range into two parts
		klorangestart	=	klorangestart
		khirangeend	=	klorangeend
		klorangeend	=	klorangestart + int((klorangeend-klorangestart)/2)
		khirangestart	=	klorangeend + 1
		;we are done if the new range is very small
		if( (khirangeend - klorangestart) < 2) then
			kreturn	tablekt klorangestart, ktable
;			printk 1,767676
			kgoto returnvalue
		endif
		kgoto		whichrange
	endif
	;if not in low range, it must be in the hirange, so adjust the new high range
	klowest		tablekt	khirangestart, ktable
	khighest		tablekt	khirangeend, ktable
	kbottomoftop	=	klowest
	if(klowest<=ktestvalue && ktestvalue<=khighest)then
		;adjust ranges for high half of the current search area
		;divide the higher range into two parts
		khirangeend	=	khirangeend
		klorangestart	=	khirangestart
		khirangestart	=	klorangestart + int( (khirangeend-klorangestart)/2 )
		klorangeend	=	khirangestart - 1
		;we are done if the new range is very small
		if( (khirangeend - klorangestart) < 2) then
			kreturn	tablekt	khirangestart, ktable
;			printk 1,77777
			kgoto		returnvalue
		endif
		kgoto		whichrange
	endif
	if( (ktopofbottom wrote:

> Dear all,
> 
> I was wondering if there is a simple method for quantising an arbitrary input value to a 'grid' defined in a table. 
> 
> Thanks
> Peiman   

Lou Cohen
www.jolc.net
www.opensound.org






Date2012-12-16 00:49
Frompeiman khosravi
SubjectRe: [Csnd] conditional, nearest quantising
This is all great info for me. 

Thanks very much!

Peiman

On 15 December 2012 18:34, Louis Cohen <loucohen@jolc.net> wrote:
I wrote and use this UDO often. This assumes that the table starts with an entry count, then contains <entry count> entries, all sorted. The table can be pretty big because the UDO uses a binary search to find the closest match.

I hope it's useful.

-Lou


opcode          findentry, k, kk        ;finds nearest table entry to the input value, using binary search
ktestvalue, ktable      xin     ;get input value, table number
;does not test for illegal table number, but if table number == -1, returns the input value
kreturn = ktestvalue
if(ktable=-1)then
        kgoto           returnvalue
endif
kentrycount     tablekt 0, ktable
;assumes table is sorted order, table values are in entries 1 through kentrycount
klorangestart           =       1
klorangeend             =       int(kentrycount/2)
khirangestart           =       klorangeend + 1
khirangeend             =       kentrycount
whichrange:
        ;is ktestvalue in bottom half of range?
        klowest         tablekt klorangestart, ktable   ;lowest value in range
        khighest                tablekt klorangeend, ktable
        ktopofbottom    =       khighest
        if(klowest<=ktestvalue && ktestvalue<=khighest)then
                ;ktestvalue is somewhere in this range.
                ;divide the lower range into two parts
                klorangestart   =       klorangestart
                khirangeend     =       klorangeend
                klorangeend     =       klorangestart + int((klorangeend-klorangestart)/2)
                khirangestart   =       klorangeend + 1
                ;we are done if the new range is very small
                if( (khirangeend - klorangestart) < 2) then
                        kreturn tablekt klorangestart, ktable
;                       printk 1,767676
                        kgoto returnvalue
                endif
                kgoto           whichrange
        endif
        ;if not in low range, it must be in the hirange, so adjust the new high range
        klowest         tablekt khirangestart, ktable
        khighest                tablekt khirangeend, ktable
        kbottomoftop    =       klowest
        if(klowest<=ktestvalue && ktestvalue<=khighest)then
                ;adjust ranges for high half of the current search area
                ;divide the higher range into two parts
                khirangeend     =       khirangeend
                klorangestart   =       khirangestart
                khirangestart   =       klorangestart + int( (khirangeend-klorangestart)/2 )
                klorangeend     =       khirangestart - 1
                ;we are done if the new range is very small
                if( (khirangeend - klorangestart) < 2) then
                        kreturn tablekt khirangestart, ktable
;                       printk 1,77777
                        kgoto           returnvalue
                endif
                kgoto           whichrange
        endif
        if( (ktopofbottom<kbottomoftop) && (ktopofbottom<ktestvalue) && (ktestvalue<kbottomoftop))then
                kreturn =       ktopofbottom
                kgoto           returnvalue
        endif
returnvalue:
        xout    kreturn
endop
On Dec 15, 2012, at 10:40 AM, peiman khosravi <peimankhosravi@gmail.com> wrote:

> Dear all,
>
> I was wondering if there is a simple method for quantising an arbitrary input value to a 'grid' defined in a table.
>
> Thanks
> Peiman

Lou Cohen
www.jolc.net
www.opensound.org






Send bugs reports to the Sourceforge bug tracker
            https://sourceforge.net/tracker/?group_id=81968&atid=564599
Discussions of bugs and features can be posted here
To unsubscribe, send email sympa@lists.bath.ac.uk with body "unsubscribe csound"



Date2012-12-16 00:58
Frompeiman khosravi
SubjectRe: [Csnd] conditional, nearest quantising
But can octcps be limited to the 8th tone? 

P
 

On 15 December 2012 16:38, Justin Smith <noisesmith@gmail.com> wrote:
octcps


Date2012-12-16 01:37
FromJustin Smith
SubjectRe: [Csnd] conditional, nearest quantising
as I mention in the comments, second arg to the qnth opcode I showed is number of pitches per octave, so an argument of 48 will quantize to 8th tones


On Sat, Dec 15, 2012 at 4:58 PM, peiman khosravi <peimankhosravi@gmail.com> wrote:
But can octcps be limited to the 8th tone? 

P
 

On 15 December 2012 16:38, Justin Smith <noisesmith@gmail.com> wrote:
octcps



Date2012-12-16 01:48
Frompeiman khosravi
SubjectRe: [Csnd] conditional, nearest quantising
I yes yes sorry I'd missed that one. This is a neat UDO, thanks!

Best,
Peiman

On 16 December 2012 01:37, Justin Smith <noisesmith@gmail.com> wrote:
as I mention in the comments, second arg to the qnth opcode I showed is number of pitches per octave, so an argument of 48 will quantize to 8th tones


On Sat, Dec 15, 2012 at 4:58 PM, peiman khosravi <peimankhosravi@gmail.com> wrote:
But can octcps be limited to the 8th tone? 

P
 

On 15 December 2012 16:38, Justin Smith <noisesmith@gmail.com> wrote:
octcps