Cabbage Logo
Back to Cabbage Site

Using static score events

I added a few score events to my .csd, and I see by the csound output that they fire,
but p4 and p5 are always zero. In fact, csound complains:

WARNING: instr 1 uses 5 p-fields but is given 3

Is there something I should know about including note events in a cabbage instrument,
or is this not supported? Eventually I was hoping to create a VST instrument that plays
a static score along with the transport of the host. Is this possible?

Thanks!

Can you post the full. csd file? Starting instruments from the score is possible and is how each effect works. Many synths work this way too, but some are triggered using the midi interop flags.

Running a score when the host runs can be done, but will involve a little work. You need to send realtime events to trigger an instrument. You can do something like this:

instr 1
kIsPlaying chnget "IS_PLAYING"
kRandFreq randi 1000, 100
;print is host currently playing
if changed:k(kIsPlaying)==1 then
	if metro(1)==1 then
		event "i", 2, 0, 1, kRandFreq
	endif
endif

endin

instr 2
a1 expon 1, p3, 0.01
a2 oscili a1, p4
outs a2, a2
endin

Instrument 1, which should be active from the start, will trigger instrument 2 to play random frequencies once per second. As far as I know, score events cannot be strictly read from the score, but you can use tables, or even text files to hold events that you could then fire to various instruments. The following quick modification for example will play a c-major scale whenever the host is running:

<Cabbage>
form caption("Untitled") size(400, 300), colour(58, 110, 182), pluginID("def1")
checkbox bounds(32, 8, 80, 20), channel("isPlaying"), text("Test")
</Cabbage>
<CsoundSynthesizer>
<CsOptions>
-n -d -+rtmidi=NULL -M0 -m0d 
</CsOptions>
<CsInstruments>
; Initialize the global variables. 
sr = 44100
ksmps = 32
nchnls = 2
0dbfs = 1

giNotes ftgen 1, 0, 8, -2, 60, 62, 64, 65, 67, 69, 71, 72

instr 1
	kIsPlaying chnget "IS_PLAYING"
	kTest chnget "isPlaying"
	kRandFreq randi 1000, 100
	kNoteIndex init 0
	;print is host currently playing
	if kIsPlaying==1 || kTest==1 then
		if metro(4)==1 then
			kNote tab kNoteIndex, giNotes
			event "i", 2, 0, 1, cpsmidinn(kNote) 
			kNoteIndex = kNoteIndex > 6 ? 0 : kNoteIndex+1
		endif
	endif
endin

instr 2
	a1 expon 1, p3, 0.01
	a2 oscili a1, p4
	outs a2, a2
endin


</CsInstruments>
<CsScore>
;starts instrument 1 and runs it for a week
i1 0 [60*60*24*7] 
</CsScore>
</CsoundSynthesizer>

In this case the C-Major scale is stored in a function table. I often use a similar mechanism to create sequencers and clips. So you can sequence notes and all sorts of things from Csound instruments, but you need to do it through the event opcodes. Let me know if this makes sense!