I know this forum is for Cabbage related questions but I couldn’t get any answers in the Csound forum and I’m desperate for help.
I have this if statement but it only runs on the first time. I’m trying to send a pitch bend message everytime the C note is pressed.
<CsOptions>
; Select audio/midi flags here according to platform
; Audio out Audio in No messages
-+rtmidi=NULL -M0 -Q0 ;;;RT audio I/O with MIDI in
; For Non-realtime ouput leave only the line below:
; -o midiin.wav -W ;;; for file output any platform
</CsOptions>
<CsInstruments>
sr = 44100
ksmps = 10
nchnls = 1
massign 0, 130
pgmassign 0, 130
instr 130
kstatus, kchan, kdata1, kdata2 midiin
if (kstatus == 144 && kdata1%12==0 &&kdata2>0 ) then
outkpb 1, 70, -200, 200
endif
if (kstatus == 144 && kdata1%12==1 &&kdata2>0 ) then
outkpb 1, 30, -200, 200
endif
endin
</CsInstruments>
<CsScore>
i130 0 3600
e
</CsScore>
</CsoundSynthesizer>
Is it a problem with the score section? I tried a while loop but I get the same result.
I added the missing tag and it runs for me. But I don’t have a device with a pitch bend wheel. I suspect kdata1%12==0 might be an issue. If I remove it, those if blocks are hit as epected:
<Cabbage>
form size(500, 300), caption("Untitled")
keyboard bounds(10, 27, 400, 100) channel("keyboard10000")
</Cabbage>
<CsoundSynthesizer>
<CsOptions>
-+rtmidi=NULL -M0 -Q0 ;;RT audio I/O with MIDI in
</CsOptions>
<CsInstruments>
sr = 44100
ksmps = 10
nchnls = 1
massign 0, 130
pgmassign 0, 130
instr 130
kstatus, kchan, kdata1, kdata2 midiin
if (kstatus == 144 && kdata2>0 ) then
printks "kdata1", 0
endif
if (kstatus == 144 && kdata2>0 ) then
printks "kdata2", 0
endif
endin
</CsInstruments>
<CsScore>
i130 0 3600
</CsScore>
I need the kdata1 because I will build turkish microtonal scales with this. I want specific pitch bend values to happen when I press specific keys.
Edit: I now checked and it was a copy paste error. I have the opening csound synthesizer part in my original code.
Here is a really crazy thing.
ps:selam means hello in turkish.
<Cabbage>
form size(500, 300), caption("Untitled")
keyboard bounds(10, 27, 400, 100) channel("keyboard10000")
</Cabbage>
<CsoundSynthesizer>
<CsOptions>
-+rtmidi=NULL -M0 -Q0 ;;RT audio I/O with MIDI in
</CsOptions>
<CsInstruments>
sr = 44100
ksmps = 10
nchnls = 1
massign 0, 130
pgmassign 0, 130
instr 130
kstatus, kchan, kdata1, kdata2 midiin
if ((kstatus == 144) && (kdata1%12==0) ) then
prints "selam"
outkpb 1, 70, -200, 200
endif
endin
</CsInstruments>
<CsScore>
i130 0 3600
</CsScore>
When I run this code, The pitch bend function runs only once and only with the C note. When I check the console, regardless of which note I play, the print function works and not only once. How can an if statement work this way? If it only took action when the C note was pressed, why did I see selam every time I played random notes on the console? If not why doesn’t it send a pitch wheel message when I play any other note(I restarted before trying other keys so it’s not because it already sent it and won’t send it the second time.)?
Depends if you are using printks or printf. Printf is probably a better option but requires a ktrig value that has to change to print more than once. Perhaps there’s another solution but this seems to work.
kprint init 0
ktrig changed kstatus
if ktrig == 1 then
kprint += 1
endif
if kstatus == 144 && kdata1 % 12 == 0 then
printf "\nselam\n", kprint
outkpb 1, 70, -200, 200
endif
Thank you for the advice. I actually solved the issue with the printing part, which was basically a test to see where the problem was. The if loop by itself works fine, I get the “selam” print everytime I play a C note from my MIDI keyboard. I just don’t understand why it sends the pitch bend message only once. I tried adding a second if statement for a B note to see if the pitch bend value needed to change before sending it again but it didn’t work either. They both run only once. Sometimes the code seems to trigger a new midi alloc(ation?) on its own and then it sends one more but I’m not sure how it does that.
What is this about? I don’t follow your use modulus here? I just now get my hands on a device with pitchbend, and it does seem a little strange. The status byte is only 224 momentarily, which messes up the if the statement. Have you considering using the midipitchbend opcode instead?
kdata1 is the midi note number of the midi message. kstatus is the note on. kdata1 changes accordingly to the midi message type. I use it to determine which note is played. So if kdata1 is perfectly dividable with 12, then it’s a C note.
Edit: Doesn’t midipitchbend opcode only return the value? I want the code to output pitchbend values that I set.
I played around with this one. The outkpb still only works once. The modulus with p4 seems to make everything worse.It goes into a state where if a second passes any key triggers the print.Also, the midi key command line flag returns values that are shifted(Ex:C1 has a midi note number of 24 but p4 returns it as 36 and the order of other notes isn’t broken.). Without the modulus the printks works okay but again, no luck with the pitch bend.
<CsoundSynthesizer>
<CsOptions>
-+rtmidi=NULL -M0 --midi-key=4 -Q0 ;;RT audio I/O with MIDI in
</CsOptions>
<CsInstruments>
ksmps = 32
instr 1
if (p4==36) then
printks "Output pitch bend data", 1
outkpb 1, 70, -200, 200
endif
endin
</CsInstruments>
<CsScore>
i1 0 z
</CsScore>
</CsoundSynthesizer>
I won’t have access to a MIDI keyboard again until Thurday, but I’ll try then. The problem is I have no clear way of testing the output from the pitch bend opcode. Try replacing the i1 0 z in the score with f0 z so that the instrument is only triggered to play with the keyboard rather than the score.
According to who? There is no standard numbering for MIDI octaves. According to the MIDI specificiation middle C is C60, but afaik, C3/C4 etc are not defined in those specs. Which is many synth manufacturers use different octave numbering.