Cabbage Logo
Back to Cabbage Site

Need help to get started modifying exiting opcodes: "wgclar", "wgbrass",

I am interested in modifying the built-in opcodes for woodwinds, brass, bowed and plucked strings, e.g. “wgclar”, “wgbrass”, etc.

(by “modify” I mean create custom versions that “save as…” new file names)

What I’m looking for:

  1. The Csound source files for the “wg…” opcodes
  2. Any tutorials that walk through that code and explain what is going on, why certain choices were made.
  3. Any examples of other people who have modified these opcodes, preferably with complete .csd files

What I have done so far:

I have found a few examples of modifications/alternatives for “wgclar”, but the explanations were almost absent beyond a few comments in the code. No examples for any of the other “wg…” opcodes.

I tried a n00b approach and copy/pasted one of those example instruments into “FirstSynth.csd”. This didn’t work. It generated this error: " Invalid ftable no. 3.000000", and I have no idea how to fix it. I can share this .csd file if anyone wants to debug it, but maybe this is the wrong approach and I am better off starting with a clean/empty file.

Yes, I have read The CSound Book sections on physical modeling.

Yes, I know these opcodes were based on Cook’s 1995 C++ code, but I don’t really want to go through the process of translating them into CSound code from scratch.

I played with the “Parp.csd” example file and it is very interesting. But it only modifies the parameters that go into “wgbrass” without modifying the “wgbrass” opcode itself.

I assume there are in here?

You need to define an appropriate function table.

I’m not really sure what you want to achieve here. If you want to ‘hack’ these opcodes, you will need to set up an entire Csound build system, or write them from scratch as plugin opcodes in C/C++. If you wish to explore these opcodes at a lower level, but don’t want to develop new opcodes, you will need to translate them into Csound code. Built-in Csound opcodes are black box units that you can only modified by rebuild the entire system.

Thanks for your reply. It is very helpful to know that these “wg…” opcodes are written in C and not in Csound code.

I want to write new opcodes in CSound code, not C or C++. From the examples I have seen, I presume this is feasible.

Below is the instrument that I copy/pasted from this article: “TEACHING SOFTWARE SYNTHESIS THROUGH CSOUND’S NEW MODELLING OPCODES”. This fails, giving the “Invalid ftable no. 3.00000” error.

<Cabbage>
form size(500, 160), caption("Baroque Clarinet"), pluginid("BaroqueClarinet")
keyboard bounds(12, 6, 480, 100)
</Cabbage>
<CsoundSynthesizer>
<CsOptions>
-n -d -+rtmidi=NULL -M0 --midi-key-cps=4 --midi-velocity-amp=5
</CsOptions>
<CsInstruments>
;sr is set by the host
;ksmps = 64
;nchnls = 2
;0dbfs=1

;instr 1
;a1 oscili p5, p4, 1
;outs a1, a1
;endin

instr 1  ; Clarinet Instrument based on Cook's Clarinet
  areedbell init 	0
  ifqc 		= 		cpspch(p5)
  ifco 		= 		p7
  ibore 	= 		1/ifqc-15/sr
  kenvl 	linseg  0, 0.005, 0.55 + 0.3 * p6, p3-0.015, 0.55+0.3*p6, 0.01, 0
  kenvibr 	linseg 	0, 0.1, 0, 0.9, 1,p3-1, 1 ; Vibrato envelope
  kemboff 	= 		p8  					; Adjust reed stiffness.
  avibr 	oscil 	0.1*kenvibr, 5, 3 		; Breath pressure
  apressm	= 		kenvl + avibr			; Lowpass reflection filter at bell
  arefilt	tone	areedbell, ifco
  abellreed	delay	arefilt, ibore			; the delay from bell to reed
  
  		; Back pressure and reed table lookup
  asum2		=		-apressm - 0.95 * arefilt - kemboff
  areedtab	tablei	asum2/4 + 0.34, p9, 1, 0.5
  amult1	=		asum2*areedtab
  
  		; Forward pressure
  asum1		=		apressm + amult1
  areedbell	delay	asum1, ibore
  aofilt	atone	areedbell, ifco
  			out 	aofilt * p4
  
endin


</CsInstruments>  
<CsScore>
f0 z
</CsScore>

What I would like to do is get this instrument working in CSound code, and then create separate but similar CSound code for “wgbrass”. If that works, then maybe I will take some of the others.


Why would I want to do this rather than just use the built-in black box “wg…” opcodes? Because I want to alter the parameters and structure of the physical model to match real and imagined Baroque period instruments such as the cornett, sackbutt, baroque clarinet, baroque trumpet, baroque oboe, etc. By “imagined” I want to be able to create instruments that are realistic but didn’t exist – a brass mouthpiece on a clarinet body. I also want to add to the physical model to add more articulation and expressiveness, and to expose those parameters so they can be controlled and automated by MIDI.

This functionality was available on the Yamaha VL1 synthesizer and also the PC plugin card (which I owned).

Back to my original request:

Thanks.

None that I am aware of. Your best bet is to read up on the Perry Cook stuff and go from there.

Again, none that I am aware of.

There is more missing than a simple table. I’ve no idea what half the parameters do here. There are two tables required, one apparently controls the breath pressure, while the other is to do with back pressure and reed?

I’ve added two tables here, and it will run now, but it sounds nothing like a clarinet. I’ve a feeling that this instrument might be in the Boulanger’s Csound book? I get what you want to do. It sounds like a cool idea.

Anyway, here is a version that doesn’t spit out any errors. The two tables are defined in the score section.:

<Cabbage>
form size(500, 160), caption("Baroque Clarinet"), pluginId("BaroqueClarinet")
keyboard bounds(12, 6, 480, 100)
</Cabbage>
<CsoundSynthesizer>
<CsOptions>
-n -d -+rtmidi=NULL -M0 --midi-key-cps=4 --midi-velocity-amp=5
</CsOptions>
<CsInstruments>
;sr is set by the host
ksmps = 32
nchnls = 2
0dbfs=1

;instr 1
;a1 oscili p5, p4, 1
;outs a1, a1
;endin

instr 1
event_i "i", 10, 0, 3, .5, 60, 1, 1000, .1, 4 
endin

instr 10  ; Clarinet Instrument based on Cook's Clarinet
  areedbell init 	0
  ifqc 		= 		cpsmidinn(p5)
  ifco 		= 		p7
  ibore 	= 		1/ifqc-15/sr
  kenvl 	linseg  0, 0.005, 0.55 + 0.3 * p6, p3-0.015, 0.55+0.3*p6, 0.01, 0
  kenvibr 	linseg 	0, 0.1, 0, 0.9, 1,p3-1, 1 ; Vibrato envelope
  kemboff 	= 		p8  					; Adjust reed stiffness.
  avibr 	oscil 	0.1*kenvibr, 5, 3 		; Breath pressure
  apressm	= 		kenvl + avibr			; Lowpass reflection filter at bell
  arefilt	tone	areedbell, ifco
  abellreed	delay	arefilt, ibore			; the delay from bell to reed
  
  		; Back pressure and reed table lookup
  asum2		=		-apressm - 0.95 * arefilt - kemboff
  areedtab	tablei	asum2/4 + 0.34, p9, 1, 0.5
  amult1	=		asum2*areedtab
  
  		; Forward pressure
  asum1		=		apressm + amult1
  areedbell	delay	asum1, ibore
  aofilt	atone	areedbell, ifco
  			out 	aofilt * p4
  
endin


</CsInstruments>  
<CsScore>
f3 0 1024 10 1
f4 0 1024 10 1
f0 z
</CsScore>
</CsoundSynthesizer>

Curiosity got the better of me. Here’s an updated version that DOES sound like a clarinet. :slight_smile:
I continue to use a sine wave for the breath pressure, that seems Ok, but I changed to use a simple triangular shape for the reed pressure and added a few sliders to controls some parameters. I also added a few realtime envelopes and got rid of the event_i stuff in instrument 1. I think this should be a good starting point for you now.

Clarinet.csd (1.5 KB)

Thanks a million! Very very helpful. I consider this my “minimum viable starting point”.

You and me both!

FYI I simply copy/pasted the instrument code from page three of this article “TEACHING SOFTWARE SYNTHESIS THROUGH CSOUND’S NEW MODELLING OPCODES” and then I commented out stuff that seemed related to FirstSynth. I changed “instr 2” to “instr 1” and changed the score to “f0 z”.

Once I have this figured out, I may write a tutorial on it. Maybe more people would be interested in physical modeling if they had an accessible way into it.

BTW, one of the main reasons I want to create my own opcodes is because I suspect there are non-obvious interdependence between the parameters – changing any one may cause the instrument to malfunction (no sound, or overdriven distorted sound). A simple example is breath pressure and tube dimensions.

I hope to find hyperparameters that define a space of viable instruments, and some blackbox functions that map hyperparameters to the opcode parameters.

I also want to create wind instruments that can change their tuning during a performance, e.g. mean temperament in different keys, depending on the key and chords in each bar of music. To do this I want change the physical mode via opcode parameters. If I do the physical model right, it should be straight forward.

1 Like

For anyone interested in the topics of this thread, I found a great article and some code examples (which I haven’t run yet).

Csound Implementation of Physical Models of Woodwind Instruments

Unlike the built-in “wgclar”, this model includes physical model of the reed. It also includes the more complex challenge of a double reed instrument (which he says is only partially successful). Nice MP3 demo for it, however.

Brilliant. I hadn’t seen that article before. It would be great to see those articles updated and placed on the main Csound site, or become part of the Csound floss manual.