[chimera-dev] midi

Dougherty, Matthew T matthewd at bcm.edu
Mon Jan 30 18:10:52 PST 2017


here is some snippets.

I let the midi callback set the variables.  in a frame trigger callback I detect a new signal and execute the variables.


midi is the only viable method I can see for cross platform.  It is more open than USB and simpler.


        ########################################################################

        global DS1_msg

        DS1_msg = 0



        global midi_in, midi_out, midi_sysex, midi_sysex_done

        midi_in    = rtmidi.MidiIn()

        midi_out   = rtmidi.MidiOut()

        midi_ports = midi_out.get_ports()

        print midi_ports


        midi_sysex_done = False

        if midi_ports:

            print midi_ports

            midi_out.open_port(0)



            midi_in.open_port(0)

            midi_in.set_callback(self.midi_in_callback, data='DS1')


            sysex = [240, 0, 1, 97, 16, 7, 6, 0, 0, 247]

            midi_out.send_message(sysex)

            from DS1 import DS1_buttons

            for i in range(0,29):

                DS1_buttons[i]=0



    #####################################

    def midi_in_callback(self, event, data):


        global DS1_msg

        global midi_in, midi_out

        global midi_sysex, midi_sysex_done

        from DS1 import DS1_buttons


        msg     = event[0]

        midi_status = msg[0]

        midi_device = msg[1]

        midi_value  = msg[2]



        if midi_device == 54:

            midi_sysex_done = True



        DS1_msg     = event[0]


        # --- update Continous Controller Values

        if midi_status ==176:

            midi_sysex[midi_device] = midi_value


        # --- update Button Values

        if midi_status ==144:

            DS1_buttons[midi_device] = midi_value


    #####################################


# -*- coding: utf-8 -*-

###############################################################################

#---------1---------2---------3---------4---------5---------6---------7--------

###############################################################################

# National Center for Macromolecular Imaging

# Matthew Dougherty/matthewd at bcm.edu

###############################################################################


S3D_focal  = 0.5

DS1_buttons= {}



def DS1(midi_in, midi_out,msg):


    midi_status = msg[0]

    midi_device = msg[1]

    midi_value  = msg[2]

    #print 'DS1:',msg



    # --- FREEZE

    if midi_status ==144 and midi_device ==16:

        import chimera

        chimera.runCommand('freeze')

        print 'FREEZE'


    # --- reset default

    if midi_status ==144 and midi_device ==22:

        import chimera

        chimera.runCommand('reset default')

        print 'Reset Default'


    # --- update Continous Controller Values

    from UCP import midi_sysex

    if midi_status ==176:

        midi_sysex[midi_device] = midi_value


    # --- update Button Values

    if midi_status ==144:

        DS1_buttons[midi_device] = midi_value




    # --- toggle Layout

    if midi_status ==144 and midi_device ==21:

        from UCP import selfHID



        if midi_value == 0:

           selfHID.L1()


        if midi_value == 127:

           selfHID.L2()



    # --- toggle S3D

    if midi_status ==144 and midi_device ==18:

        from UCP import selfHID

        selfHID.S3D()

        return


    # --- Volume Rendering

    if midi_status ==176 and (midi_device >=1 and midi_device <= 48):

        DS1_VR(midi_device, midi_value)

        return


    if midi_status ==144 and (midi_device >=0 and midi_device <= 15):

        DS1_VR(midi_device, midi_value)

        return


    # --- Camera

    if midi_status ==176 and (midi_device >=96 and midi_device <= 99):

        DS1_Camera(midi_device, midi_value)

        return


    if midi_status ==176 and (midi_device >=49 and midi_device <= 53):

        DS1_Camera(midi_device, midi_value)

        return


    if midi_status ==144 and (midi_device >=25 and midi_device <= 28):

        DS1_buttons[midi_device] = midi_value

        DS1_Camera(midi_device, midi_value)

        return


###############################################################################

def DS1_VR(d,v):



    if DS1_buttons[20]==127:

        return


    from VolumeViewer import active_volume

    v = active_volume()

    if v == None:

        return


    levels = getattr(v, "solid_levels")

    colors = getattr(v, "solid_colors")

    cnt    = len(colors)

    if cnt != 8:

        return


    #print d,v


    from UCP import midi_sysex



    sbf    = getattr(v, "solid_brightness_factor")

    td     = getattr(v, "transparency_depth")

    levels = getattr(v, "solid_levels")

    colors = getattr(v, "solid_colors")


    kw = {}

    kw["transparency_depth"]      = td

    kw["solid_brightness_factor"] = sbf


    s = v.matrix_value_statistics(read_matrix = False)

    rMax = s.maximum

    rMin = s.minimum


    j = 0

    for i in range(0,8):

        t,a         = levels[i]

        cr,cg,cb,ca = colors[i]


        cr = float(midi_sysex[1+j])/127.0

        cg = float(midi_sysex[2+j])/127.0

        cb = float(midi_sysex[3+j])/127.0

        ca = float(midi_sysex[4+j])/127.0

        a  = float(midi_sysex[41+i])/127.0


        # null transparency

        if DS1_buttons[i*2+1]==127:

            ca = 0

            a  = 0



        # lock density value

        if DS1_buttons[17]!=127:

            t = rMin+(rMax-rMin)*float(midi_sysex[5+j])/127.0



        print DS1_buttons[17],i,d

        if DS1_buttons[17]==127 and (i>0 and i<7):

            if (i+1)*5==d:

                t0,t         = levels[i-1]

                t1,t         = levels[i+1]

                t = t0+(t1-t0)*float(midi_sysex[d])/127.0

                print i,d,t0,t,t1



        if DS1_buttons[17]==127 and i==0:

            m,t = levels[1]

            t = rMin+(m-rMin)*float(midi_sysex[5+j])/127.0


        if DS1_buttons[17]==127 and i==7:

            m,t = levels[6]

            t = m + (rMax-m)*float(midi_sysex[5+j])/127.0



        levels[i] = (t,a)

        colors[i] = (cr,cg,cb,ca)

        j=j+5



    levelsOut=tuple(levels)

    kw["solid_levels"] = levelsOut

    colors[i-1] = (cr,cg,cb,ca)

    kw["solid_colors"] = colors

    v.set_parameters(**kw)

    v.show()




###############################################################################

def DS1_Camera(d,v):


    from UCP import selfHID

    from UCP import midi_sysex



    vScaled = float(v)/127.0

    from chimera import viewer

    cam = viewer.camera


    # --- Save Position

    if d==25 and v==127:

        selfHID.executeSavepos()

        return


    # --- Clipping Plane order of magnitude

    if d==50:

        f = float(midi_sysex[50])

        c = (f+0.1)**(f/60.0)-0.9

        print 'CP OM=', c



    # --- set select camera

    if d==96 and v==1:

        selfHID.executeKFinc()


    if d==96 and v==127:

        selfHID.executeKFdec()





    # --- set S3D focal plane

    if d==49:

        global S3D_focal

        S3D_focal = vScaled

        near, far = cam.nearFar

        cam.focal = near-(S3D_focal*(near-far))


     # --- set field of view

    if d==51:

        sdMax = 130.0

        sdMin = 0.1

        cam.fieldOfView = (sdMax-sdMin)*vScaled+sdMin



    # --- set S3D eye seperation

    if d==52:

        esMax=300

        esMin=0.1

        cam.eyeSeparation  = (esMax-esMin)*vScaled+esMin


    # --- set S3D screen distance

    if d==53:

        sdMax = 2000.0

        sdMin = 100.0

        cam.screenDistance = (sdMax-sdMin)*vScaled+sdMin



    # --- set near focal plane

    f = float(midi_sysex[50])

    c = (f+0.1)**(f/60.0)-0.9

    if d==98 and v==1:

        near, far = cam.nearFar

        near = near - c

        cam.nearFar = near, far


    if d==98 and v==127:

        near, far = cam.nearFar

        near = near + c

        cam.nearFar = near, far


    # --- set near focal plane

    if d==99 and v==1:

        near, far = cam.nearFar

        far = far - c

        cam.nearFar = near, far


    if d==99 and v==127:

        near, far = cam.nearFar

        far = far+ c

        cam.nearFar = near, far








Matthew Dougherty
National Center for Macromolecular Imaging
Baylor College of Medicine
=================================================
=================================================
________________________________
From: Tom Goddard <goddard at sonic.net>
Sent: Monday, January 30, 2017 8:00:51 PM
To: Dougherty, Matthew T
Cc: chimera-dev at cgl.ucsf.edu
Subject: Re: [chimera-dev] midi

***CAUTION:*** This email is not from a BCM Source. Only click links or open attachments you know are safe.
________________________________
Hi Matt,

  The RtMidi library looks like a good find.  I’ll be interested to hear how your testing goes.  Also I’d like to hear how difficult it is to include rtmidi in your tool.  We usually only ship third-party libraries that the Chimera core tools use — it is too difficult to compile and maintain them on all platforms.  Another issue is that all our development effort is on ChimeraX.

Tom


On Jan 28, 2017, at 11:47 AM, Dougherty, Matthew T  wrote:

Hi,

I got the midi interface working with chimera, thanks.  I ended up using the rtmidi package instead of mido.
https://pypi.python.org/pypi/python-rtmidi<https://urldefense.proofpoint.com/v2/url?u=https-3A__pypi.python.org_pypi_python-2Drtmidi&d=DwMFaQ&c=ZQs-KZ8oxEw0p81sqgiaRA&r=lEMX2_AJ6Iksc5dFd0-VOg&m=D2s5FN-a0IhX27WTzA4T7wVxJoMVaC7UwAgWcYwtHqM&s=sU4YDkPK3rVyfMNNljxFiK3Yrc6S921529ujMwqwcR8&e=>


Midi will significantly reduce my reliance on accelerators.  It will give me the ability to pass multivariate parameters from hardware and modify LED displays on those devices.   Previous efforts directly working with USB has be difficult because of lack of compliance and limited open source methods.


The software I developed allows the DS1 control surface to easily control volume rendering and stereographics.
http://lividinstruments.com/products/ds1/<https://urldefense.proofpoint.com/v2/url?u=http-3A__lividinstruments.com_products_ds1_&d=DwMFaQ&c=ZQs-KZ8oxEw0p81sqgiaRA&r=lEMX2_AJ6Iksc5dFd0-VOg&m=D2s5FN-a0IhX27WTzA4T7wVxJoMVaC7UwAgWcYwtHqM&s=znUNVAMdLozE-1DIKMbrlrDReCP0Qr7QYpzObLdpP5s&e=>

I am anticipating this will improve operational viz for tomograms.  If users demonstrate value in device, will release as an chimera extension.  Internal NCMI testing begins next week.

Also looking at other inexpensive midi devices.

Recommending chimera ship with rtmidi library.

thanks,


Matthew Dougherty
National Center for Macromolecular Imaging
Baylor College of Medicine
=================================================
=================================================
_______________________________________________
Chimera-dev mailing list
Chimera-dev at cgl.ucsf.edu<mailto:Chimera-dev at cgl.ucsf.edu>
http://www.rbvi.ucsf.edu/mailman/listinfo/chimera-dev<https://urldefense.proofpoint.com/v2/url?u=http-3A__plato.cgl.ucsf.edu_mailman_listinfo_chimera-2Ddev&d=DwMFaQ&c=ZQs-KZ8oxEw0p81sqgiaRA&r=lEMX2_AJ6Iksc5dFd0-VOg&m=D2s5FN-a0IhX27WTzA4T7wVxJoMVaC7UwAgWcYwtHqM&s=F5OTntuRw1fKYlzDhQ4C0mt2ahkwt3oZD7OgxeL8d6A&e=>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://plato.cgl.ucsf.edu/pipermail/chimera-dev/attachments/20170131/cc11735b/attachment.html>


More information about the Chimera-dev mailing list