Old 11-29-2017, 05:58 PM   #1
Flaneurette
Human being with feelings
 
Join Date: Dec 2016
Posts: 373
Default A few MIDI scripts

Maybe useful for those who want to work with raw MIDI inside Python. I originally wrote these scripts for ReaScore, an unreleased Python score notation app.

It is collection of python files I wrote to control MIDI and MIDI devices through Reaper. It also has a small library to read and write MIDI files inside Python.

If you wonder how to connect MIDI devices, enumerate them on Windows, then this might be helpful, because there is little information on this.

Download: https://stash.reaper.fm/32364/MIDI.zip


windll.winmm MIDI CAPS example, to enumerate the connected MIDI devices on Windows:

Code:
    def devices(self,method):

        devicelist = []

        '''
        caps.wMid,
        caps.wPid,
        caps.vDriverVersion,
        caps.wVoices,
        caps.wNotes,
        caps.wChannel_mask,
        caps.dwSupport
        '''

        if method == 'in':

            dev = self.lib.midiInGetNumDevs()
            try:
                caps = MIDIINCAPS()
                for i in range(0,dev):
                    out = self.lib.midiInGetDevCapsA(i,byref(caps),ctypes.sizeof(caps))
                    name = ctypes.string_at(ctypes.cast(caps.szPname, c_char_p))
                    devicelist.extend([
                    name.decode(encoding="utf-8")
                    ])

            except (RuntimeError, NameError, TypeError, AttributeError):
                pass
        else:

            dev = self.lib.midiOutGetNumDevs()
            try:
                caps = MIDIOUTCAPS()
                for i in range(-1,dev):
                    out = self.lib.midiOutGetDevCapsA(i,byref(caps),ctypes.sizeof(caps))
                    name = ctypes.string_at(ctypes.cast(caps.szPname, c_char_p))
                    devicelist.extend([
                    name.decode(encoding="utf-8")
                    ])

            except (RuntimeError, NameError, TypeError, AttributeError):
                pass

        return devicelist

Code:
from ctypes import WINFUNCTYPE, wintypes, c_long, c_char_p, byref
from ctypes.wintypes import *

MIDI_CALLBACK_FUNCTION = 196608

WNDPROC = WINFUNCTYPE(None, c_long, UINT, DWORD, DWORD, DWORD)

class MIDIINCAPS(ctypes.Structure):

    _fields_ = [
        ('wMid', WORD),
        ('wPid', WORD),
        ('vDriverVersion', UINT),
        ('szPname', BYTE * 64),
        ('dwSupport', DWORD),
    ]

class MIDIOUTCAPS(ctypes.Structure):

    _fields_ = [

        ('wMid', WORD),
        ('wPid', WORD),
        ('vDriverVersion', UINT),
        ('szPname', BYTE * 64),
        ('wTechnology', WORD),
        ('wVoices', WORD),
        ('wNotes', WORD),
        ('wChannel_mask', WORD),
        ('dwSupport', DWORD),
    ]

    device_type = [

        'NONE',
        'MOD_MIDIPORT',     # MIDI hardware port.
        'MOD_SYNTH',        # Synthesizer.
        'MOD_SQSYNTH',      # Square wave synthesizer.
        'MOD_FMSYNTH',      # FM synthesizer
        'MOD_MAPPER',       # Microsoft MIDI mapper.
        'MOD_WAVETABLE',    # Hardware wavetable synthesizer.
        'MOD_SWSYNTH',      # Software synthesizer.
        'NONE',
    ]

Last edited by Flaneurette; 11-29-2017 at 06:23 PM.
Flaneurette is offline   Reply With Quote
Old 12-04-2017, 07:22 PM   #2
Time Waster
Human being with feelings
 
Time Waster's Avatar
 
Join Date: Aug 2013
Location: Bowral, Australia
Posts: 1,643
Default

Thanks Flaneurette, I've been trying to learn python, so this might give me some clues.
__________________
Mal, aka The Wasters of Time
Mal's JSFX: ReaRack2 Modular Synth
Time Waster is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -7. The time now is 01:23 PM.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.