Cabbage Logo
Back to Cabbage Site

Help, "Stop Audio" button Crashing Cabbage

This is the code I’m trying to figure out, honestly I’m not the greatest with code so fairly clueless

; Define instrument 101 to handle play/stop button presses and playback
instr 101

kButton1 chnget "playButton1"


if (kButton1 == 1 && gkPlayFlag1 == 0) then
    event "i", 1, 0, -1 ; Play instrument 1 indefinitely
    gkPlayFlag1 = 1 ; Set the play flag for the first audio file
endif

kStopButton1 chnget "stopButton1"

if (kStopButton1 == 1 && gkPlayFlag1 == 1) then
    turnoff2 1, 0, 0 ; Stop instrument 1
    gkPlayFlag1 = 0 ; Reset the play flag for the first audio file
endif

endin

This is the result that comes out in the code and seems to be an infinite loops which causes the crash but i’m not sure how to fix it. rtevent: T 16.631 TT 16.631 M: 0.00096 0.00101 diskin2: opened ‘C:############\Desktop\TEST\ambience1.wav’: 44100 Hz, 2 channel(s), 11356592 sample frames

Hi @Shane_Dunphy, can you upload a full, albeit simplified .csd file to test with?

What would turn off kButton1?

Hi @rorywalsh I’ve uploaded the full .csd cut down to 4 play buttons. Honestly I dont understand enough to figure out where I’m going wrong. Any help would be amazing thank you. https://1drv.ms/u/s!AqLSnUAwjdp9iaIITCowC-arlloKjA?e=40HRjv

You’re right about the infinite loop. Here is the problem:

instr 101
    ; Check the state of the "playButton1" channel
    kButton1 chnget "playButton1"
    
    ; If the button is pressed and the play flag is not set, play the first audio file
    if (kButton1 == 1 && gkPlayFlag1 == 0) then
        event "i", 1, 0, -1 ; Play instrument 1 indefinitely
        gkPlayFlag1 = 1 ; Set the play flag for the first audio file
    endif
    
    ; Check the state of the "stopButton1" channel
    kStopButton1 chnget "stopButton1"
    
    ; If the stop button is pressed and the play flag is set, stop the first audio file
    if (kStopButton1 == 1 && gkPlayFlag1 == 1) then
        turnoff2 1, 0, 0 ; Stop instrument 1
        gkPlayFlag1 = 0 ; Reset the play flag for the first audio file
    endif
endin

You set gkPlayFlag1 to 0 when you stop the playback, but as Csound thn moves through with the next k-cycle, kbutton1 is still 1, and gkPlayFlag is 0. Therefore it enters the first if statement and starts the whole thing again, and keeps on starting it. If you want to start events using buttons, it’s always best to do so ONLY when a button state changes. You can used the changed opcode for this, or cabbageGetValue, which will give you a trigger when the button state changes. Something like this should work:

; Define instrument 101 to handle play/stop button presses and playback
instr 101
    ; Check the state of the "playButton1" channel
    kButton1, kButton1Trig cabbageGetValue "playButton1"
    
    ; If the button is pressed and the play flag is not set, play the first audio file
    if (kButton1Trig == 1) then
        event "i", 1, 0, -1 ; Play instrument 1 indefinitely
    endif
    
    ; Check the state of the "stopButton1" channel
    kStopButton1, kStopButtonTrig cabbageGetValue "stopButton1"
    
    ; If the stop button is pressed and the play flag is set, stop the first audio file
    if (kStopButtonTrig == 1) then
        turnoff2 1, 0, 0 ; Stop instrument 1
    endif
endin

And you’ve no need for those flags any more either. One thing you might want to look into when you have this much working for all files is to simplify your code. You really only need 2 instruments for this. One to play a sound file, and one to manage. By passing p-fields from the score you can create instances of the same instrument, that will interact with the different play instruments, for example:

(...)

; Define instrument 101 to handle play/stop button presses and playback
instr 101
    ; Check the state of the "playButton1" channel
    SPlayChannel sprintf "playButton%d", p4
    kButton, kButtonTrig cabbageGetValue SPlayChannel
    
    ; If the button is pressed and the play flag is not set, play the first audio file
    if (kButtonTrig == 1) then
        event "i", p4, 0, -1 ; Play instrument 1 indefinitely
    endif
    
    ; Check the state of the "stopButton1" channel
    ;SStopChannel sprintf "stopButton%d", p4
    kStopButton1, kStopButtonTrig cabbageGetValue "stopButton1"
    
    ; If the stop button is pressed and the play flag is set, stop the first audio file
    if (kStopButtonTrig == 1) then
        turnoff2 p4, 0, 0 ; Stop instrument 1
    endif
endin

</CsInstruments>
<CsScore>
; Activate the play/stop control instrument
i 101 0 z 1
i 101 0 z 2
i 101 0 z 3
i 101 0 z 4
</CsScore>
</CsoundSynthesizer> 

In that example all instances are stopped when the stop ambience button is pressed, But if you want control over each instance, why not use each Ambience button to control the start/stop of the samples? He’s a simple version of your instrument. The only slightly advanced aspect of it is that we start each sound file instrument with a fractional instrument number.

;========================================================================================================================================================================================================================
; UX Section
;========================================================================================================================================================================================================================

; Define the main window with a title, size, GUI mode, and plugin ID form caption("Tabletop Audio Controller") size(1200, 800), guiMode("queue"), pluginId("def1")

; Create the first set of controls for the first audio file
groupbox bounds(2, 2, 1198, 140), text(“Ambience”) channel(“groupbox1”) colour(89, 0, 0, 255) outlineColour(255, 255, 255, 255) fontColour(255, 255, 255, 255)
button bounds(100, 28, 80, 80) channel(“playButton1”) text(“Play Ambience”, “Stop Ambience”)
button bounds(194, 28, 80, 80) channel(“playButton2”) text(“Play Ambience 2”, “Stop Ambience 2”)
button bounds(286, 28, 80, 80) channel(“playButton3”) text(“Play Ambience 3”, “Stop Ambience 3”)
button bounds(378, 28, 80, 80) channel(“playButton4”) text(“Play Ambience 4”, “Stop Ambience 4”)
hslider bounds(10, 110, 1180, 30) channel(“volumeSlider1”) range(0, 1, 0.5, 1, 0.001) textColour(0, 0, 0, 255)

; Set Csound options: -n for no sound output file, -d for no display of performance information -n -d

; Initialize global variables
sr = 44100 ; Set the sample rate to 44100 Hz
ksmps = 64 ; Set the control rate to 64 samples
nchnls = 2 ; Set the number of audio channels to 2 (stereo)
0dbfs = 1 ; Set the maximum amplitude to 1

;========================================================================================================================================================================================================================
; Instrument Section for Playback
;========================================================================================================================================================================================================================

; Define instrument 1 for the first audio file playback
instr 1
; Load the audio file “ambience1.wav” and output its audio signals a1 and a2
SFilname sprintf “ambience%d.wav”, p4
a1, a2 diskin2 SFilname, 1, 0, 1
; Get the volume value from the “volumeSlider1” channel
kVol chnget “volumeSlider1”
; Output the audio signals scaled by the volume value
outs a1 * kVol, a2 * kVol
endin

;========================================================================================================================================================================================================================
; Instrument Section for Play/Stop Control
;========================================================================================================================================================================================================================
; Define instrument 101 to handle play/stop button presses and playback
instr 101
; Check the state of the “playButton1” channel
SPlayChannel sprintf “playButton%d”, p4
kButton, kButtonTrig cabbageGetValue SPlayChannel

; If the button is pressed and the play flag is not set, play the first audio file
if (kButtonTrig == 1) then
    if ( kButton == 1 ) then
        //start instrument 1. By adding p4*.1 we ensure it's a unique instance
        event "i", 1+(p4*.1), 0, -1, p4 ; Play instrument 1 indefinitely
    else
        //we can now stop the unique instance we started earlier 
        turnoff2 1+(p4*.1), 0, 0 ; Stop instrument 1
    endif
endif

endin

; Activate the play/stop control instrument i 101 0 z 1 i 101 0 z 2 i 101 0 z 3 i 101 0 z 4

Thank you so much that works perfectly. Ill try the second solution if I have time but for now I have to take the if it isn’t broken dont fix it approach :joy:

Hi @rorywalsh, the solution works perfectly all ambience .wavs in 1 instrument thank you. Having issues now trying to get a second instrument to work. I dont understand enough to see why the second two instruments are still calling for ambience.wavs. Again thanks for the help, any you could give would be fantastic

;========================================================================================================================================================================================================================
; UX Section
;========================================================================================================================================================================================================================

; Define the main window with a title, size, GUI mode, and plugin ID form caption("Tabletop Audio Controller") size(834, 748), guiMode("queue"), pluginId("def1") ; Used to Define the Background Image and its boundaries image bounds(0, 0, 834, 748) channel("image1") file("BG1.jpg")

; Create the first set of controls for the Ambience
groupbox bounds(2, 2, 830, 110), text(“Ambience”) channel(“groupbox1”) colour(89, 0, 0, 255) outlineColour(255, 255, 255, 255) fontColour(255, 255, 255, 255) alpha(0.6)
button bounds(100, 22, 80, 80) channel(“playButton1”) text(“Tavern”, “Tavern”)
button bounds(194, 22, 80, 80) channel(“playButton2”) text(“Town”, “Town”)
button bounds(286, 22, 80, 80) channel(“playButton3”) text(“Cave”, “Cave”)
button bounds(378, 22, 80, 80) channel(“playButton4”) text(“Forest”, “Forest”)
button bounds(10, 22, 80, 80) channel(“stopButton1”) text(“Stop”, “Stop”) colour:1(147, 0, 0, 255) colour:0(147, 0, 0, 255)
hslider bounds(460, 22, 370, 40) channel(“volumeSlider1”) range(0, 1, 0.5, 1, 0.001) textColour(0, 0, 0, 255) trackerColour(210, 178, 0, 255)

; Create the second set of controls for the Music
groupbox bounds(2, 118, 830, 110), text(“Music”) channel(“groupbox2”) colour(67, 0, 89, 255) outlineColour(255, 255, 255, 255) fontColour(255, 255, 255, 255) alpha(0.6)
button bounds(100, 138, 80, 80) channel(“playButton5”) text(“Relaxed”, “Relaxed”)
button bounds(194, 138, 80, 80) channel(“playButton6”) text(“Combat”, “Combat”)
button bounds(286, 138, 80, 80) channel(“playButton7”) text(“Tense”, “Tense”)
button bounds(10, 138, 80, 80) channel(“stopButton2”) text(“Stop”, “Stop”) colour:1(147, 0, 0, 255) colour:0(147, 0, 0, 255)
hslider bounds(380, 138, 450, 40) channel(“volumeSlider2”) range(0, 1, 0.5, 1, 0.001) textColour(0, 0, 0, 255) trackerColour(210, 0, 166, 255)

; Set Csound options: -n for no sound output file, -d for no display of performance information -n -d

;=======================================================================================================================================================================================================================
; Initialize global variables
;=======================================================================================================================================================================================================================

sr = 44100 ; Set the sample rate to 44100 Hz
ksmps = 64 ; Set the control rate to 64 samples
nchnls = 2 ; Set the number of audio channels to 2 (stereo)
0dbfs = 1 ; Set the maximum amplitude to 1

;========================================================================================================================================================================================================================
; Ambience Instrument Section
;========================================================================================================================================================================================================================

instr Ambience
; Generate the filename for the Ambience based on the button pressed
SFilname sprintf “ambience%d.wav”, p4
a1, a2 diskin2 SFilname, 1, 0, 1
kVol chnget “volumeSlider1”
outs a1 * kVol, a2 * kVol
endin

instr AmbiencePlay
SPlayChannel sprintf “playButton%d”, p4
kButton, kButtonTrig cabbageGetValue SPlayChannel

if (kButtonTrig == 1) then
    if ( kButton == 1 ) then
        turnoff2 1.1, 0, 0
        turnoff2 1.2, 0, 0
        turnoff2 1.3, 0, 0
        turnoff2 1.4, 0, 0
        event "i", 1+(p4*.1), 0, -1, p4
    else
        turnoff2 1+(p4*.1), 0, 0
    endif
endif

kStopButton1, kStopButtonTrig cabbageGetValue "stopButton1"
if (kStopButtonTrig == 1) then
    turnoff2 1.1, 0, 0
    turnoff2 1.2, 0, 0
    turnoff2 1.3, 0, 0
    turnoff2 1.4, 0, 0
endif

endin

;========================================================================================================================================================================================================================
; Music Instrument Section
;========================================================================================================================================================================================================================

instr Music
; Generate the filename for the Music based on the button pressed
SFilname sprintf “music%d.wav”, p4
a1, a2 diskin2 SFilname, 1, 0, 1
kVol chnget “volumeSlider2”
outs a1 * kVol, a2 * kVol
endin

instr MusicPlay
SPlayChannel sprintf “playButton%d”, p4
kButton, kButtonTrig cabbageGetValue SPlayChannel

if (kButtonTrig == 1) then
    if ( kButton == 1 ) then
        turnoff2 2.1, 0, 0
        turnoff2 2.2, 0, 0
        turnoff2 2.3, 0, 0
        event "i", 2+(p4*.1), 0, -1, p4
    else
        turnoff2 2+(p4*.1), 0, 0
    endif
endif

kStopButton2, kStopButtonTrig cabbageGetValue "stopButton2"
if (kStopButtonTrig == 1) then
    turnoff2 2.1, 0, 0
    turnoff2 2.2, 0, 0
    turnoff2 2.3, 0, 0
endif

endin

i "AmbiencePlay" 0 86400 1 i "AmbiencePlay" 0 86400 2 i "AmbiencePlay" 0 86400 3 i "AmbiencePlay" 0 86400 4 i "MusicPlay" 0 86400 5 i "MusicPlay" 0 86400 6 i "MusicPlay" 0 86400 7

Managed to fix the issue, now trying to get the second stop button working

Issue Sorted, replying to my own post so I’m not takin up anyone’s time

Glad to hear it’s sorted .When posted code, it’s best to highlight it and hit the </> button in the text editor to format it. Otherwise it’s really quite hard to read :wink: