示例#1
0
    def test_sent_directly(self):
        from alsamidi import pitchbendevent

        data = (1, 0, 9)
        expected = (13, 1, 0, 253, (0, 0), (0, 0), (0, 0), data)
        self.assertEqual(expected, pitchbendevent(1, 9))
示例#2
0
    def test_scheduled(self):
        from alsamidi import pitchbendevent

        data = (1, 0, 9)
        expected = (13, 1, 0, 0, (1, 0), (0, 0), (0, 0), data)
        self.assertEqual(expected, pitchbendevent(1, 9, 1000))
示例#3
0
    def MidimanToYoshiRouter_Poll(self):
        ' Router, worker, poll often, so we do not have to use threads ;)'

        if not self.mDev.Poll():
            return False # no midi events, nothing processed

        #print('got a midi event!')
        pkt = self.mDev.ReadMidi() # read only 1 message at a time
        if pkt == None:
            # ignore bogus(alsaseq giving 3 odd pkts per sec)
            return True # processed something
        m_b0 = pkt[0] # rx_ch | midi_ctrl
        m_b1 = pkt[1] # note or param
        m_b2 = pkt[2] # velocity or value

        rx_ch = m_b0 & 0xf        # The channel in lower first nibble
        tx_ch = self.mChannel # send channel, send on channel we select

        if (m_b0 & 0xf0) == 0xb0: # CC control message upper nibble

            idxEffectKnob = -1
            if m_b1 == KNOB0_CC: idxEffectKnob = 0
            if m_b1 == KNOB1_CC: idxEffectKnob = 1
            if m_b1 == KNOB2_CC: idxEffectKnob = 2
            if m_b1 == KNOB3_CC: idxEffectKnob = 3
            if idxEffectKnob >= 0: # knob 0-3 change CC event?
                # map them to the 4 yoshi system effects 0 level control
                effect_num  = 4 # system effect(4=system, 8=insert)
                effect_index = idxEffectKnob # effect index
                self.last_sys_effect = effect_index
                if self.verbose & 1:
                    map_desc = 'system effect level(%d)= %d' % (effect_index+1, m_b2)
                msb_effect_ctrl = 0 # level(volume, dry/wet)
                cc_data = m_b2 # route CC data value to new use
                self.Send_NRPN(tx_ch, effect_num, effect_index,
                               msb_effect_ctrl, cc_data)
                if self.verbose & 1:
                    print('map CC %d %d to: ' % (m_b1, m_b2) + map_desc)
            elif m_b1 == KNOB4_CC:
                if self.verbose & 1:
                    map_desc = ' master PAN CC-10= %d' % (m_b2)
                self.mDev.Write([0xb0 | tx_ch, 10, m_b2]) # route to CC-10 PAN(master)
                if self.verbose & 1:
                    print('map CC-%d %d to PAN CC-10:' % (m_b1, m_b2) + map_desc)
            elif m_b1 == KNOB5_CC:
                # this one routes pan based on last first 4 knobs used.
                # routes pan to that system effect.
                effect_num  = 4 # system effect(4=system, 8=insert)
                effect_index = self.last_sys_effect # effect index, last vol chged above
                if self.verbose & 1:
                    map_desc = ' Effect Pan, System(%d)= %d' % (effect_index+1, m_b2)
                msb_effect_ctrl = 1 # Pan
                cc_data = m_b2 # route CC data value to new use
                self.Send_NRPN(tx_ch, effect_num, effect_index,
                               msb_effect_ctrl, cc_data)
                if self.verbose & 1:
                    print('map CC %d %d to: ' % (m_b1, m_b2) + map_desc)
            elif m_b1 == KNOB6_CC:
                if self.verbose & 1:
                    map_desc = 'master Yoshi-Portamento CC-65= %d' % (m_b2)
                # This is digital on/off, > 64 is on, less off
                self.mDev.Write([0xb0 | tx_ch, 65, m_b2]) # route to CC-65 Yoshi portamento
                if self.verbose & 1:
                    print('map CC-%d %d to: ' % (m_b1, m_b2) + map_desc)
            elif m_b1 == KNOB7_CC:
                # yoshi expression cc-11, seems like same as master volume?
                #map_desc = 'master Yoshi-Expression CC-11= %d' % (m_b2)
                #mOut.Write([0xb0 | tx_ch, 11, m_b2]) # route to CC-11 Yoshi portamento
                if self.verbose & 1:
                    map_desc = 'master Yoshi-Sustain CC-64= %d' % (m_b2)
                self.mDev.Write([0xb0 | tx_ch, 64, m_b2]) # route to CC-11 Yoshi sustain?
                if self.verbose & 1:
                    print('map CC-%d %d to: ' % (m_b1, m_b2) + map_desc)
            else:
                if m_b1 == 1: # mod wheel
                    if MODWHEEL_BANKPROG_KEY_FEATURE:
                    # mod wheel escape for setting bank/prog selection.
                    # we save last mod value to try out using to set
                    # bank/prog as escape sequence - push mod up > 100
                    # then press a key, then pull mod down < 100
                    # kludgy, don't think I like it very much, but..
                        self.last_modwheel = m_b2
                        if self.last_modwheel > 100:
                            if self.verbose & 2:
                                pr('Filter Mod-Wheel %d' % (self.last_modwheel))
                            return True # processed, filter out
                    if MODWHEEL_TO_PITCH_FEATURE:
                        # mod wheel convert to differential pitch modulation
                        # make it do what pitch wheel does, but without dead middle spot
                        diff_mod = m_b2 - self.last_modwheel
                        self.last_modwheel = m_b2
                        # pitch value see from -8192 to 8191
                        self.virtual_pitchval += (diff_mod * 64)
                        if self.virtual_pitchval > 8191: self.virtual_pitchval = 8191
                        if self.virtual_pitchval < -8192: self.virtual_pitchval = -8192
                        ev = alsamidi.pitchbendevent(tx_ch, self.virtual_pitchval)
                        if self.verbose & 4:
                            print('made:')
                            print(ev)
                        fixed_ev = (13,0,0,253, (0,0), (0,0), (0,0), (0,0,0, 0,0, self.virtual_pitchval))
                        ev = fixed_ev
                        if self.verbose & 4:
                            print('fixed:')
                            print(ev)
                        #self.mDev.Write(ev) # send out as pitch wheel control
                        alsaseq.output(ev)
                        # put out a pitch wheel change based on mod wheel change
                        if self.verbose & 2:
                            pr('Filter Mod-Wheel %d, to pitch %d bend' % (self.last_modwheel, self.virtual_pitchval))
                        return True # processed, filter out

                if self.pass_thru:
                    if self.verbose & 2:
                        desc = self.mDev.SummaryCC_Desc(m_b1, m_b2)
                        print('pass thru CC event:' + desc)
                    #self.mDev.WriteAlsaEvent(alsa_event)
                    alsaseq.outlast((tx_ch | 0x10, 0,0,0)) # modify first(channel)

        elif (m_b0 & 0xf0) == 0x90:
            if self.verbose & 2:
                print('ch:%d NoteOff:%d Vel:%d' % (rx_ch, m_b1, m_b2))
            self.mDev.Write([0x90 | tx_ch, m_b1, m_b2])
        elif (m_b0 & 0xf0) == 0x80:
            if self.verbose & 2:
                print('ch:%d NoteOn:%d Vel:%d' % (rx_ch, m_b1, m_b2))

            if MODWHEEL_BANKPROG_KEY_FEATURE:
                if self.last_modwheel > 100:
                # using top of modwheel to set program(12 choices)
                    if m_b2 != 0: # velocity: off (only do when key on)
                        self.key_select = m_b1 % 12 # C-B, 12 choices, any octave
                        self.ProgBankListSelect(self.key_select)
                    if self.verbose & 2:
                        pr('Filter Prog Key')
                    return True # processed, don't pass thru, filter

            if MODWHEEL_TO_PITCH_FEATURE:
                if self.virtual_pitchval != 0:
                    self.virtual_pitchval = 0 # reset it and send out
                    ev = alsamidi.pitchbendevent(tx_ch, self.virtual_pitchval)
                    #fixed_ev = (13,0,0,253, (0,0), (28,0), (130,0), (0,0,0, 0,0,0))
                    ev = fixed_ev
                    #self.mDev.Write(ev) # send out as pitch wheel control
                    self.mDev.WriteAlsaEvent(ev)
                    #alsaseq.output(ev)
                    # put out a pitch wheel change based on mod wheel change
                    if self.verbose & 2:
                        pr('RESET Filter Mod-Wheel %d, to pitch %d bend' % (self.last_modwheel, self.virtual_pitchval))

            if self.pass_thru:
                if self.verbose & 2:
                    print('pass thru noteon')
                alsaseq.outlast((tx_ch | 0x10, 0,0,0)) # modify first(channel)
        else:
            if self.verbose & 1:
                print('Unhandled event ch:%d Cmd:%d Vel:%d' % (rx_ch, m_b1, m_b2))
            if self.pass_thru:
                if self.verbose & 2:
                    print('pass thru event')
                #self.mDev.WriteAlsaEvent(alsa_event)
                #self.mDev.Write([0x80 | tx_ch, m_b1, m_b2])
                alsaseq.outlast((tx_ch | 0x10, 0,0,0)) # modify first(channel)
        return True # processed something