Cabbage Logo
Back to Cabbage Site

Sfile

Hello

I’m trying to make kind of drum sampler that uses a mix of real samples and oscillators that are triggered by midi notes.

In my code, I use Sfile to trigger different samples in the same instrument and when I make a new instrument for an oscillator, it does not come out with any sound, when I click the assigned midi-key. The error seems to be that it tries to use the disk-in in my first instrument.

I can’t seem the figure out how instr 2 doesn’t use the disk-in output but it’s own. Also the samples themselves only play fully out if I hold down the key, but doesn’t if I just tap the note on the keyboard.

Any suggestions?, thanks! :slight_smile:

Sfile - test.csd (1.4 KB)

Hi @lukasrb, welcome to the forum. So instrument 1 is being triggered by the MIDI keyboard by default. You don’t need to start it using i1 0 z. You don’t need to start instrument 2 either, you can just assign it a midi channel using massign:

massign 1, 2

On top of that you have another few issues, but they should become clear once you actually start triggering instrument 2. Note that you can use f0 z in the score section to keep Csound running, even if no instruments are playing. This is optimal for working with live midi input.

1 Like

Hi Rory - thanks for the quick answer!

I think I was aware of that. I see that it makes sense to just use massign, but for the triggering of instr 2 it works, but it keeps on telling me that it can’t find the specific “wav”, file when clicking other midi-notes than the ones in instr 1, so I guess I don’t know how to separate the instr 2 from instr 1, so it doesn’t use the outs in instr 1.

I think I’m totally lost here :smiley:
I also tried with just a simple oscillator, and it doesn’t work either. It just keeps giving me an error when clicking other notes than the assigned in instr 1.

You should pass a full path to your sound files. you can get the path of the current csd file using chnget:S(“CSD_PATH”), from that you can construct the full path. But for testing you can just use an absolute path to the sound files.

1 Like

Hi Rory.

I’m sorry for many questions - and I might’ve not explained my issue well enough. I am no wizard in Csound! But the problem isn’t that audio files are not playing. The problem appears when I want another instrument that is not an audiofile to play at a specific midi note. I want to create an oscillator, that just like the audio files, plays at a certain midi note. But sound recognizes all notes on the midi-keyboard as disk in notes, even though I’ve set the oscillator to be at another midi note.

The only problem with the files are that they only play the full sample if I hold down the key. I want them to play the full sample when just clicked on - but that didn’t work as planned. I tried with turnoff, but with no luck unfortunately.

I’m sure Rory can help find better solutions but for now this should work ok:

<Cabbage>
form caption("Drum-synth") size(400, 300), guiMode("queue"), pluginId("def1")
keyboard bounds(8, 158, 381, 95)
</Cabbage>
<CsoundSynthesizer>

<CsOptions>
-n -d -+rtmidi=NULL -M0 --midi-key-cps=4 --midi-velocity-amp=5 -b128 -B256
</CsOptions>

<CsInstruments>
; Initialize the global variables. 
ksmps = 32
nchnls = 2
0dbfs = 1

    instr 1

iNote notnum
iVel = p5

 ; Declare a variable to hold the file name
    Sfile = ""

    ; Choose the sample file based on the MIDI note number
    if (iNote == 60) then
        Sfile = "1 - Hi-Hat.wav"
    elseif (iNote == 61) then
        Sfile = "2 - Crash.wav"
    elseif (iNote == 62) then
        Sfile = "3 - Rimshot.wav"
    ; Add more conditions for other notes/samples if needed
    elseif (iNote > 0) then
        event_i "i", 2, 0, 1, iNote, 1
    endif

    ; Get Sfile length & add extra time
    iLen filelen Sfile
    xtratim iLen

    ; Play the selected sample without looping
    a1, a2 diskin2 Sfile, 1, 0, 0

    ; Output the audio
    outs a1, a2
 
endin

instr 2
   
    iNote = p4
    iVel = p5

    if (iNote == 63) then
      
        kFreq expon 400, 0.1, 5
       
        kAmp expon 1, 0.7, 0.00001
        aSin oscil kAmp, kFreq

        kNoiseAmp expon 1, 0.1, 0.00001
    
        aNoise rand kNoiseAmp * 0.2

        aOut = aSin + aNoise

        outs aOut, aOut
    endif

endin

</CsInstruments>

<CsScore>
;causes Csound to run for about 7000 years...
f 0 z
</CsScore>
</CsoundSynthesizer>
1 Like

Sorry @lukasrb I misread your issue. Another problem I spotted with instrument 2 is your checking for note number 63, but p4 is a frequency value, not a note number. So instead of:

--midi-key-cps=4

you should use:

--midi-key=4

If you do, then p4 will be assigning the midi note number.

1 Like

This definitely works for the samples playing fully when clicked on, but still won’t allow me to play the instr 2 cause it’s still referring to the disk ins.

Maybe I should re-think the whole code and do each sound in separate instruments!

Btw, you can also just run the oscillator code in instrument 1…

1 Like

I tried that too, but as the diskin is in the outs, it will do the exact same thing. And still not play out the sound of the oscillator! I tried rearranging the outs too without success :frowning:

Did you fix the --midi-key-cps=4 issue? Also, you have an invalid function table in instrument 2. You are trying to use a function table that hasn’t been defined.

1 Like

Ye, I saw that. My bad! Now the sound from the oscillator comes out on the midi-keyboard, but now it won’t play the samples now. I’ve tried both with having the oscillator in instr 1 and 2.

Can you post the most up to date .csd file?

Yes - here its s

Drum Synth.csd (1.6 KB)

you’re not assigning the midi channels to any instruments? So only instrument 1 will be triggered when you play a note. See my comments about massign

Here:

<Cabbage>
form caption("Drum-synth") size(400, 300), guiMode("queue"), pluginId("def1")
keyboard bounds(8, 158, 381, 95)
</Cabbage>
<CsoundSynthesizer>

<CsOptions>
-n -d -+rtmidi=NULL -M0 --midi-key=4 --midi-velocity-amp=5 -b128 -B256
</CsOptions>

<CsInstruments>
; Initialize the global variables. 
ksmps = 32
nchnls = 2
0dbfs = 1

massign 1, 1
massign 1, 2

instr 1

;Henter notenummer

iNote notnum
iVel = p5

 ; Declare a variable to hold the file name
    Sfile = ""

    ; Choose the sample file based on the MIDI note number
    if (iNote == 60) then
        Sfile = "1 - Hi-Hat.wav"
    elseif (iNote == 61) then
        Sfile = "2 - Crash.wav"
    elseif (iNote == 62) then
        Sfile = "3 - Rimshot.wav"
    ; Add more conditions for other notes/samples if needed
    elseif (iNote > 0) then
        event_i "i", 2, 0, 1, iNote, 1
    endif


iLen filelen Sfile
xtratim iLen

    ; Play the selected sample without looping
    a1, a2 diskin2 Sfile, 1, 0, 0
 

    ; Output the audio
    outs a1, a2

endin

instr 2


    ; Get the MIDI note number and velocity
    iNote = p4
    iVel = p5

    ; Midi-note input
    if (iNote == 63) then
        ; Bass drum synthesis code
      
        kFreq expon 400, 0.1, 5
        kAmp expon 1, 0.7, 0.00001
        aSin oscil kAmp, kFreq

        kNoiseAmp expon 1, 0.1, 0.00001
        aNoise rand kNoiseAmp * 0.2

        aOut = aSin + aNoise

        ; Output the audio
        outs aOut, aOut
    endif
endin

</CsInstruments>

<CsScore>
;causes Csound to run for about 7000 years...
f 0 z
</CsScore>
</CsoundSynthesizer>

I get it. I actually tried that before. And with your code it still doesn’t play the samples now. It prints out the midi-key and event but no sound is coming when I use the internal keyboard in Cabbage. The kick still works.

It won’t play the sample here either because I don’t have them. Look at your Csound output, it should give you some information about why they are not playing.

I am getting no error anymore. It just prints out in console when clicking on the selected midi note:

I’m sorry for the lack of knowledge, but I’m genuinely confused :smiley:

midiKey: pfield: 4 value: 62
midiVelocityAmp: pfield: 5 value: 0.544
rtevent: T 22.252 TT 22.252 M: 0.00000 0.00000

Ok, I see an issue with my code, it seems that you can’t assign two different Csound instruments to the same MIDI channel. I always thought this was possible. Anyway, I think you’re better off putting everything into the same instrument. Otherwise you’ll have to manage the starting and stopping of the other instruments manually. See below, Btw, this code is a bit of a mess - but should get you set up.

<Cabbage>
form caption("Drum-synth") size(400, 300), guiMode("queue"), pluginId("def1")
keyboard bounds(8, 158, 381, 95)
</Cabbage>
<CsoundSynthesizer>

<CsOptions>
-n -d -+rtmidi=NULL -M0 --midi-key=4 --midi-velocity-amp=5 -b128 -B256
</CsOptions>

<CsInstruments>
; Initialize the global variables. 
ksmps = 32
nchnls = 2
0dbfs = 1

massign 1, 1

instr 1

;Henter notenummer

iNote notnum
iVel = p5

 ; Declare a variable to hold the file name
    Sfile = ""

;    ; Choose the sample file based on the MIDI note number
    if (iNote == 60) then
        Sfile = "1 - Hi-Hat.wav"
    elseif (iNote == 61) then
        Sfile = "2 - Crash.wav"
    elseif (iNote == 62) then
        Sfile = "3 - Rimshot.wav"
    endif


    iLen filelen Sfile
    xtratim iLen

    ; Play the selected sample without looping
    a1, a2 diskin2 Sfile, 1, 0, 0
 

    ; Output the audio
    outs a1, a2
 
     ; Midi-note input
    if (iNote == 63) then
        ; Bass drum synthesis code
      
        kFreq expon 400, 0.1, 5
        kAmp expon 1, 0.7, 0.00001
        aSin oscil kAmp, kFreq

        kNoiseAmp expon 1, 0.1, 0.00001
        aNoise rand kNoiseAmp * 0.2

        aOut = aSin + aNoise

        ; Output the audio
        outs aOut, aOut
    endif
endin



</CsInstruments>

<CsScore>
;causes Csound to run for about 7000 years...
f 0 z
</CsScore>
</CsoundSynthesizer>