[CSOUND-DEV:4571] Bus design
Date | 2004-05-06 09:31 |
From | jpff@codemist.co.uk |
Subject | [CSOUND-DEV:4571] Bus design |
This message is a meander through thoughts on the software bus. Basic design: Finite number of a-input, a-output, k-input and k-output slots, all independent. Csound interface with four opcodes: buso a1, kn ;; write a1 to a-output #kn ar busi kn ;; read ar from a-input #kn buso k1, kn ;; write k1 to k-output #kn kr busi kn ;; read kr from k-input #kn API interface: Not so sure about this but something like csoundReadABus(void*, MYFLT* a, int n); csoundWriteABus(void*, MYFLT* a, int n); csoundReadKBus(void*, MYFLT* k, int n); csoundWriteKBus(void*, MYFLT* k, int n); /* or csoundWriteKBus(void*, MYFLT k,int n); ???*/ Implementation: Within the ENVIRON variable pointers to the four regions. Rest is obvious! Problems: How many bus items should we provide? Should it be a fixed number or grow as referenced? Alternatives: Just allow access to ZAK buses from the API. I rather prefer the above as it seems simpler and orthogonal to previous ideas Comments, improvements,... as appropriate. The above would be easy to implement over breakfast(!) ==John ffitch |
Date | 2004-05-06 16:51 |
From | "Josep MComajuncosas" |
Subject | [CSOUND-DEV:4573] RE: Bus design |
What is supposed to be a or k-output #kn? External audio output? Output to the host app? "Generic" output? Just curious Josep M Comajuncosas -----Mensaje original----- De: owner-csound-dev@eartha.mills.edu [mailto:owner-csound-dev@eartha.mills.edu] En nombre de jpff@codemist.co.uk Enviado el: jueves, 06 de mayo de 2004 10:31 Para: Csound Developers Discussion List Asunto: [CSOUND-DEV:4571] Bus design This message is a meander through thoughts on the software bus. Basic design: Finite number of a-input, a-output, k-input and k-output slots, all independent. Csound interface with four opcodes: buso a1, kn ;; write a1 to a-output #kn ar busi kn ;; read ar from a-input #kn buso k1, kn ;; write k1 to k-output #kn kr busi kn ;; read kr from k-input #kn API interface: Not so sure about this but something like csoundReadABus(void*, MYFLT* a, int n); csoundWriteABus(void*, MYFLT* a, int n); csoundReadKBus(void*, MYFLT* k, int n); csoundWriteKBus(void*, MYFLT* k, int n); /* or csoundWriteKBus(void*, MYFLT k,int n); ???*/ Implementation: Within the ENVIRON variable pointers to the four regions. Rest is obvious! Problems: How many bus items should we provide? Should it be a fixed number or grow as referenced? Alternatives: Just allow access to ZAK buses from the API. I rather prefer the above as it seems simpler and orthogonal to previous ideas Comments, improvements,... as appropriate. The above would be easy to implement over breakfast(!) ==John ffitch |
Date | 2004-05-06 20:28 |
From | "Matt J. Ingalls" |
Subject | [CSOUND-DEV:4575] Re: Bus design |
first of all i would be willing to VOLUNTEER to implement this. or i should say i have already implemented this via the invalue/outvalue stuff, would just need to move the 'matrix' code out of my host program and into csound. > buso a1, kn ;; write a1 to a-output #kn > ar busi kn ;; read ar from a-input #kn > buso k1, kn ;; write k1 to k-output #kn > kr busi kn ;; read kr from k-input #kn + what is wrong with using 'out' and 'in'? + i strongly suggest the bus channel optionally be a string name [as invalue/outvalue do now] + might also consider an i-rate opcode, ive noticed many instances where you want to set parameters before instantiating a note. i have fixed 'invalue' to return the val during the i-pass as well, but then to use it you have to do something like: kval invalue "gain" igain = i(kval) + wouldnt we also need opcodes to assign midi/fltk/etc to bus channels? > > API interface: > Not so sure about this but something like > csoundReadABus(void*, MYFLT* a, int n); > csoundWriteABus(void*, MYFLT* a, int n); > csoundReadKBus(void*, MYFLT* k, int n); > csoundWriteKBus(void*, MYFLT* k, int n); > /* or csoundWriteKBus(void*, MYFLT k,int n); ???*/ to keep with current api it would be: csoundReadKBus(void *csound, char *channelName, MYFLT *value); for a-rate i think a buffer-passing system like we already have in the api would be better. of course im thinking more about host apps and not opcodes [but do you really want opcode plugins reading/writing to the busses?] > Implementation: > Within the ENVIRON variable pointers to the four regions. Rest is > obvious! > > Problems: > How many bus items should we provide? Should it be a fixed number > or grow as referenced? i use a linked list. seems easy enough to start with nchnls and dynamically add any named or numbered channels when requested. however would need to prevent problems like: kchannel linseg 1, p3, 1000000 out asig, kchannel > Alternatives: > Just allow access to ZAK buses from the API. I rather prefer the i vote no -m |
Date | 2004-05-06 22:15 |
From | "Josep MComajuncosas" |
Subject | [CSOUND-DEV:4580] Re: Bus design |
Yep but please keep the ability to access buses by numbers. It will be necessary for some kind of arithmetics relating bus routing. Josep M Comajuncosas -----Mensaje original----- De: owner-csound-dev@eartha.mills.edu [mailto:owner-csound-dev@eartha.mills.edu] En nombre de Matt J. Ingalls Enviado el: jueves, 06 de mayo de 2004 21:29 Para: Csound Developers Discussion List Asunto: [CSOUND-DEV:4575] Re: Bus design first of all i would be willing to VOLUNTEER to implement this. or i should say i have already implemented this via the invalue/outvalue stuff, would just need to move the 'matrix' code out of my host program and into csound. > buso a1, kn ;; write a1 to a-output #kn > ar busi kn ;; read ar from a-input #kn > buso k1, kn ;; write k1 to k-output #kn > kr busi kn ;; read kr from k-input #kn + what is wrong with using 'out' and 'in'? + i strongly suggest the bus channel optionally be a string name [as invalue/outvalue do now] + might also consider an i-rate opcode, ive noticed many instances where you want to set parameters before instantiating a note. i have fixed 'invalue' to return the val during the i-pass as well, but then to use it you have to do something like: kval invalue "gain" igain = i(kval) + wouldnt we also need opcodes to assign midi/fltk/etc to bus channels? > > API interface: > Not so sure about this but something like > csoundReadABus(void*, MYFLT* a, int n); > csoundWriteABus(void*, MYFLT* a, int n); > csoundReadKBus(void*, MYFLT* k, int n); > csoundWriteKBus(void*, MYFLT* k, int n); > /* or csoundWriteKBus(void*, MYFLT k,int n); ???*/ to keep with current api it would be: csoundReadKBus(void *csound, char *channelName, MYFLT *value); for a-rate i think a buffer-passing system like we already have in the api would be better. of course im thinking more about host apps and not opcodes [but do you really want opcode plugins reading/writing to the busses?] > Implementation: > Within the ENVIRON variable pointers to the four regions. Rest is > obvious! > > Problems: > How many bus items should we provide? Should it be a fixed number > or grow as referenced? i use a linked list. seems easy enough to start with nchnls and dynamically add any named or numbered channels when requested. however would need to prevent problems like: kchannel linseg 1, p3, 1000000 out asig, kchannel > Alternatives: > Just allow access to ZAK buses from the API. I rather prefer the i vote no -m |
Date | 2004-05-06 22:50 |
From | Richard Dobson |
Subject | [CSOUND-DEV:4581] Re: Bus design |
I have never understood this business of having names. How does it relate to what the host sees? Is "gain" a purely local/private name created in the orch? If so, what does it actually correspond to on the host side? Whereas a statement such as: kgain busi 2 makes complete sense to me. Richard Dobson Matt J. Ingalls wrote: > first of all i would be willing to VOLUNTEER to implement this. > > or i should say i have already implemented this via the invalue/outvalue > stuff, would just need to move the 'matrix' code out of my host > program and into csound. > > > >> buso a1, kn ;; write a1 to a-output #kn >> ar busi kn ;; read ar from a-input #kn >> buso k1, kn ;; write k1 to k-output #kn >> kr busi kn ;; read kr from k-input #kn > > > + what is wrong with using 'out' and 'in'? > > + i strongly suggest the bus channel optionally be a string name > [as invalue/outvalue do now] .... |
Date | 2004-05-06 23:39 |
From | "Matt J. Ingalls" |
Subject | [CSOUND-DEV:4582] Re: Bus design |
> Whereas a statement such as: > kgain busi 2 > makes complete sense to me. and kgain busi "gain" doesnt make sense to you? maybe im crazy, but i would rather have a control channel named "gain" than "2"? just like i would rather use named functions instead of numbers: aout oscili 1, 440, "sawtooth" > I have never understood this business of having names. How does it relate to > what the host sees? Is "gain" a purely local/private name created in the orch? > If so, what does it actually correspond to on the host side? what i do in MacCsound, is you assign each graphic object a channel # or name - if its a display object it reads that channel, if it is a control object it writes that channel. multiple objects can be assigned the same channel. internally its basically a linked list of key/values as steven mentioned. this brings up another point, that the bus system needs to be global or there should be a way to specify global channels for hosts that are using multiple csound processes and/or multiple csound processes communicating with eachother. -m |
Date | 2004-05-07 00:15 |
From | "Matt J. Ingalls" |
Subject | [CSOUND-DEV:4583] Re: Bus design |
> this brings up another point, that the bus system needs to be global or > there should be a way to specify global channels for hosts that are using correction: there should AT LEAST be away to specify global channels, and now that i think about it, there definitely needs to be local channels as well, because of: > multiple csound processes and/or multiple csound processes communicating > with eachother. |
Date | 2004-05-07 00:30 |
From | Richard Dobson |
Subject | [CSOUND-DEV:4585] Re: Bus design |
Well, I am trying to understand it from an implementation point of view. A name string is semantically much weaker than a number. What exactly does "gain" or "sawtooth" refer to? Are they variables, or immutable? How does Csound know that one refers to an ftable and one refers to an automation signal? Does the Csound host have to scan the orch at init time, to identify all the instances of a name string (including those wrapped inside conditional code) and then the host has to publish them, identifying each one for what it signifies ("gain" = automation bus channel, "sawtooth" = ftable, "volume" = automation bus, or possibly an ftable, or...???). The ftable example is actually moot, as we are using a programmning language, and the score (or even the orch) may change the ftable dynamically - how meaningful is "sawtooth" then? Does it refer to a fixed/static ftable in the score, or can the score assign a new ftable to "sawtooth" dynamically? In which case, what guarantee is there that the name "sawtooth" is accurate? A name is semantically less obviously a variable than a number. I see your example as trying to replace a variable name such as isawtooth = p5 aout oscili 1, 440, isawtooth with some sort of name that directly refers to an object - presumanbly Csound has to look up "sawtooth" in the score to find out what on earth it refers to. And if you are obliged to use a linked list to store names, that means that random access (the great advantage of an array) is not directly possible. If I want to dynamically change the ftable, defined by name, how do I do it? If "sawtooth" is defined in the score, a clearer semantic might be itab = ftin "sawtooth" ; by analogy with soundin etc aout oscili 1, 440, itab So what ~exactly~ happens when Csound parses "sawtooth" and "gain" in instrument statements? Do they refer to something defined externally (host? score?), or is the orch statement the "declaration" which the host and/or score has to discover? Who owns the name? Who is allowed to change it dynamically? If it is not a variable, it seems less useful than a number, which usually is! Whereas if you just want to alias a name to a number, it seems to me we need an opcode to do it: namei ival, |
Date | 2004-05-07 00:35 |
From | Richard Dobson |
Subject | [CSOUND-DEV:4586] Re: Bus design |
It never occurred to me the automation bus would be anything other than global. It is created by Csound itself, and ~used~ by instruemnts and hosts. zak is global. Having multiple instances of Csound in a process is one thing, having them talk to each other is quite another! I can recall that trick ever having been discussed before! Inter-instance comms really would need to be mediated by a host (ports, busses, etc). It sounds at least as scary as plugin opcodes talking to each other behind the scenes. Richard Dobson Matt J. Ingalls wrote: >>this brings up another point, that the bus system needs to be global or >>there should be a way to specify global channels for hosts that are using > > > correction: there should AT LEAST be away to specify global channels, > and now that i think about it, there definitely needs to be local channels > as well, because of: > > >>multiple csound processes and/or multiple csound processes communicating >>with eachother. > > > > |
Date | 2004-05-07 01:23 |
From | "Matt J. Ingalls" |
Subject | [CSOUND-DEV:4588] Re: Bus design |
i meant 'global' in a more 'global' sense: existing outside the ENVIRON struct. i dont see anything really tricky or scary to it. im making an assumption about dynamic libs here, but as long as one instance is running there should be global access to any data. our current problem with getting multiple instances running simultaneously proves the point! -m On Fri, 7 May 2004, Richard Dobson wrote: > It never occurred to me the automation bus would be anything other than global. > It is created by Csound itself, and ~used~ by instruemnts and hosts. zak is global. > > Having multiple instances of Csound in a process is one thing, having them talk > to each other is quite another! I can recall that trick ever having been > discussed before! Inter-instance comms really would need to be mediated by a > host (ports, busses, etc). It sounds at least as scary as plugin opcodes talking > to each other behind the scenes. > > Richard Dobson > > > > Matt J. Ingalls wrote: > > >>this brings up another point, that the bus system needs to be global or > >>there should be a way to specify global channels for hosts that are using > > > > > > correction: there should AT LEAST be away to specify global channels, > > and now that i think about it, there definitely needs to be local channels > > as well, because of: > > > > > >>multiple csound processes and/or multiple csound processes communicating > >>with eachother. > > > > > > > > > > |
Date | 2004-05-07 02:07 |
From | "Matt J. Ingalls" |
Subject | [CSOUND-DEV:4593] Re: Bus design |
Richard, its not that complicated! im not proposing anything that radical.. from the user end it would be just like a soundin, you can specify the input parameter as a number or as a string. internally, i could see 3 ways of implementation: one would just be an array: struct channel { char *name; MYFLT val; } channel kbus[]; or you could use a table of names and a table of channels: struct channel_name { char *name; long channel; }; channel_name namedChannels[]; MYFLT kbus[]; or you could have two busses, one that is numbered and one that is named: struct channel { char *name; MYFLT val; } channel namedkbus[]; MYFLT numberedkbus[]; any way, the busin/busout opcodes would see if the input channel was specified as a string or a number and handle it accordingly. > "sawtooth" refer to? Are they variables, or immutable? How does Csound know that > one refers to an ftable and one refers to an automation signal? > Does the Csound host have to scan the orch at init time, to identify all again, just like soundin. its done inside the opcode. soundin knows its getting the name of soundfile, not a string to printf(), and likewise the busin opcode would know it is receiving the name of a channel, not the name of a function table! > Does the Csound host have to scan the orch at init time, to identify all > instances of a name string (including those wrapped inside conditional code) and > then the host has to publish them, identifying each one for what it signifies > ("gain" = automation bus channel, "sawtooth" = ftable, "volume" = automation > bus, or possibly an ftable, or...???). how i do it is i seach the list for channel matching the name and if none is found i return 0 [if i am fetching a value] or i create a new channel and add it to the list. > The ftable example is actually moot, as we are using a programmning language, > and the score (or even the orch) may change the ftable dynamically - how > meaningful is "sawtooth" then? Does it refer to a fixed/static ftable in the > score, or can the score assign a new ftable to "sawtooth" dynamically? In which > case, what guarantee is there that the name "sawtooth" is accurate? what guarantee is "101" is accurate? whats the difference between a name and a number? a function's number is its name! all im saying is allow named function tables just like we have named instruments now. its no big deal! > with some sort of name that directly refers to an object - presumanbly Csound > has to look up "sawtooth" in the score to find out what on earth it refers to. again, csound has to lookup a table number too..so i see little difference > And if you are obliged to use a linked list to store names, that means that > random access (the great advantage of an array) is not directly possible. If I > want to dynamically change the ftable, defined by name, how do I do it? ftgen "sawtooth", 0, 512, 7, -1, 512, 1 ; for an example only > namei 1, "gain" > ; can now use "gain" to mean automation bus channel 1 > namek 2, "sawtooth" > ; can now use "sawtooth" to refer to ftable 2; ftable 2 must exist of course... > namei ain1, "left" > namei ain2, "right" > ; can now write: > outs "left","right" im sorry, but that is lame. i want to be able to name a function and call it by name, i dont want to have to do this extra step in between, in fact [maybe this is what you are trying to prove] your example is less awkward just using '=': aleft = ain1 aright = ain2 outs aleft, aright > > There is also the disadvantage being that parsing names will take more time than > parsing integers. all the parsing would take place during an opcode's i-pass, i think the added computation would be negligible -m |
Date | 2004-05-07 02:46 |
From | iainduncan@telus.net |
Subject | [CSOUND-DEV:4595] Re: Bus design |
Something to consider as well is that names make it a whole heck of a lot easier to share code, something sorely needed by csound. No one is likely to need to renumber/rename their code on account of say "iainsawtooth". Iain > > Richard, > > its not that complicated! im not proposing anything that radical.. > > from the user end it would be just like a soundin, you can specify the > input parameter as a number or as a string. > > > internally, i could see 3 ways of implementation: > > one would just be an array: > > struct channel { > char *name; > MYFLT val; > } > > channel kbus[]; > > > or you could use a table of names and a table of channels: > > struct channel_name { > char *name; > long channel; > }; > > channel_name namedChannels[]; > MYFLT kbus[]; > > > or you could have two busses, one that is numbered and one that is named: > > struct channel { > char *name; > MYFLT val; > } > > channel namedkbus[]; > MYFLT numberedkbus[]; > > > any way, the busin/busout opcodes would see if the input channel was > specified as a string or a number and handle it accordingly. > > > > "sawtooth" refer to? Are they variables, or immutable? How does Csound know > that > > one refers to an ftable and one refers to an automation signal? > > Does the Csound host have to scan the orch at init time, to identify all > > again, just like soundin. its done inside the opcode. soundin knows > its getting the name of soundfile, not a string to printf(), and likewise > the busin opcode would know it is receiving the name of a channel, not the > name of a function table! > > > Does the Csound host have to scan the orch at init time, to identify all > > instances of a name string (including those wrapped inside conditional > code) and > > then the host has to publish them, identifying each one for what it > signifies > > ("gain" = automation bus channel, "sawtooth" = ftable, "volume" = > automation > > bus, or possibly an ftable, or...???). > > how i do it is i seach the list for channel matching the name and if none > is found i return 0 [if i am fetching a value] or i create a new channel > and add it to the list. > > > The ftable example is actually moot, as we are using a programmning > language, > > and the score (or even the orch) may change the ftable dynamically - how > > meaningful is "sawtooth" then? Does it refer to a fixed/static ftable in > the > > score, or can the score assign a new ftable to "sawtooth" dynamically? In > which > > case, what guarantee is there that the name "sawtooth" is accurate? > > what guarantee is "101" is accurate? whats the difference between a > name and a number? a function's number is its name! all im saying is > allow named function tables just like we have named instruments now. its no > big deal! > > > with some sort of name that directly refers to an object - presumanbly > Csound > > has to look up "sawtooth" in the score to find out what on earth it refers > to. > > again, csound has to lookup a table number too..so i see little difference > > > And if you are obliged to use a linked list to store names, that means > that > > random access (the great advantage of an array) is not directly possible. > If I > > want to dynamically change the ftable, defined by name, how do I do it? > > ftgen "sawtooth", 0, 512, 7, -1, 512, 1 ; for an example only > > > > namei 1, "gain" > > ; can now use "gain" to mean automation bus channel 1 > > namek 2, "sawtooth" > > ; can now use "sawtooth" to refer to ftable 2; ftable 2 must exist of > course... > > namei ain1, "left" > > namei ain2, "right" > > ; can now write: > > outs "left","right" > > > im sorry, but that is lame. i want to be able to name a function > and call it by name, i dont want to have to do this extra step in between, > in fact [maybe this is what you are trying to prove] your example is less > awkward just using '=': > > aleft = ain1 > aright = ain2 > outs aleft, aright > > > > > There is also the disadvantage being that parsing names will take more time > than > > parsing integers. > > all the parsing would take place during an opcode's i-pass, i think the > added computation would be negligible > > > -m > > |
Date | 2004-05-07 10:15 |
From | Richard Dobson |
Subject | [CSOUND-DEV:4605] Re: Bus design |
OK, you have answered my questions: Matt J. Ingalls wrote: > Richard, > > its not that complicated! im not proposing anything that radical.. > ... > > any way, the busin/busout opcodes would see if the input channel was > specified as a string or a number and handle it accordingly. > > That says that the host defines the names, so the orch has to know what the names are. My question then is, how? (Just checking: I am talking about an automation bus to/from the outside world, such as Cubase or Sonar or AudioMulch, ~not~ communication between instruments inside an orch.) > > ftgen "sawtooth", 0, 512, 7, -1, 512, 1 ; for an example only > Diito here, i can accept this as the score always associates to an ortch that knows about it. the questiona re then simply about whether a table defined by name can be redefined 10 seconds later, as you can do with numbered ftables. How would this work with the ftgen utility that Steven posted to the main list? >> namei 1, "gain" >>; can now use "gain" to mean automation bus channel 1 >> namek 2, "sawtooth" >>; can now use "sawtooth" to refer to ftable 2; ftable 2 must exist of course... >> namei ain1, "left" >> namei ain2, "right" >>; can now write: >> outs "left","right" > > > > im sorry, but that is lame. It was meant to be! :-) Richard Dobson |
Date | 2004-05-07 19:34 |
From | "Matt J. Ingalls" |
Subject | [CSOUND-DEV:4607] Re: Bus design |
> That says that the host defines the names, so the orch has to know what the > names are. My question then is, how? not necessarily. it can be an open thing where a new channel allocation can come from anywhere. but this brings up the 'global' issue again [see below] > (Just checking: I am talking about an automation bus to/from the outside world, > such as Cubase or Sonar or AudioMulch, ~not~ communication between instruments > inside an orch.) well if you think instrument<-->instrument is less of a priority, then i would suggest simply using what is ALREADY THERE in the API: having callbacks to the host to read/write control data and making the host keep track of the bus matrixing. This would be better because the host can be using the bus before and after a csound process is running. For instance, it would then be trivial to have a GUI set control parameters before running csound, or still read data that a csound process had bussed out long after that process had terminated. It also would be possible to have the host use the bussing system for its own internal communication. if you want to not put the burden on hosts, then you could implement this in 'global' space, which probably would mean adding and additional layer to the archictecture and api, which may be a good thing to do in general. [ ill type this up in a separate email ] AND HERE IS ANOTHER ISSUE WITH THE BUS would k-rate bus be directional or directionless? in other words, given this outbus 2, -999 kgain inbus 2 would kgain == -999, or is output channel 2 be totally independent of input channel 2? i would assume the former, but my experience with this soundflower utility is that most people assume a send/return system like auxes on an analog mixer. > Diito here, i can accept this as the score always associates to an ortch that > knows about it. the questiona re then simply about whether a table defined by > name can be redefined 10 seconds later, as you can do with numbered ftables. as long as it is the exact name, i see no reason why it shouldnt be identical to numbered function tables. > How would this work with the ftgen utility that Steven posted to the main list? same, i think.. -m |
Date | 2004-05-07 23:41 |
From | Richard Dobson |
Subject | [CSOUND-DEV:4611] Re: Bus design |
I think the best way for me to approach these issues is to describe my wish-list for an automation bus. Matt J. Ingalls wrote: .. > well if you think instrument<-->instrument is less of a priority, then i > would suggest simply using what is ALREADY THERE in the API: having I have no opinion on priority here! I think my automation bus model is just different from what you are describing, and from what seems to be implemented in the callback mechanism you refer to. .. > AND HERE IS ANOTHER ISSUE WITH THE BUS > would k-rate bus be directional or directionless? > in other words, given this > > outbus 2, -999 > kgain inbus 2 > > would kgain == -999, or is output channel 2 be totally independent of > input channel 2? i would assume the former, but my experience with this > soundflower utility is that most people assume a send/return system > like auxes on an analog mixer. > I don't have any problem with a bidirection bus; in the end it appears simply as a memory location that can be read and written. Of course, if multiple opcodes write to the same signal, the results may be "undefined". I assume the Csound host will write signals at the beginning of each k-cycle, but read them at the end. But it could be done the other way around - it would just have to be documented accordingly. Anyway, to my spec: The goal is communication with the outside world, so that a VST/Dx/AudioUnits host can record and send automation data to/from a Csound instance. There are therefore three entities - the Csound engine running an orch; the Csound host app that manages the engine; and the host that is running CsoundVST, say. Setting aside the names issue (with which I do have much sympathy, except where it may conflict with the needs for structure and algorithmic manipulation): The bus is an simple array of N channels, managed by the Csound host, and accessed by a csound instance, where it is visible as a guaranteed number of bus channels (indexable by number!). The host would be able to discern the number of ports actually used (e.g. by a Csound top=level opcode that declares them), so that it can avoid publishing unused ones to a plugin host. Maybe the orch can even parametrize a channel as either "local" (used internally by the Csound host - such as a GUI) or "extern" (Csound host exposes it to e.g the containing VST host). Added to this is the definition of the width and range of the signal. I want an orthogonal architecture, which means crucially that all signals must be bounded in the range [0.0,1.0], as VST parameters are required to be. This will enable any opcode to read any parameter from any channel, and be able to adapt it to what it needs. Similarly, where the host reads automation, the opcode must convert it to the normalised range. (Seen from outside, this orthogonal system will enable any automation track in a VST host to be applied to any parameter of any plugin in any track - including multiple instances of Csound. It is only the limitation of current track-based hosts that prevents this. It is ultimately no different from the "obvious" use of normalized ftables so that one table can be used by arbitrarily many opcodes.) "Width" address the need for multi-dimensional control signals. The key example here is surround-sound and similar positional information. Planar surround requires two values (azimuth/distance, or X/Y coordinates); full periphoinic requires 3 (again, two standard representations). Ideally, a single bus channel should be able to be defined in terms of width, so that a single "invalue" opcode can receive or transmit, say, three parameters. Alternatively, an array notation would do the job adequately. This is where numbers really come into their own, as we will want to be able to index over a contiguous group of automation signals. Names are important, but we will always need to be able to apply numerical indexing; even if it is just to ask for "position"[1].the alternative might have to be "position"["azimuth"]; which is a language idiom unlike anything I have seen. It will be strange, to put it mildly, if three parameters that are clearly required to be treated as a composite are arbitrarily dispersed over a bus because they are enumerated (somehow!) by name - name strings typically do not describe structural relationships between signals, in the way the numbers 1,2,3 do. The challenge therefore is to define an automation signal in a way that is both fully bounded, and as future-proof as we can make it: - a defined numeric range of the signal, independent of the huge and arbitrary range Csound instruments may use - relationships between signals - can be expressed algorithmically - signal width, by direct analogy with audio streams - scope - private to Orch/Csound host, or public - accessible by a VST or whatever host. - compatibility with existing plugin automation standards, especially VST. Richard Dobson |