Csound Csound-dev Csound-tekno Search About

[Csnd-dev] question about mtof and similar converters

Date2023-01-21 19:15
Fromjoachim heintz
Subject[Csnd-dev] question about mtof and similar converters
hi all -

i have another question related to my work on a new Getting Started.

it works when i use mtof without the rate specification.  i can write:

	iFreq = mtof(62)
	kMidi = linseg:k(62,0.5,58)
	kFreq = mtof(kMidi)

no need to write mtof:i(62) or mtof:k(kMidi).  (the same applies for 
ampdb and similar converters.)

is it correct to say that the mtof opcode "knows" the rate of its input 
argument?

i remember it was different when i used mtof some years ago, but perhaps 
the implementation has been changed?

thanks -
	joachim

Date2023-01-21 20:08
FromEduardo Moguillansky
SubjectRe: [Csnd-dev] question about mtof and similar converters
This is surprising, since mtof is one of the cases where the order of declaration is wrong...
Testing it actually results in an error here.

Unable to find opcode entry for '=' with matching argument types:
Found: i = k
       ifreq = mtof ...

As a general rule, the :i or :k indicates the type of the output. csound uses the input and output arguments to dispatch the correct opcode. For mtof, there are two versions for scalar arguments:

* i mtof i
* k mtof k

csound's matching algorithm is not very sofisticated. In this case it finds "mtof(62)" and looks through the declared versions of the opcode. Since "k mtof k" is found first, this results in a match being that the output is unknown and 62 can be interpreted as a k argument. 

The behaviour would be correct if the "i" version would be declared first. But I would argue that using the order of declaration to determine the matching behaviour is a rather fragile strategy. It would be probably wiser to make the dispatch algorithm cleverer.

In general, not the information you would like to put in a "getting started" ... 

cheers
Eduardo


On 21.01.23 20:15, joachim heintz  wrote:
> hi all -
> 
> i have another question related to my work on a new Getting Started.
> 
> it works when i use mtof without the rate specification.  i can write:
> 
>      iFreq = mtof(62)
>      kMidi = linseg:k(62,0.5,58)
>      kFreq = mtof(kMidi)
> 
> no need to write mtof:i(62) or mtof:k(kMidi).  (the same applies for 
> ampdb and similar converters.)
> 
> is it correct to say that the mtof opcode "knows" the rate of its input 
> argument?
> 
> i remember it was different when i used mtof some years ago, but perhaps 
> the implementation has been changed?
> 
> thanks -
>      joachim
> 

Date2023-01-22 04:25
Fromjoachim heintz
SubjectRe: [Csnd-dev] question about mtof and similar converters
that's true, but it is good to know for me.  thanks for explaining.

i am wondering why ampdb() figures out the right input.  do you know this?

and i am currently working on the development version, so on csound 
7.0.0 =) --- perhaps this is the reason that it works for me?

best -
	joachim



On 21/01/2023 21:08, Eduardo Moguillansky wrote:
> This is surprising, since mtof is one of the cases where the order of 
> declaration is wrong...
> Testing it actually results in an error here.
> 
> Unable to find opcode entry for '=' with matching argument types:
> Found: i = k
>        ifreq = mtof ...
> 
> As a general rule, the :i or :k indicates the type of the output. csound 
> uses the input and output arguments to dispatch the correct opcode. For 
> mtof, there are two versions for scalar arguments:
> 
> * i mtof i
> * k mtof k
> 
> csound's matching algorithm is not very sofisticated. In this case it 
> finds "mtof(62)" and looks through the declared versions of the opcode. 
> Since "k mtof k" is found first, this results in a match being that the 
> output is unknown and 62 can be interpreted as a k argument.
> The behaviour would be correct if the "i" version would be declared 
> first. But I would argue that using the order of declaration to 
> determine the matching behaviour is a rather fragile strategy. It would 
> be probably wiser to make the dispatch algorithm cleverer.
> 
> In general, not the information you would like to put in a "getting 
> started" ...
> cheers
> Eduardo
> 
> 
> On 21.01.23 20:15, joachim heintz  wrote:
>> hi all -
>>
>> i have another question related to my work on a new Getting Started.
>>
>> it works when i use mtof without the rate specification.  i can write:
>>
>>      iFreq = mtof(62)
>>      kMidi = linseg:k(62,0.5,58)
>>      kFreq = mtof(kMidi)
>>
>> no need to write mtof:i(62) or mtof:k(kMidi).  (the same applies for 
>> ampdb and similar converters.)
>>
>> is it correct to say that the mtof opcode "knows" the rate of its 
>> input argument?
>>
>> i remember it was different when i used mtof some years ago, but 
>> perhaps the implementation has been changed?
>>
>> thanks -
>>      joachim
>>

Date2023-01-22 08:59
FromEduardo Moguillansky
SubjectRe: [Csnd-dev] question about mtof and similar converters

Maybe something was changed in csound7 regarding dispatch?

Regarding ampdb, at least in csound6 the reason it works correctly without hints is that it is declared in the correct way, the i variant first. In this case:

Engine/entry1.c
291:  { "ampdb.a",S(EVAL),0,    2,      "a",    "a",    NULL,   aampdb  },
292:  { "ampdb.i",S(EVAL),0,    1,      "i",    "i",    ampdb                   },
293:  { "ampdb.k",S(EVAL),0,    2,      "k",    "k",    NULL,   ampdb           },
294:  { "ampdbfs.a",S(EVAL),0,  2,      "a",    "a",    NULL,   aampdbfs },
295:  { "ampdbfs.i",S(EVAL),0,  1,      "i",    "i",    ampdbfs                 },
296:  { "ampdbfs.k",S(EVAL),0,  2,      "k",    "k",    NULL,   ampdbfs         },
On 22.01.23 05:25, joachim heintz wrote:
that's true, but it is good to know for me.  thanks for explaining.

i am wondering why ampdb() figures out the right input.  do you know this?

and i am currently working on the development version, so on csound 7.0.0 =) --- perhaps this is the reason that it works for me?

best -
    joachim



On 21/01/2023 21:08, Eduardo Moguillansky wrote:
This is surprising, since mtof is one of the cases where the order of declaration is wrong...
Testing it actually results in an error here.

Unable to find opcode entry for '=' with matching argument types:
Found: i = k
       ifreq = mtof ...

As a general rule, the :i or :k indicates the type of the output. csound uses the input and output arguments to dispatch the correct opcode. For mtof, there are two versions for scalar arguments:

* i mtof i
* k mtof k

csound's matching algorithm is not very sofisticated. In this case it finds "mtof(62)" and looks through the declared versions of the opcode. Since "k mtof k" is found first, this results in a match being that the output is unknown and 62 can be interpreted as a k argument.
The behaviour would be correct if the "i" version would be declared first. But I would argue that using the order of declaration to determine the matching behaviour is a rather fragile strategy. It would be probably wiser to make the dispatch algorithm cleverer.

In general, not the information you would like to put in a "getting started" ...
cheers
Eduardo


On 21.01.23 20:15, joachim heintz <jh@JOACHIMHEINTZ.DE> wrote:
hi all -

i have another question related to my work on a new Getting Started.

it works when i use mtof without the rate specification.  i can write:

     iFreq = mtof(62)
     kMidi = linseg:k(62,0.5,58)
     kFreq = mtof(kMidi)

no need to write mtof:i(62) or mtof:k(kMidi).  (the same applies for ampdb and similar converters.)

is it correct to say that the mtof opcode "knows" the rate of its input argument?

i remember it was different when i used mtof some years ago, but perhaps the implementation has been changed?

thanks -
     joachim


Date2023-01-22 11:21
FromVictor Lazzarini
SubjectRe: [Csnd-dev] [EXTERNAL] Re: [Csnd-dev] question about mtof and similar converters
there is a completely new parser on Csound 7.

Prof. Victor Lazzarini
Maynooth University
Ireland

On 22 Jan 2023, at 09:01, Eduardo Moguillansky <eduardo.moguillansky@gmail.com> wrote:



*Warning*

This email originated from outside of Maynooth University's Mail System. Do not reply, click links or open attachments unless you recognise the sender and know the content is safe.

Maybe something was changed in csound7 regarding dispatch?

Regarding ampdb, at least in csound6 the reason it works correctly without hints is that it is declared in the correct way, the i variant first. In this case:

Engine/entry1.c
291:  { "ampdb.a",S(EVAL),0,    2,      "a",    "a",    NULL,   aampdb  },
292:  { "ampdb.i",S(EVAL),0,    1,      "i",    "i",    ampdb                   },
293:  { "ampdb.k",S(EVAL),0,    2,      "k",    "k",    NULL,   ampdb           },
294:  { "ampdbfs.a",S(EVAL),0,  2,      "a",    "a",    NULL,   aampdbfs },
295:  { "ampdbfs.i",S(EVAL),0,  1,      "i",    "i",    ampdbfs                 },
296:  { "ampdbfs.k",S(EVAL),0,  2,      "k",    "k",    NULL,   ampdbfs         },
On 22.01.23 05:25, joachim heintz wrote:
that's true, but it is good to know for me.  thanks for explaining.

i am wondering why ampdb() figures out the right input.  do you know this?

and i am currently working on the development version, so on csound 7.0.0 =) --- perhaps this is the reason that it works for me?

best -
    joachim



On 21/01/2023 21:08, Eduardo Moguillansky wrote:
This is surprising, since mtof is one of the cases where the order of declaration is wrong...
Testing it actually results in an error here.

Unable to find opcode entry for '=' with matching argument types:
Found: i = k
       ifreq = mtof ...

As a general rule, the :i or :k indicates the type of the output. csound uses the input and output arguments to dispatch the correct opcode. For mtof, there are two versions for scalar arguments:

* i mtof i
* k mtof k

csound's matching algorithm is not very sofisticated. In this case it finds "mtof(62)" and looks through the declared versions of the opcode. Since "k mtof k" is found first, this results in a match being that the output is unknown and 62 can be interpreted as a k argument.
The behaviour would be correct if the "i" version would be declared first. But I would argue that using the order of declaration to determine the matching behaviour is a rather fragile strategy. It would be probably wiser to make the dispatch algorithm cleverer.

In general, not the information you would like to put in a "getting started" ...
cheers
Eduardo


On 21.01.23 20:15, joachim heintz <jh@JOACHIMHEINTZ.DE> wrote:
hi all -

i have another question related to my work on a new Getting Started.

it works when i use mtof without the rate specification.  i can write:

     iFreq = mtof(62)
     kMidi = linseg:k(62,0.5,58)
     kFreq = mtof(kMidi)

no need to write mtof:i(62) or mtof:k(kMidi).  (the same applies for ampdb and similar converters.)

is it correct to say that the mtof opcode "knows" the rate of its input argument?

i remember it was different when i used mtof some years ago, but perhaps the implementation has been changed?

thanks -
     joachim


Date2023-01-22 21:22
Fromjoachim heintz
SubjectRe: [Csnd-dev] [EXTERNAL] Re: [Csnd-dev] question about mtof and similar converters
and this parser checks the type (rate) of the input argument?


On 22/01/2023 12:21, Victor Lazzarini wrote:
> there is a completely new parser on Csound 7.
> 
> Prof. Victor Lazzarini
> Maynooth University
> Ireland
> 
>> On 22 Jan 2023, at 09:01, Eduardo Moguillansky 
>>  wrote:
>>
>> 
>>
>>
>>   *Warning*
>>
>> This email originated from outside of Maynooth University's Mail 
>> System. Do not reply, click links or open attachments unless you 
>> recognise the sender and know the content is safe.
>>
>> Maybe something was changed in csound7 regarding dispatch?
>>
>> Regarding ampdb, at least in csound6 the reason it works correctly 
>> without hints is that it is declared in the correct way, the i variant 
>> first. In this case:
>>
>> Engine/entry1.c
>> 291:  { "ampdb.a",S(EVAL),0,    2,      "a",    "a",    NULL,   aampdb  },
>> 292:  { "ampdb.i",S(EVAL),0,    1,      "i",    "i",    ampdb                   },
>> 293:  { "ampdb.k",S(EVAL),0,    2,      "k",    "k",    NULL,   ampdb           },
>> 294:  { "ampdbfs.a",S(EVAL),0,  2,      "a",    "a",    NULL,   aampdbfs },
>> 295:  { "ampdbfs.i",S(EVAL),0,  1,      "i",    "i",    ampdbfs                 },
>> 296:  { "ampdbfs.k",S(EVAL),0,  2,      "k",    "k",    NULL,   ampdbfs         },
>> On 22.01.23 05:25, joachim heintz wrote:
>>> that's true, but it is good to know for me.  thanks for explaining.
>>>
>>> i am wondering why ampdb() figures out the right input.  do you know 
>>> this?
>>>
>>> and i am currently working on the development version, so on csound 
>>> 7.0.0 =) --- perhaps this is the reason that it works for me?
>>>
>>> best -
>>>     joachim
>>>
>>>
>>>
>>> On 21/01/2023 21:08, Eduardo Moguillansky wrote:
>>>> This is surprising, since mtof is one of the cases where the order 
>>>> of declaration is wrong...
>>>> Testing it actually results in an error here.
>>>>
>>>> Unable to find opcode entry for '=' with matching argument types:
>>>> Found: i = k
>>>>        ifreq = mtof ...
>>>>
>>>> As a general rule, the :i or :k indicates the type of the output. 
>>>> csound uses the input and output arguments to dispatch the correct 
>>>> opcode. For mtof, there are two versions for scalar arguments:
>>>>
>>>> * i mtof i
>>>> * k mtof k
>>>>
>>>> csound's matching algorithm is not very sofisticated. In this case 
>>>> it finds "mtof(62)" and looks through the declared versions of the 
>>>> opcode. Since "k mtof k" is found first, this results in a match 
>>>> being that the output is unknown and 62 can be interpreted as a k 
>>>> argument.
>>>> The behaviour would be correct if the "i" version would be declared 
>>>> first. But I would argue that using the order of declaration to 
>>>> determine the matching behaviour is a rather fragile strategy. It 
>>>> would be probably wiser to make the dispatch algorithm cleverer.
>>>>
>>>> In general, not the information you would like to put in a "getting 
>>>> started" ...
>>>> cheers
>>>> Eduardo
>>>>
>>>>
>>>> On 21.01.23 20:15, joachim heintz  wrote:
>>>>> hi all -
>>>>>
>>>>> i have another question related to my work on a new Getting Started.
>>>>>
>>>>> it works when i use mtof without the rate specification.  i can write:
>>>>>
>>>>>      iFreq = mtof(62)
>>>>>      kMidi = linseg:k(62,0.5,58)
>>>>>      kFreq = mtof(kMidi)
>>>>>
>>>>> no need to write mtof:i(62) or mtof:k(kMidi).  (the same applies 
>>>>> for ampdb and similar converters.)
>>>>>
>>>>> is it correct to say that the mtof opcode "knows" the rate of its 
>>>>> input argument?
>>>>>
>>>>> i remember it was different when i used mtof some years ago, but 
>>>>> perhaps the implementation has been changed?
>>>>>
>>>>> thanks -
>>>>>      joachim
>>>>>

Date2023-01-23 10:14
FromVictor Lazzarini
SubjectRe: [Csnd-dev] [EXTERNAL] Re: [Csnd-dev] question about mtof and similar converters
The old parser was already doing that. Checking outputs in functional-style syntax could have issues sometimes I guess,
but this for instance works on 6.18

 k1 = oscili(0.5,1)

and this

a1 = oscili(0.5, 1)

I am not sure to what extent this works. I think it breaks down when you do inlining (e.g. oscili(oscili(), oscilil())),
because there is no way to check what return type is required.

Steven can give more details if he implemented return type inference in parser3.

best
========================
Prof. Victor Lazzarini
Maynooth University
Ireland

> On 22 Jan 2023, at 21:22, joachim heintz  wrote:
> 
> and this parser checks the type (rate) of the input argument?
> 
> 
> On 22/01/2023 12:21, Victor Lazzarini wrote:
>> there is a completely new parser on Csound 7.
>> Prof. Victor Lazzarini
>> Maynooth University
>> Ireland
>>> On 22 Jan 2023, at 09:01, Eduardo Moguillansky  wrote:
>>> 
>>> 
>>> 
>>> 
>>>  *Warning*
>>> 
>>> This email originated from outside of Maynooth University's Mail System. Do not reply, click links or open attachments unless you recognise the sender and know the content is safe.
>>> 
>>> Maybe something was changed in csound7 regarding dispatch?
>>> 
>>> Regarding ampdb, at least in csound6 the reason it works correctly without hints is that it is declared in the correct way, the i variant first. In this case:
>>> 
>>> Engine/entry1.c
>>> 291:  { "ampdb.a",S(EVAL),0,    2,      "a",    "a",    NULL,   aampdb  },
>>> 292:  { "ampdb.i",S(EVAL),0,    1,      "i",    "i",    ampdb                   },
>>> 293:  { "ampdb.k",S(EVAL),0,    2,      "k",    "k",    NULL,   ampdb           },
>>> 294:  { "ampdbfs.a",S(EVAL),0,  2,      "a",    "a",    NULL,   aampdbfs },
>>> 295:  { "ampdbfs.i",S(EVAL),0,  1,      "i",    "i",    ampdbfs                 },
>>> 296:  { "ampdbfs.k",S(EVAL),0,  2,      "k",    "k",    NULL,   ampdbfs         },
>>> On 22.01.23 05:25, joachim heintz wrote:
>>>> that's true, but it is good to know for me.  thanks for explaining.
>>>> 
>>>> i am wondering why ampdb() figures out the right input.  do you know this?
>>>> 
>>>> and i am currently working on the development version, so on csound 7.0.0 =) --- perhaps this is the reason that it works for me?
>>>> 
>>>> best -
>>>>     joachim
>>>> 
>>>> 
>>>> 
>>>> On 21/01/2023 21:08, Eduardo Moguillansky wrote:
>>>>> This is surprising, since mtof is one of the cases where the order of declaration is wrong...
>>>>> Testing it actually results in an error here.
>>>>> 
>>>>> Unable to find opcode entry for '=' with matching argument types:
>>>>> Found: i = k
>>>>>        ifreq = mtof ...
>>>>> 
>>>>> As a general rule, the :i or :k indicates the type of the output. csound uses the input and output arguments to dispatch the correct opcode. For mtof, there are two versions for scalar arguments:
>>>>> 
>>>>> * i mtof i
>>>>> * k mtof k
>>>>> 
>>>>> csound's matching algorithm is not very sofisticated. In this case it finds "mtof(62)" and looks through the declared versions of the opcode. Since "k mtof k" is found first, this results in a match being that the output is unknown and 62 can be interpreted as a k argument.
>>>>> The behaviour would be correct if the "i" version would be declared first. But I would argue that using the order of declaration to determine the matching behaviour is a rather fragile strategy. It would be probably wiser to make the dispatch algorithm cleverer.
>>>>> 
>>>>> In general, not the information you would like to put in a "getting started" ...
>>>>> cheers
>>>>> Eduardo
>>>>> 
>>>>> 
>>>>> On 21.01.23 20:15, joachim heintz  wrote:
>>>>>> hi all -
>>>>>> 
>>>>>> i have another question related to my work on a new Getting Started.
>>>>>> 
>>>>>> it works when i use mtof without the rate specification.  i can write:
>>>>>> 
>>>>>>      iFreq = mtof(62)
>>>>>>      kMidi = linseg:k(62,0.5,58)
>>>>>>      kFreq = mtof(kMidi)
>>>>>> 
>>>>>> no need to write mtof:i(62) or mtof:k(kMidi).  (the same applies for ampdb and similar converters.)
>>>>>> 
>>>>>> is it correct to say that the mtof opcode "knows" the rate of its input argument?
>>>>>> 
>>>>>> i remember it was different when i used mtof some years ago, but perhaps the implementation has been changed?
>>>>>> 
>>>>>> thanks -
>>>>>>      joachim
>>>>>> 


Date2023-01-23 17:19
FromSteven Yi
SubjectRe: [Csnd-dev] [EXTERNAL] Re: [Csnd-dev] question about mtof and similar converters
Last I remember, any assignment gets rewritten so that the left hand
side becomes the output arguments to the root expression on the right
hand side. So the above should become:

k1 oscili 0.5,1
a1 oscili 0.5, 1

rather than:

#xsynthetic1 oscili 0.5,1 // if just this, it's ambiguous
k1 = #xsynthetic1

It's always tricky because casting from a to k and k to a was added,
so it can hide some unintentional rates (i.e., you might get a k-rate
when expecting an a-rate, and then those get downsampled, etc.).


On Mon, Jan 23, 2023 at 5:15 AM Victor Lazzarini  wrote:
>
> The old parser was already doing that. Checking outputs in functional-style syntax could have issues sometimes I guess,
> but this for instance works on 6.18
>
>  k1 = oscili(0.5,1)
>
> and this
>
> a1 = oscili(0.5, 1)
>
> I am not sure to what extent this works. I think it breaks down when you do inlining (e.g. oscili(oscili(), oscilil())),
> because there is no way to check what return type is required.
>
> Steven can give more details if he implemented return type inference in parser3.
>
> best
> ========================
> Prof. Victor Lazzarini
> Maynooth University
> Ireland
>
> > On 22 Jan 2023, at 21:22, joachim heintz  wrote:
> >
> > and this parser checks the type (rate) of the input argument?
> >
> >
> > On 22/01/2023 12:21, Victor Lazzarini wrote:
> >> there is a completely new parser on Csound 7.
> >> Prof. Victor Lazzarini
> >> Maynooth University
> >> Ireland
> >>> On 22 Jan 2023, at 09:01, Eduardo Moguillansky  wrote:
> >>>
> >>> 
> >>>
> >>>
> >>>  *Warning*
> >>>
> >>> This email originated from outside of Maynooth University's Mail System. Do not reply, click links or open attachments unless you recognise the sender and know the content is safe.
> >>>
> >>> Maybe something was changed in csound7 regarding dispatch?
> >>>
> >>> Regarding ampdb, at least in csound6 the reason it works correctly without hints is that it is declared in the correct way, the i variant first. In this case:
> >>>
> >>> Engine/entry1.c
> >>> 291:  { "ampdb.a",S(EVAL),0,    2,      "a",    "a",    NULL,   aampdb  },
> >>> 292:  { "ampdb.i",S(EVAL),0,    1,      "i",    "i",    ampdb                   },
> >>> 293:  { "ampdb.k",S(EVAL),0,    2,      "k",    "k",    NULL,   ampdb           },
> >>> 294:  { "ampdbfs.a",S(EVAL),0,  2,      "a",    "a",    NULL,   aampdbfs },
> >>> 295:  { "ampdbfs.i",S(EVAL),0,  1,      "i",    "i",    ampdbfs                 },
> >>> 296:  { "ampdbfs.k",S(EVAL),0,  2,      "k",    "k",    NULL,   ampdbfs         },
> >>> On 22.01.23 05:25, joachim heintz wrote:
> >>>> that's true, but it is good to know for me.  thanks for explaining.
> >>>>
> >>>> i am wondering why ampdb() figures out the right input.  do you know this?
> >>>>
> >>>> and i am currently working on the development version, so on csound 7.0.0 =) --- perhaps this is the reason that it works for me?
> >>>>
> >>>> best -
> >>>>     joachim
> >>>>
> >>>>
> >>>>
> >>>> On 21/01/2023 21:08, Eduardo Moguillansky wrote:
> >>>>> This is surprising, since mtof is one of the cases where the order of declaration is wrong...
> >>>>> Testing it actually results in an error here.
> >>>>>
> >>>>> Unable to find opcode entry for '=' with matching argument types:
> >>>>> Found: i = k
> >>>>>        ifreq = mtof ...
> >>>>>
> >>>>> As a general rule, the :i or :k indicates the type of the output. csound uses the input and output arguments to dispatch the correct opcode. For mtof, there are two versions for scalar arguments:
> >>>>>
> >>>>> * i mtof i
> >>>>> * k mtof k
> >>>>>
> >>>>> csound's matching algorithm is not very sofisticated. In this case it finds "mtof(62)" and looks through the declared versions of the opcode. Since "k mtof k" is found first, this results in a match being that the output is unknown and 62 can be interpreted as a k argument.
> >>>>> The behaviour would be correct if the "i" version would be declared first. But I would argue that using the order of declaration to determine the matching behaviour is a rather fragile strategy. It would be probably wiser to make the dispatch algorithm cleverer.
> >>>>>
> >>>>> In general, not the information you would like to put in a "getting started" ...
> >>>>> cheers
> >>>>> Eduardo
> >>>>>
> >>>>>
> >>>>> On 21.01.23 20:15, joachim heintz  wrote:
> >>>>>> hi all -
> >>>>>>
> >>>>>> i have another question related to my work on a new Getting Started.
> >>>>>>
> >>>>>> it works when i use mtof without the rate specification.  i can write:
> >>>>>>
> >>>>>>      iFreq = mtof(62)
> >>>>>>      kMidi = linseg:k(62,0.5,58)
> >>>>>>      kFreq = mtof(kMidi)
> >>>>>>
> >>>>>> no need to write mtof:i(62) or mtof:k(kMidi).  (the same applies for ampdb and similar converters.)
> >>>>>>
> >>>>>> is it correct to say that the mtof opcode "knows" the rate of its input argument?
> >>>>>>
> >>>>>> i remember it was different when i used mtof some years ago, but perhaps the implementation has been changed?
> >>>>>>
> >>>>>> thanks -
> >>>>>>      joachim
> >>>>>>
>