MIDI IN issues - Real time sync of CC values not working

Hi there ,

Excuses if it is too simple an issue but I am a bit short in time and I would really like to use Sonic Pi in my next performance a few days from now.

The issue is with MDI IN settings . How do I get the MIDI CC value to keep constant?
If I use it within the loop like so :

in_thread(name: :key_0) do

live_loop :midi_piano do

chan, ampCC = sync "/midi/reloop_keypad/9/1/control_change"

with_fx :compressor, amp: 0.5  do

          use_real_time
          
          use_synth_defaults release: 2, cutoff: 1, attack: 1, amp: ampCC/127.0
          ##| use_synth :saw
          note, velocity = sync "/midi/reloop_keypad/9/1/note_on"
          synth :saw, note: note,
            amp: velocity / 127.0
          play note
          play note + 50
          sleep 0.125
          
       end

end
end

The amp value from my Midi controller updates only when I touch it and seems to reset to 0 if I don’t

If I place it outside the loop like so :

in_thread(name: :key_0) do

chan, ampCC = sync “/midi/reloop_keypad/9/1/control_change”

live_loop :midi_piano do

with_fx :compressor, amp: 0.5  do
  
  use_real_time
  
  use_synth_defaults release: 2, cutoff: 1, attack: 1, amp: ampCC/127.0
  ##| use_synth :saw
  note, velocity = sync "/midi/reloop_keypad/9/1/note_on"
  synth :saw, note: note,
    amp: velocity / 127.0
  play note
  play note + 50
  sleep 0.125
  
  
end

end
end

it updates only if I run the code again

Any alternatives to this ?
I should be able to control in real time the level of ampCC without having to rerun the code every time or touch the volume fader every note I strike.

Any suggestions welcome

Thanks in advance

Seb

I think you can do it with two live loops, something like the following (untested):

use_real_time

set :ampcc, 0
live_loop :midi_cc do
  _, amp = sync "/midi/reloop_keypad/9/1/control_change"
  set :ampcc, amp
end

live_loop :midi_piano do
  with_fx :compressor, amp: 0.5  do
    note, velocity = sync "/midi/reloop_keypad/9/1/note_on"
    ampCC = get :ampcc
    use_synth_defaults release: 2, cutoff: 1, attack: 1, amp: ampCC/127.0
    synth :saw, note: note, amp: velocity / 127.0
    play note
    play note + 50
  end
end

This way only the first loop will block waiting for new CC messages, and the second loop will only wait for key presses, but still get the latest ampCC via set/get.

2 Likes

Emily , Thanks you so much for your reply. I think it works now , however this only controls any cc as amplitude value, do you know how can I filter my controls so that only controller 7 for example gets to handle the master volume and I can use other faders for different value wihout affecting my synth master amop value. I was trying using a conditional but it does not seem to be working

Thanks again
Seb

Hi Seb,
I think that the first returned value (that’s being ignored above) might be what you need to use to differentiate between the controls. Try running:

use_real_time
live_loop :midi_cc do
  cc, val = sync "/midi/reloop_keypad/9/1/control_change"
  print cc
end

and have a look at the log output to see what values are printed when you change different controls. If it varies, then you can use the different values to do different things, by replacing the first live_loop with something like:

set :ampcc, 0
live_loop :midi_cc do
  cc, val = sync "/midi/reloop_keypad/9/1/control_change"
  if cc == 7
    set :ampcc, val
  elsif cc == 8
    set :something, val
    # etc...
  end
end

I’m not sure, but I hope that works!

1 Like

Yes I needed to filter that first value. thaanks so much for your help.
I have been working on what you gave me , I get stuck since my syntax is tragic, somehow it seems I cannot reuse “ampOut” if it’s not local to the loop where it’s declared. Or that’s at least what I thought was happening. I think I am missing a method here (not extrapolating to life : / )

Also , I would need everything to be under the same thread ? since I want to update the code whilst playing (when using DirtMIDI or ARP+SUS on my controller)
Getting closer
Thanks again
Seb

in_thread(name: :key_0) do
use_real_time

live_loop :midi_piano do

set :ampcc, 0
live_loop :midi_cc do
  cc, val = sync "/midi/reloop_keypad/9/1/control_change"
  if cc == 7
    set :ampcc, val
  elsif cc == 8
    set :something, val
    # etc...
    ampOut = get :ampcc
    
    ##| sleep 0.01
  end
end





with_fx :compressor, amp: ampOut  do
  with_fx :lpf, cutoff: 80 do
    with_fx :slicer, phase: 0.15, wave: 3, mix: 0.2 do
      with_fx :bitcrusher,bits: 4, mix: 0.8 do
        with_fx :distortion, distort: 0.8,mix: 0.5 do
          
          
          use_real_time
          ##| use_sched_ahead_time <0.2>
          ##| use_synth :saw
          note, velocity = sync "/midi/reloop_keypad/9/1/note_on"
          use_synth_defaults release: 2, cutoff: 1, attack: 1, amp: velocity/127.0
          ##| chan, ampCC = sync "/midi/reloop_keypad/9/1/control_change"
          synth :saw, note: note,
            amp: velocity / 127.0
          play note
          play note + 50
          sleep 0.125
          
          ##| play note - 25
        end
        
      end
      
    end
  end
end

end
end

You should be able to update the code while playing if you use live_loops, no need for more threads, as live_loops already incorporate threads.

To send values between different live_loops, you can use set in one loop, and get in the other. Check out sections 9 & 10 of the built-in tutorial for more detail.

In order to control the amp of an effect it’s a little more complicated: you have to pass the effect into the block of code, and then you can use control to modify it.

I think this should be close to what you’re trying to do (although it only adjusts the volume at the start of each note, to control it continuously is a bit more tricky)


set :ampcc, 0
set :something, 0
live_loop :midi_cc do
  cc, val = sync "/midi/reloop_keypad/9/1/control_change"
  if cc == 7
    set :ampcc, val
  elsif cc == 8
    set :something, val
    # etc...
  end
end


live_loop :midi_piano do
  with_fx :compressor, amp: 1 do |fx|
    with_fx :lpf, cutoff: 80 do
      with_fx :slicer, phase: 0.15, wave: 3, mix: 0.2 do
        with_fx :bitcrusher,bits: 4, mix: 0.8 do
          with_fx :distortion, distort: 0.8,mix: 0.5 do
            use_real_time
            note, velocity = sync "/midi/reloop_keypad/9/1/note_on"
            
            ampout = get :ampcc
            control fx, amp: ampout
            
            # now you can also use 'something'
            something = get :something
            
            use_synth_defaults release: 2, cutoff: 1, attack: 1, amp: velocity/127.0
            synth :saw, note: note,
              amp: velocity / 127.0
            play note
            play note + 50
            sleep 0.125
            
            ##| play note - 25
          end
        end
      end
    end
  end
end