daily_automated
This commit is contained in:
114
trunk/Arduino/libraries/MIDI_Library/res/validator/midi.py
Normal file
114
trunk/Arduino/libraries/MIDI_Library/res/validator/midi.py
Normal file
@@ -0,0 +1,114 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import rtmidi
|
||||
import random
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
class Midi:
|
||||
InvalidType = 0x00 # For notifying errors
|
||||
NoteOff = 0x80 # Note Off
|
||||
NoteOn = 0x90 # Note On
|
||||
AfterTouchPoly = 0xA0 # Polyphonic AfterTouch
|
||||
ControlChange = 0xB0 # Control Change / Channel Mode
|
||||
ProgramChange = 0xC0 # Program Change
|
||||
AfterTouchChannel = 0xD0 # Channel (monophonic) AfterTouch
|
||||
PitchBend = 0xE0 # Pitch Bend
|
||||
SystemExclusive = 0xF0 # System Exclusive
|
||||
TimeCodeQuarterFrame = 0xF1 # System Common - MIDI Time Code Quarter Frame
|
||||
SongPosition = 0xF2 # System Common - Song Position Pointer
|
||||
SongSelect = 0xF3 # System Common - Song Select
|
||||
TuneRequest = 0xF6 # System Common - Tune Request
|
||||
Clock = 0xF8 # System Real Time - Timing Clock
|
||||
Start = 0xFA # System Real Time - Start
|
||||
Continue = 0xFB # System Real Time - Continue
|
||||
Stop = 0xFC # System Real Time - Stop
|
||||
ActiveSensing = 0xFE # System Real Time - Active Sensing
|
||||
SystemReset = 0xFF # System Real Time - System Reset
|
||||
|
||||
@staticmethod
|
||||
def getChannel(statusByte):
|
||||
return statusByte & 0x0f;
|
||||
|
||||
@staticmethod
|
||||
def getType(statusByte):
|
||||
if statusByte >= 0xf0:
|
||||
# System messages
|
||||
return statusByte
|
||||
else:
|
||||
# Channel messages
|
||||
return statusByte & 0xf0;
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
class MidiInterface:
|
||||
def __init__(self, listenerCallback = None):
|
||||
self.input = rtmidi.MidiIn()
|
||||
self.output = rtmidi.MidiOut()
|
||||
self.listenerCallback = listenerCallback
|
||||
self.ports = self.getAvailablePorts()
|
||||
self.port = self.connect(self.choosePorts())
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
def handleMidiInput(self, message, timestamp):
|
||||
midiData = message[0]
|
||||
if self.listenerCallback:
|
||||
self.listenerCallback(midiData)
|
||||
|
||||
def send(self, message):
|
||||
print('Sending', message)
|
||||
self.output.send_message(message)
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
def getAvailablePorts(self):
|
||||
return {
|
||||
'input' : self.input.get_ports(),
|
||||
'output': self.output.get_ports(),
|
||||
}
|
||||
|
||||
def choosePorts(self):
|
||||
return {
|
||||
'input' : self.choosePort(self.ports['input'], 'input'),
|
||||
'output': self.choosePort(self.ports['output'], 'output')
|
||||
}
|
||||
|
||||
def choosePort(self, ports, direction):
|
||||
if not ports:
|
||||
print('No MIDI ports available, bailing out.')
|
||||
return None
|
||||
|
||||
if len(ports) == 1:
|
||||
return {
|
||||
'id': 0,
|
||||
'name': ports[0]
|
||||
}
|
||||
|
||||
else:
|
||||
# Give a choice
|
||||
print('Multiple %s ports available, please make a choice:' % direction)
|
||||
choices = dict()
|
||||
for port, i in zip(ports, range(0, len(ports))):
|
||||
choices[i] = port
|
||||
print(' [%d]' % i, port)
|
||||
choiceIndex = int(input('-> '))
|
||||
return {
|
||||
'id': choiceIndex,
|
||||
'name': choices[choiceIndex]
|
||||
}
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
def connect(self, ports):
|
||||
if not ports:
|
||||
return None
|
||||
|
||||
print('Connecting input to %s' % ports['input']['name'])
|
||||
print('Connecting output to %s' % ports['output']['name'])
|
||||
|
||||
self.input.set_callback(self.handleMidiInput)
|
||||
self.input.open_port(ports['input']['id'])
|
||||
self.output.open_port(ports['output']['id'])
|
||||
return ports
|
||||
24
trunk/Arduino/libraries/MIDI_Library/res/validator/tester.py
Normal file
24
trunk/Arduino/libraries/MIDI_Library/res/validator/tester.py
Normal file
@@ -0,0 +1,24 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
class Tester:
|
||||
def __init__(self, interface):
|
||||
self.interface = interface
|
||||
self.sent = None
|
||||
self.expected = None
|
||||
self.received = None
|
||||
|
||||
def handleMidiInput(self, data):
|
||||
print('Recived data:', data)
|
||||
self.received = data
|
||||
|
||||
def checkThru(self, message):
|
||||
self.interface.send(message)
|
||||
self.sent = message
|
||||
self.expected = message
|
||||
self.received = None
|
||||
while not self.received:
|
||||
pass
|
||||
return self.expected == self.received
|
||||
182
trunk/Arduino/libraries/MIDI_Library/res/validator/validate.py
Normal file
182
trunk/Arduino/libraries/MIDI_Library/res/validator/validate.py
Normal file
@@ -0,0 +1,182 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import sys
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
import argparse
|
||||
from pprint import pprint
|
||||
from midi import *
|
||||
from tester import *
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
rootDir = os.path.abspath(os.path.join(os.path.dirname(os.path.realpath(__file__)), '../..'))
|
||||
logsDir = os.path.join(rootDir, 'logs')
|
||||
resDir = os.path.join(rootDir, 'res')
|
||||
srcDir = os.path.join(rootDir, 'src')
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
class Dict(dict):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.__dict__ = self
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
class Arduino:
|
||||
if sys.platform == 'darwin':
|
||||
binary = '/Applications/Arduino.app/Contents/MacOS/JavaApplicationStub'
|
||||
home = os.path.expanduser('~/Documents/Arduino')
|
||||
elif sys.platform == 'win32':
|
||||
binary = 'arduino.exe'
|
||||
home = os.path.expanduser('~/My Documents/Arduino')
|
||||
elif sys.platform == 'linux':
|
||||
binary = 'arduino'
|
||||
home = os.path.expanduser('~/Arduino')
|
||||
else:
|
||||
print('Unsupported platform %s' % str(sys.platform))
|
||||
sys.exit(1)
|
||||
|
||||
libraryDir = os.path.join(home, 'libraries')
|
||||
|
||||
boards = [
|
||||
Dict({
|
||||
'name': 'Uno',
|
||||
'id': 'arduino:avr:uno',
|
||||
'port': None,
|
||||
}),
|
||||
Dict({
|
||||
'name': 'Leonardo',
|
||||
'id': 'arduino:avr:leonardo',
|
||||
'port': None,
|
||||
}),
|
||||
Dict({
|
||||
'name': 'Mega',
|
||||
'id': 'arduino:avr:mega',
|
||||
'port': None,
|
||||
}),
|
||||
Dict({
|
||||
'name': 'Due',
|
||||
'id': 'arduino:sam:due',
|
||||
'port': None,
|
||||
}),
|
||||
]
|
||||
|
||||
def checkReturnCode(code):
|
||||
if code == 0:
|
||||
return True
|
||||
if code == 1:
|
||||
print('Operation failed.')
|
||||
if code == 2:
|
||||
print('File not found')
|
||||
if code == 3:
|
||||
print('Invalid argument')
|
||||
return False
|
||||
|
||||
def verify(sketch, boardId):
|
||||
return Arduino.checkReturnCode(subprocess.call([
|
||||
Arduino.binary,
|
||||
'--verify', sketch,
|
||||
'--board', boardId,
|
||||
'--verbose-build',
|
||||
]))
|
||||
#], stdout = open(os.devnull, 'wb')))
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
class ArduinoMidiLibrary:
|
||||
def __init__(self):
|
||||
self.path = os.path.join(Arduino.libraryDir, 'MIDI')
|
||||
self.sources = self.getSources()
|
||||
self.resources = self.getResources()
|
||||
|
||||
def getSources(self):
|
||||
sources = dict()
|
||||
for root, dirs, files in os.walk(srcDir):
|
||||
for name, ext in [os.path.splitext(f) for f in files]:
|
||||
if ext in ('.cpp', '.hpp', '.h'):
|
||||
source = os.path.join(root, name + ext)
|
||||
dest = os.path.join(self.path, os.path.relpath(source, srcDir))
|
||||
sources[source] = dest
|
||||
return sources
|
||||
|
||||
def getResources(self):
|
||||
return {
|
||||
os.path.join(resDir, 'keywords.txt'): os.path.join(self.path, 'keywords.txt'),
|
||||
os.path.join(resDir, 'examples/'): os.path.join(self.path, 'examples/'),
|
||||
}
|
||||
|
||||
def install(self):
|
||||
payloads = dict(list(self.sources.items()) + list(self.resources.items()))
|
||||
for s,d in payloads.items():
|
||||
if not os.path.exists(os.path.dirname(d)):
|
||||
os.makedirs(os.path.dirname(d))
|
||||
if os.path.isfile(s):
|
||||
shutil.copy2(s, d)
|
||||
elif os.path.isdir(s):
|
||||
if os.path.exists(d):
|
||||
shutil.rmtree(d)
|
||||
shutil.copytree(s, d)
|
||||
|
||||
def getInstalledExamples(self):
|
||||
exDir = os.path.join(self.path, 'examples')
|
||||
return [os.path.join(exDir, x, x + '.ino') for x in next(os.walk(exDir))[1]]
|
||||
|
||||
def validate(self):
|
||||
for board in Arduino.boards:
|
||||
# Validate examples
|
||||
print('Validation for Arduino %s' % board.name)
|
||||
for example in self.getInstalledExamples():
|
||||
if not Arduino.verify(example, board.id):
|
||||
print('{0:40} {1}'.format(os.path.basename(example), 'FAILED'))
|
||||
return False
|
||||
else:
|
||||
print('{0:40} {1}'.format(os.path.basename(example), 'PASSED'))
|
||||
return True
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
def main():
|
||||
|
||||
info = "Validator script for the Arduino MIDI Library."
|
||||
arg_parser = argparse.ArgumentParser(description = info)
|
||||
|
||||
arg_parser.add_argument('--compile', '-c',
|
||||
action="store_true",
|
||||
help="Test compilation of the example sketches")
|
||||
|
||||
arg_parser.add_argument('--runtime', '-r',
|
||||
action="store_true",
|
||||
help="Test runtime")
|
||||
|
||||
args = arg_parser.parse_args()
|
||||
|
||||
if args.compile:
|
||||
lib = ArduinoMidiLibrary()
|
||||
lib.install()
|
||||
if lib.validate():
|
||||
print('Compilation test passed')
|
||||
else:
|
||||
print('Compilation test failed')
|
||||
|
||||
if args.runtime:
|
||||
midiInterface = MidiInterface()
|
||||
tester = Tester(midiInterface)
|
||||
midiInterface.listenerCallback = tester.handleMidiInput
|
||||
|
||||
tester.checkThru([Midi.NoteOn, 64, 80])
|
||||
tester.checkThru([Midi.AfterTouchChannel, 1])
|
||||
tester.checkThru([2])
|
||||
tester.checkThru([3])
|
||||
tester.checkThru([Midi.NoteOn, 64, 0])
|
||||
tester.checkThru([65, 127])
|
||||
tester.checkThru([65, 0])
|
||||
tester.checkThru([66, 127])
|
||||
tester.checkThru([66, 0])
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Reference in New Issue
Block a user