Cabbage Logo
Back to Cabbage Site

Can't get grain3 opcode to work in csound7

Is it possible the grain3 opcode is broken in csound7? Or am I doing something wrong?

I had it working in Cabbage 2 but here when I run it, if I click a note on the keyboard widget (or play it from my midi keyboard), I see this in the cabbage output:

Cabbage INFO: 	   T  6.356 TT  6.356 M:
Cabbage INFO:   0.00000
Cabbage INFO:   0.00000
Cabbage INFO: 
Cabbage INFO: new MIDI alloc for instr 3:

And then nothing else, even if I hit other notes after, as if it crashed or froze.

I can get audio output from grain, grain2 and partikkel so I know my audio sample is being loaded properly.

Here’s my test CSD:

<Cabbage>
[
  {
    "type": "form",
    "size": {
      "width": 680,
      "height": 380
    }
  },
  {
    "type": "keyboard",
    "channel": "keyboard",
    "bounds": {
      "left": 5,
      "top": 305,
      "width": 670,
      "height": 75
    }
  }
]
</Cabbage>
<CsoundSynthesizer>

<CsOptions>
-n -+rtmidi=NULL -M0
</CsOptions>

<CsInstruments>

; sr set by host
ksmps = 64
nchnls = 2
0dbfs = 1

massign 0, 3 ; all midi notes on all channels sent to instrument 3

gihanningWindow ftgen 0, 0, 131072, 20, 2
giblackmanWindow ftgen 0, 0, 131072, 20, 4

opcode NextPowerOf2i, i, i
  iInVal xin
  icount = 1
  LOOP:
  if 2^icount > iInVal then
    goto DONE
  else
    icount = icount + 1
    goto LOOP
  endif
  DONE:
  xout 2 ^ icount
endop

instr 1
  if timeinstk() < 2 then
    event "i", 99, 0, 0
  endif
endin

instr 99
  SFileName = "testaudio.wav"
  SFilePath sprintf "%s/%s", chnget:S("CSD_PATH"), SFileName

  ; load soundfile into table for grain instrument
  ginumChannels filenchnls SFilePath
  ifTableLength  NextPowerOf2i filelen:i(SFilePath)*sr
  gitableLeft ftgen 1, 0, ifTableLength, 1, SFilePath, 0, 0, 1
  if ginumChannels == 2 then
    gitableRight ftgen 2, 0, ifTableLength, 1, SFilePath, 0, 0, 2
  endif
  if filevalid(SFilePath) == 0 then
    prints "Error: Soundfile %s not found or invalid!\n", SFilePath
  endif
endin

instr 3
  kSpeed = 1

  ; kcps is the number of times to play the sample per second
  ; usually meant for a single cycle table, ie 220 -> 220hz
  ; we want to play a longer sample so we have to do some math:
  kcps = (kSpeed * sr) / (ftlen(gitableLeft))

  kSampleOffset = 0.5 ; start at 50%
  ; because the table is always a power of 2 in length, we have to scale the start time down
  ; to the length of the actual waveform inside the table
  kstartTime = kSampleOffset * (nsamp(gitableLeft) / ftlen(gitableLeft))

  kstartTimeVariation = 0.0005
  kgrainDuration = 0.2
  kgrainsPerSecond = 15
  imaxGrainOverlaps = 1024

  kfrpow = 0 ; controls distribution of random values for frequency variation
  kprpow = 0.5 ; controls distribution of random values for start time variation

  ktableLeft = gitableLeft
  ktableRight = gitableRight

  a1 grain3 kcps, kstartTime, 0, kstartTimeVariation, kgrainDuration, kgrainsPerSecond\
     , imaxGrainOverlaps, ktableLeft, giblackmanWindow, kfrpow, kprpow
  a2 grain3 kcps, kstartTime, 0, kstartTimeVariation, kgrainDuration, kgrainsPerSecond\
     , imaxGrainOverlaps, ktableRight, giblackmanWindow, kfrpow, kprpow
  outs a1, a2

  ; kamp = 0.2
  ; a1 grain kamp, kcps, kgrainsPerSecond, 0, 0, kgrainDuration, gitableLeft, giblackmanWindow, 2, 0.1
  ; outs a1, a1

  ; aout oscil 0.1, cpsmidi()
  ; outs aout, aout
endin

</CsInstruments> 

<CsScore>
f0 z
i 1 0 -1
</CsScore>

</CsoundSynthesizer>

I may be able to get what I need from the partikkel opcode but I thought I’d check cause grain3 really gives me exactly what I want.

That’s interesting. Have you tried an example outside of Cabbage, from the command line? You might get more info there. If it crashes there I’d suggest you prepare a simple example and file an issue on the Csound github page. :+1: I will try your example later when I am back to a machine with a running version of Cabbage 3.

I just tried this here with csound7 from the command line and it’s working fine. I’ll take a look in Cabbage now…

No issues here with Cabbage either (windows). It’s not crashing or producing any errors. It’s also not producing any audio, but I didn’t have time to look into that.

This is pretty odd. Why not start instrument 99 from the score, or replace this entire instr block with schedule(99, 0, 0)?