Csound Csound-dev Csound-tekno Search About

[Csnd] Creating an instrument like a "class"

Date2008-02-05 15:40
From"Arda Eden"
Subject[Csnd] Creating an instrument like a "class"
AttachmentsNone  None  

Date2008-02-05 16:01
From"Rory Walsh"
Subject[Csnd] Re: Creating an instrument like a "class"
I did something like this a while back using one instrument that does
nothing but instantiates other instruments. I was building a sampler and I
didn't want any limitations on the number of samples I could capture, or
the number of sampling instruments that could be run at one time. I was
able to communicate and interact with each of my instrument
instances(classes if you like) through the named software bus. I would
keep a track of each instance by assigning it a unique ID so that changing
my on-screen controller would affect the correct instance only. All in all
it turned out to be quite a hack, I had to stop it in the end but the
basic prototype worked Ok and I learned a lot along the way. I can show
you the code if you like.

Rory.


> Hi there,
> As you'll remember i was working on a tangible interface (reactable) to
> control csound.
> The work at school was so hard and i had to give it a break. Now i'm
> workin'
> on it again.
>
> I wonder if it's possible to define an instrument like a class, so i'll be
> able to call it by using something like "new" statement in most
> programming
> languages.
>
> What I'm trying to do is exactly that, when I put an object on the control
> surface, I want it to create an instrument from a skeleton in real time.
> Conventional definition of instruments like "instr 1", "instr 2" and etc.
> causes some kind of limitation. I want it to be more flexible.
> Thank you.
>
> --
> Arda EDEN
> Cumhuriyet University
> Faculty of Fine Arts
> Department of Music Technology
>
> Send bugs reports to this list.
> To unsubscribe, send email sympa@lists.bath.ac.uk with body "unsubscribe
> csound"



Date2008-02-05 16:05
From"Arda Eden"
Subject[Csnd] Re: Re: Creating an instrument like a "class"
AttachmentsNone  None  

Date2008-02-05 16:06
FromJohn Lato
Subject[Csnd] Re: Creating an instrument like a "class"
Hello,

Every time a note is triggered, either through the score or some real-time trigger, 
csound will automatically allocate a new (or re-use an existing) instance of the 
instrument specified.  In that  way, score notes are csound's equivalent of "new".
e.g. in the score:
i1 0 5  ;csound allocates a new instance of instr. 1
i1 2 10 ;csound allocates another instance of instr. 1
i2 3 9  ;csound allocates a new instance of instr. 2

It seems that just triggering score events in real-time would do what you want, or am 
I missing something?

John W. Lato
School of Music
The University of Texas at Austin
1 University Station E3100
Austin, TX 78712-0435
(512) 232-2090

Arda Eden wrote:
> Hi there,
> As you'll remember i was working on a tangible interface (reactable) to 
> control csound.
> The work at school was so hard and i had to give it a break. Now i'm 
> workin' on it again.
> 
> I wonder if it's possible to define an instrument like a class, so i'll 
> be able to call it by using something like "new" statement in most 
> programming languages.
> 
> What I'm trying to do is exactly that, when I put an object on the 
> control surface, I want it to create an instrument from a skeleton in 
> real time. Conventional definition of instruments like "instr 1", "instr 
> 2" and etc. causes some kind of limitation. I want it to be more flexible.
> Thank you.
> 
> -- 
> Arda EDEN
> Cumhuriyet University
> Faculty of Fine Arts
> Department of Music Technology

Date2008-02-05 16:12
From"Arda Eden"
Subject[Csnd] Re: Re: Creating an instrument like a "class"
AttachmentsNone  None  

Date2008-02-05 17:10
From"Rory Walsh"
Subject[Csnd] Re: Re: Re: Creating an instrument like a "class"
It might not make much sense without seeing the host application code but
here it is anyway. It makes use of David's bit crunching UDO. Combined
with my host is allows me to dynamically create as many sample
record/playback instruments as I like and I can control each instance
individually. Each sample is written and played back from disk so RAM
shouldn't be a problem.

Rory.




-odevaudio -b10 -idevaudio


sr = 44100
kr = 4410
ksmps = 10
nchnls = 1

zakinit 1, 1000

#define FREQ #100#
#define BITDEPTH #200#
#define FADETIME #300#
#define ACTIVE8 #300#
#define DEF_SR #44100#
#define DEF_BD #16#
#define DEF_FR #1#
#define DEF_INIT #0#
#define DEF_AMP #1#
;//============= named channels ================
gkStartStop chnexport "StartStop", 1
gkLoopID chnexport "LoopInstance", 1
gkFreq chnexport "Freqeuncy", 1
gkBitDepth chnexport "BitDepth", 1
gkFadeTime chnexport "FadeIO", 1
gkActive chnexport "Active", 1

;//========== bit crunching UDO =============
opcode    decimator, a, akk
    setksmps    1
ain, kbit, ksrate        xin
kbits    = 2^kbit            ; Bit depth (1 to 16)
kfold    = (sr/ksrate)            ; Sample rate
kin      downsamp  ain            ; Convert to kr
kin      = (kin + 32768)        ; Add DC to avoid (-)
kin      = kin*(kbits / 65536)        ; Divide signal level
kin      = int(kin)            ; Quantise
aout     upsamp  kin            ; Convert to sr
aout     = aout * (65536/kbits) - 32768    ; Scale and remove DC
a0ut     fold  aout, kfold        ; Resample
    xout      a0ut
        endop

;//------------    controller    ------------
instr 1
ain in
kActive8_Audio init 0
kRecord_Sample init 1
kOldFileID init 0
kTIME_EVENT init 0
kSTARTCLOCK init 1
kButtontrig1 changed gkStartStop
if(kButtontrig1==1) then
       if(kRecord_Sample==1) then
       turnoff2 3+(gkLoopID/100), 4, 0
       event "i", 2+(gkLoopID/100), 0, -1, gkLoopID
       elseif(kRecord_Sample==0) then
            turnoff2 2+(gkLoopID/100), 4, 0
            ;//init all paramters..
            zkw 1, $FREQ+gkLoopID
            zkw 1, $ACTIVE8+gkLoopID
            zkw 0.5, $FADETIME+gkLoopID
            zkw 16, $BITDEPTH+gkLoopID
            event "i", 3+(gkLoopID/100), 0, -1, gkLoopID, $DEF_INIT
       endif
               if(kRecord_Sample==0) then
               kRecord_Sample=1
               elseif(kRecord_Sample==1) then
               kRecord_Sample=0
               endif
endif

kFreqtrig changed gkFreq
if((kFreqtrig==1)&&(kButtontrig1==0)) then
zkw gkFreq, $FREQ+gkLoopID
endif

kBitDepTrig changed gkBitDepth
if((kBitDepTrig==1)&&(kButtontrig1==0)) then
zkw gkBitDepth, $BITDEPTH+gkLoopID
endif

kActiveTrig changed gkActive
if((kActiveTrig==1)&&(kButtontrig1==0)) then
   if(kActive8_Audio==0) then
   event "i", 4+(gkLoopID/100), 0, -1, gkLoopID, gkFadeTime, 0
   elseif(kActive8_Audio==1) then
   event "i", 4+(gkLoopID/100), 0, -1, gkLoopID, gkFadeTime, 1
   endif
               if(kActive8_Audio==0) then
               kActive8_Audio=1
               elseif(kActive8_Audio==1) then
               kActive8_Audio=0
               endif
endif

out ain
endin
;//--------------- fade i/o ---------------
instr 4
if(p6==1) then
kline linseg 1, p5, 0
zkw kline, $ACTIVE8+p4
elseif(p6==0) then
kline linseg 0, p5, 1
zkw kline, $ACTIVE8+p4
endif
endin

;//----------------- playback sample -------------
instr 3
kamp zkr $ACTIVE8+p4
kfreq zkr $FREQ+p4
kbitdepth zkr $BITDEPTH+p4
SFileName   sprintfk "sound%d", p4
asnd diskin SFileName, kfreq, 0, 1, 4, p5
adecy decimator asnd, kbitdepth, 44100
out adecy*kamp
ficlose SFileName
endin


;//----------------  record sample  --------------
instr 2
ain in
SFileName   sprintfk "sound%d", p4
fout SFileName, 1, ain
ficlose SFileName
endin



f1 0 1024 10 1
i1 0 3600



> Dear Rory,
> I'd be pleased to see the code.
> You can mail it to : ardaeden@gmail.com
> or post it here to share with everybody.
> Thanks.



Date2008-02-05 17:12
FromJacob Joaquin
Subject[Csnd] Re: Creating an instrument like a "class"
I've experimented quite heavily with this.  Though working this manner is
currently a bit convoluted, imho.  With a few additions to Csound, I think
it be quite possible to create a somewhat user friendly way of doing it. 
Here's a csd:

http://www.thumbuki.com/csound/files/thumbuki20070702.csd


Here's a quick example on how instances are generated dynamically in the
score using this system:


/* Create new instances */
i $MonoSynth_new 0 1 "lead"
i $RingMod_new 0 1 "ring"
i $Mixer_new 0 1 "mixer"

/* Connect lead into ring into mixer */
i $Attach 0 1 "ring.SaAudioIn:lead.aAudioOut"
i $Attach 0 1 "mixer.SaAudioIn:ring.aAudioOut"

/* Turn on lead, ring and mixer */
i $MonoSynth 0 $duration "lead"
i $Mixer 0 $duration "mixer"
i $RingMod   0 $duration "ring"



The biggest issue using this system, besides being way overly complex, is
finding bugs.  If I misspell the name of an instance, Csound won't spit out
a warning.  Thus, it can be very frustrating when something doesn't work, as
I have to manually scan every single character in the score.

The upside is that this method is extremely powerful and versatile.  For
example, one can design sounds in the score much like doing it on a patch
chord modular synth.

Best, 
Jake 
---- 
The Csound Blog 
http://www.thumbuki.com/csound/blog/




Arda Eden wrote:
> 
> I wonder if it's possible to define an instrument like a class, so i'll be
> able to call it by using something like "new" statement in most
> programming
> languages.
> 
> What I'm trying to do is exactly that, when I put an object on the control
> surface, I want it to create an instrument from a skeleton in real time.
> Conventional definition of instruments like "instr 1", "instr 2" and etc.
> causes some kind of limitation. I want it to be more flexible.
> Thank you.
> 

-- 
View this message in context: http://www.nabble.com/Creating-an-instrument-like-a-%22class%22-tp15292772p15293703.html
Sent from the Csound - General mailing list archive at Nabble.com.


Date2008-02-05 19:35
FromJohn Lato
Subject[Csnd] Re: Re: Creating an instrument like a "class"
Jake,

Thanks for the link to your modular instrument article.  I did some experimenting 
with this style of working in csound 4.  At that time the chn interface wasn't 
available, just the zak system, and I quickly became frustrated with the limitations 
you describe in your writeup.  It looks like the capabilities have come a long way 
since then.

There is (at least) one problematic element to this approach.  During each k-cycle, 
csound runs instruments in order by instrument number.  That means that, when reading 
from a buffer (or global var), an instrument will access the most recent audio from 
instruments with a lower number, but a delay of ksmps samples will be introduced for 
instruments of a higher number.  That makes it difficult to string together multiple 
units.  Since your Attach instrument has a lower i-number than all the sound-handling 
instruments, I would think that Attach itself would introduce a delay of ksmps into 
the signal.  It looks like you've organized all the instrument numbers so there are 
no other problems in the csd you linked to, but if you wanted to, e.g. apply RingMod 
to Reverb (RingMod is 14, Reverb 15), it would be delayed.

Do you have a solution to this issue?  I've found it particularly cumbersome to work 
around.
Thanks,
John

John W. Lato
School of Music
The University of Texas at Austin
1 University Station E3100
Austin, TX 78712-0435
(512) 232-2090

Jacob Joaquin wrote:
> I've experimented quite heavily with this.  Though working this manner is
> currently a bit convoluted, imho.  With a few additions to Csound, I think
> it be quite possible to create a somewhat user friendly way of doing it. 
> Here's a csd:
> 
> http://www.thumbuki.com/csound/files/thumbuki20070702.csd
> 
> 
> Here's a quick example on how instances are generated dynamically in the
> score using this system:
> 
> 
> /* Create new instances */
> i $MonoSynth_new 0 1 "lead"
> i $RingMod_new 0 1 "ring"
> i $Mixer_new 0 1 "mixer"
> 
> /* Connect lead into ring into mixer */
> i $Attach 0 1 "ring.SaAudioIn:lead.aAudioOut"
> i $Attach 0 1 "mixer.SaAudioIn:ring.aAudioOut"
> 
> /* Turn on lead, ring and mixer */
> i $MonoSynth 0 $duration "lead"
> i $Mixer 0 $duration "mixer"
> i $RingMod   0 $duration "ring"
> 
> 
> 
> The biggest issue using this system, besides being way overly complex, is
> finding bugs.  If I misspell the name of an instance, Csound won't spit out
> a warning.  Thus, it can be very frustrating when something doesn't work, as
> I have to manually scan every single character in the score.
> 
> The upside is that this method is extremely powerful and versatile.  For
> example, one can design sounds in the score much like doing it on a patch
> chord modular synth.
> 
> Best, 
> Jake 
> ---- 
> The Csound Blog 
> http://www.thumbuki.com/csound/blog/
> 
> 
> 
> 
> Arda Eden wrote:
>> I wonder if it's possible to define an instrument like a class, so i'll be
>> able to call it by using something like "new" statement in most
>> programming
>> languages.
>>
>> What I'm trying to do is exactly that, when I put an object on the control
>> surface, I want it to create an instrument from a skeleton in real time.
>> Conventional definition of instruments like "instr 1", "instr 2" and etc.
>> causes some kind of limitation. I want it to be more flexible.
>> Thank you.
>>
> 

Date2008-02-05 20:13
FromJacob Joaquin
Subject[Csnd] Re: Re: Creating an instrument like a "class"
John,

It's been awhile since I've used this code, so I'm a little rusty.  I'll
have to take a look at $Attach to see if it creates a ksmp delay.  The
instruments that precede it only create blocks of chn memory, and do no
audio work.  $Attach itself only alters a chn string within the memory
blocks, and does no audio work either.  My guess is that there is no delay. 
But I've been wrong before, so I'm not ruling out that possibility.  :)

I have a working theory that I've not tried, so I could be really off with
this.  I think what would need to happen is to assign multiple numbers to
the same instrument(s).  For example:



#define $ringmod_new # 3 #
#define $reverb_new #4#
#define $Attach #5#

#define $ringmod_a # 14 #
#define $reverb_a # 15 #
#define $ringmod_b # 16 #
#define $reverb_b # 17 #

instr $ringmod_a, $ringmod_b
    ...
endin

instr $reverb_a, $reverb_b
    ...
endin

...

i $ringmod_new 0 1 "ring" 
i $reverb_new 0 1 "reverb" 

i $Attach 0 1 "reverb.SaAudioIn:ring.aAudioOut"

i $reverb_a 0 $duration "reverb" 
i $ringmod_b  0 $duration "ring"



My assumption is that since the audio streams exist in chn busses, they do
not have an order in which they get processed.  Instead, the order of
processing falls squarely on the order of instruments.  If I'm wrong on
this, then I'm certainly wrong on the rest.

As for the score example, since the chn memory blocks are created separately
from the instruments that process them, it is conceivable to create more
than one instrument that can read and write to the same chn block of memory. 
In the example, I've created two identical instruments of both the ringmod
and the reverb, with their i-numbers interwoven.  So if I wanted to plug a
reverb into a ringmod, I would use reverb_a and ringmod_b.  The chn audio
streams, I think, will be processed in this order.

Like I said, I may be completely wrong about this.  Plus, I don't think I'm
being all that clear at the moment.

Best,
Jake





John Lato wrote:
> 
> It looks like you've organized all the instrument numbers so there are 
> no other problems in the csd you linked to, but if you wanted to, e.g.
> apply RingMod 
> to Reverb (RingMod is 14, Reverb 15), it would be delayed.
> 

-- 
View this message in context: http://www.nabble.com/Creating-an-instrument-like-a-%22class%22-tp15292772p15298481.html
Sent from the Csound - General mailing list archive at Nabble.com.


Date2008-02-05 20:41
FromJohn Lato
Subject[Csnd] Re: Re: Re: Creating an instrument like a "class"
Jake,

It looks like I misread your code, and I think you're right that $Attach doesn't 
create a delay.  Of course, it needs to come before audio processing instruments 
(which your sample does), or the channel assignment will be ksmps delayed.

Assuming I understand your system properly now, assigning multiple instrument numbers 
to each instrument should work.  Now that you've reminded me of it, I think I used 
the same approach when I originally had this problem.  However, it's a particularly 
unsatisfying solution to me, because you need another number for each position in the 
processing chain for every instrument.  It also clutters up the number space.  Even 
so, it looks like the best option for the moment.
Thanks,
John

John W. Lato
School of Music
The University of Texas at Austin
1 University Station E3100
Austin, TX 78712-0435
(512) 232-2090

Jacob Joaquin wrote:
> John,
> 
> It's been awhile since I've used this code, so I'm a little rusty.  I'll
> have to take a look at $Attach to see if it creates a ksmp delay.  The
> instruments that precede it only create blocks of chn memory, and do no
> audio work.  $Attach itself only alters a chn string within the memory
> blocks, and does no audio work either.  My guess is that there is no delay. 
> But I've been wrong before, so I'm not ruling out that possibility.  :)
> 
> I have a working theory that I've not tried, so I could be really off with
> this.  I think what would need to happen is to assign multiple numbers to
> the same instrument(s).  For example:
> 
> 
> 
> #define $ringmod_new # 3 #
> #define $reverb_new #4#
> #define $Attach #5#
> 
> #define $ringmod_a # 14 #
> #define $reverb_a # 15 #
> #define $ringmod_b # 16 #
> #define $reverb_b # 17 #
> 
> instr $ringmod_a, $ringmod_b
>     ...
> endin
> 
> instr $reverb_a, $reverb_b
>     ...
> endin
> 
> ...
> 
> i $ringmod_new 0 1 "ring" 
> i $reverb_new 0 1 "reverb" 
> 
> i $Attach 0 1 "reverb.SaAudioIn:ring.aAudioOut"
> 
> i $reverb_a 0 $duration "reverb" 
> i $ringmod_b  0 $duration "ring"
> 
> 
> 
> My assumption is that since the audio streams exist in chn busses, they do
> not have an order in which they get processed.  Instead, the order of
> processing falls squarely on the order of instruments.  If I'm wrong on
> this, then I'm certainly wrong on the rest.
> 
> As for the score example, since the chn memory blocks are created separately
> from the instruments that process them, it is conceivable to create more
> than one instrument that can read and write to the same chn block of memory. 
> In the example, I've created two identical instruments of both the ringmod
> and the reverb, with their i-numbers interwoven.  So if I wanted to plug a
> reverb into a ringmod, I would use reverb_a and ringmod_b.  The chn audio
> streams, I think, will be processed in this order.
> 
> Like I said, I may be completely wrong about this.  Plus, I don't think I'm
> being all that clear at the moment.
> 
> Best,
> Jake
> 
> 
> 
> 
> 
> John Lato wrote:
>> It looks like you've organized all the instrument numbers so there are 
>> no other problems in the csd you linked to, but if you wanted to, e.g.
>> apply RingMod 
>> to Reverb (RingMod is 14, Reverb 15), it would be delayed.
>>
> 

Date2008-02-14 08:39
FromTim Mortimer
Subject[Csnd] Re: Creating an instrument like a "class"
This recent discussion about "an instrument class" was one i saw, & the
wheels were already grinding deep inside the cesspit of my head on the
subject, too deeply & primordially in fact to even consider making a comment
at the time.

All i want to say is that at present my take on it is rather than using a
lot of macro's & opcodes etc etc, i'm looking at possibly simply having all
the necessary elements of csound code reduced to Python string variables, &
then hopefully the Csound orchestra can simply "write itself" on demand from
the input score. (with the string variables having things like %d replaced
with table numbers or expseg trajectories allocated as required..). 

Hopefully this means longer term i can have the Class structure inherant in
Python to organise my instruments & sonic modular elements (which are
essentially just "slabs of csound code"), & I simply assemble the required
.orc & .sco on demand, possibly even to the point of deleting the csound
code again once the necessary audio &/or MIDI has been generated.

Am I being trivial at this point? Has anybody else "gone to town" already
with this kind of approach? it certainly overcomes any issues to do with
requiring "variable length p fields" or the like, & many of my SDIF &/or
Phase Vocoder type instruments tend to sooner or later be about the same
types of things, they just require differing numbers of source data files,
or ftables for masking etc etc... Hopefully this is a way therefore to make
what is generic more, err, "generic", & takes the Class notion off to a
Class based language that can handle it comfortably in the first place -
laeving csound simply to execute the toppling of the dominoes once the
scripting language has lined them up to be toppled...

My "solution" to this therefore may be trivial &/or bleeding obvious - but
to someone who might be bashing their head againt a Csound wall on this one
(a sensation I am certainly familiar with) my idea of simply taking the
"Class" notion off to somewhere suitably equipped to handle it in the first
place may be worthy of consideration. For anyone not across Python at all,
simply "generating text files" (essentially what i'd be doing in this
scenario) is something you could get your head around very quickly IMHO...

Anyway, as a wrap up, this seems like as gooder time as any to wheel out
what is essentially a kind of "newsletter" on the state of play of my
Parseval Python / Csound project i have drafted over the last few days, & i
encourage anyone who is vaguely interested to take a look. 

www.phasetransitions.net/parseval

There was discussion back before christmas as to turning it into an Open
Source project. All I can say is that i'm still having too many ideas of my
own to let go of it at the mo, but hopefully at some point soon it will be
stable enough to release the code in some form that people can see what kind
of goodies (& baddies) are in it, & how much might be of use to others
(particularly Blue users, as I'm still keen to potentially offer this as an
"out the box" python object (sic) for use in that environment if that were
to be possible...)





-----
*******************
www.phasetransitions.net
hermetic music * python * csound * possibly mindless ranting
various werk in perpetual delusions of progress....

-- 
View this message in context: http://www.nabble.com/Creating-an-instrument-like-a-%22class%22-tp15292772p15475859.html
Sent from the Csound - General mailing list archive at Nabble.com.


Date2008-02-14 08:52
FromTim Mortimer
Subject[Csnd] Re: Creating an instrument like a "class"
Apologies - as if my indirect self aggrandisement & self promotion weren't
already enough of an insult to everyones sensibilities! ; )

The "link" below will actually work if you type .html at the end of it
(certainly that's what I found when i just copied & pasted it into Mozilla
Firefox anyway - I'm no web developer, as my page will suitably attest!)


Tim Mortimer wrote:
> 
> 
> www.phasetransitions.net/parseval
> 
> 


-----
*******************
www.phasetransitions.net
hermetic music * python * csound * possibly mindless ranting
various werk in perpetual delusions of progress....

-- 
View this message in context: http://www.nabble.com/Creating-an-instrument-like-a-%22class%22-tp15292772p15476271.html
Sent from the Csound - General mailing list archive at Nabble.com.