Welcome to the new and improved Native Instruments online community. Join our active forum of 40,000+ members for discussions and much more.

Octave Transposition Per Group

AndrewFromTexas Member Posts: 5 Sine

Hey everyone,

I'm building a pretty simple instrument that only has four groups and I'm running into a bit of trouble figuring out how to manipulate the MIDI note number that each individual group receives. I'd like to have four sets of buttons on the UI that set the octave at which each group plays back.

For example, if I press C3 on the MIDI controller and have the group 0 transposition controls set to -1 (for minus one octave), then group 0 plays back C2 while the other groups play the original C3.

I've looked at the Interval factory script and understand how to apply that idea to the entire instrument, but my brain is having trouble trying to figure out how to split that between the individual groups.

So far, this is what my On Note CB looks like, including the factory Arpeggiator script, which I do not want to split between groups.

on note


    {Group on/off permissions}
    if $sine_pnl_on_off_swi = 1
    end if

    if $square_pnl_on_off_swi = 1
    end if

    if $triangle_pnl_on_off_swi = 1
    end if

    if $saw_pnl_on_off_swi = 1
    end if

{******************** ARP STUFF ********************}
    if ($arp_pnl_on_off_swi = 1)

        { make sure we only receive one event per key }
        if (%note_ids[$EVENT_NOTE] > 0)
            %note_ids[$EVENT_NOTE] := $EVENT_ID
        end if

        select ($arp_pnl_latch_swi)
            case 0
                %note_buffer[$cursor] := $EVENT_NOTE
                %vel_buffer[$cursor] := $EVENT_VELOCITY

            case 1
                if ($ENGINE_UPTIME - $old_latch_time > $LATCH_TIME)
                    $i := 0
                    while ($i < $cursor)
                        %note_buffer[$i] := 0
                    end while

                    $cursor := 0
                end if

                $old_latch_time := $ENGINE_UPTIME
                %note_buffer[$cursor] := $EVENT_NOTE
                %vel_buffer[$cursor] := $EVENT_VELOCITY

        end select

        { start arpegiator }
        if ($cursor < 2 and $seq_running = 0)
            if ($NI_TRANSPORT_RUNNING = 0)
                wait($REC_TIME_TRANSPORT_STOPPED * 1000)
                wait($REC_TIME_TRANSPORT_RUNNING * 1000)
            end if

            call StartSeq()
        end if
    end if

end on 

As I was writing this I took another look through the Event Commands chapter in the KSP manual but I must be missing something. I'm thinking I may be able to use set_event_mark() or set_event_par(), but I'm not seeing a way to tie those to a specific group.


  • AndrewFromTexas
    AndrewFromTexas Member Posts: 5 Sine

    So, as a quick update just in case anyone has checked out this thread, instead of trying to separate out incoming MIDI note information to each group, I created two duplicates of each original group for a total of twelve groups. One of the duplicate sets is for the down-one-octave setting, the other duplicate set for the up-one-octave setting. The difference being the MIDI note number that each zone is assigned to within those duplicate groups. Now the up and down octave buttons set a variable value between 0 and 2 that determine which groups are to be allowed inside the On Note CB.

    To make sure all effect and modulation parameters are the same between the groups, I'm simply going through the script to replace all of the instances where a group number is required with an array containing the group numbers. A For loop is being used to cycle through each array index so that the UI controls will change the parameters for all groups within the array.

    For example, here's what part of a UI CB looks like with this change:

    on init
    declare sine_group_nums[3] := (4, 0, 8) // An index for each octave: low, normal, high
    end on 
    on ui_control ($sine_pnl_attack_knb)
        for i := 0 to 2
            set_engine_par(ENGINE_PAR_ATTACK, $sine_pnl_attack_knb, sine_group_nums[i], find_mod(sine_group_nums[i], "SINE_ADSR"), -1)
        end for 
    end on 
Back To Top