def test_good_text(self): note_prefix = { "Cb": 11, "C": 12, "C#": 13, "Db": 13, "D": 14, "D#": 15, "Eb": 15, "E": 16, "Fb": 16, "E#": 17, "F": 17, "F#": 18, "Gb": 18, "G": 19, "G#": 20, "Ab": 20, "A": 21, "A#": 22, "Bb": 22, "B": 23, "B#": 24, } # test from Cb0 to B#8 for prefix, base_value in note_prefix.items(): for octave in range(9): note = prefix + str(octave) expected_value = base_value + octave * 12 # 12 semitones in octave self.assertEqual(note_parser(note), expected_value) # re-test with simple C4/A4 tests to catch any bugs in above self.assertEqual(note_parser("C4"), 60) self.assertEqual(note_parser("A4"), 69)
def text_int_passthru(self): self.assertEqual(note_parser(0), 0) self.assertEqual(note_parser(70), 70) self.assertEqual(note_parser(127), 127) # it does not range check so these should pass self.assertEqual(note_parser(-303), -303) self.assertEqual(note_parser(808), 808)
from adafruit_midi.note_off import NoteOff from adafruit_midi.control_change import ControlChange from adafruit_midi.pitch_bend import PitchBend # Turn the speaker on speaker_enable = digitalio.DigitalInOut(board.SPEAKER_ENABLE) speaker_enable.direction = digitalio.Direction.OUTPUT speaker_on = True speaker_enable.value = speaker_on dac = audioio.AudioOut(board.SPEAKER) # 440Hz is the standard frequency for A4 (A above middle C) # MIDI defines middle C as 60 and modulation wheel is cc 1 by convention A4refhz = 440 # was const(440) midi_note_C4 = note_parser("C4") midi_note_A4 = note_parser("A4") midi_cc_modwheel = 1 # was const(1) twopi = 2 * math.pi # A length of 12 will make the sawtooth rather steppy sample_len = 12 base_sample_rate = A4refhz * sample_len max_sample_rate = 350000 # a CPX / M0 DAC limitation midpoint = 32768 # A sawtooth function like math.sin(angle) # 0 returns 1.0, pi returns 0.0, 2*pi returns -1.0 def sawtooth(angle):
def test_bad_text(self): for text_note in ["H", "H4", "asdfasdfasdf", "000", "999"]: with self.assertRaises(ValueError): note_parser(text_note)
from adafruit_midi.pitch_bend import PitchBend from adafruit_midi.program_change import ProgramChange ### TODO - deal with max sample playback rate of 350000 ### TODO - add control over this ### and work out what's going on at 97-98 speaker_enable = digitalio.DigitalInOut(board.SPEAKER_ENABLE) speaker_enable.direction = digitalio.Direction.OUTPUT speaker_enable.value = True dac = audioio.AudioOut(board.SPEAKER) ### TO RESEARCH - is const more memory efficient? A4refhz = const(440) midinoteC4 = note_parser("C4") midinoteA4 = note_parser("A4") ### TODO - review this - way too fragile with MemoryError problems basesamplerate = 42240 ### this makes A4 exactly 96 samples (440*96) wavename = "square" wavenames = [ "square", "sawtooth", "supersaw", "supersupersaw", "sine", "sineoct2", "sinefifth" ] ## removed "sinemajorchord" for now ### brightness 1.0 saves memory by removing need for a second buffer ### 10 is number of NeoPixels on numpixels = const(10) ### brightness of 1.0 prevents an extra array from being created
from adafruit_bluefruit_connect.color_packet import ColorPacket from adafruit_ble import BLERadio from adafruit_ble.advertising.standard import ProvideServicesAdvertisement from adafruit_ble.services.nordic import UARTService from adafruit_midi.midi_message import note_parser from adafruit_midi.note_on import NoteOn from adafruit_midi.note_off import NoteOff # brightness 1.0 saves memory by removing need for a second buffer # 10 is number of NeoPixels on CPX numpixels = 10 # was const(10) pixels = neopixel.NeoPixel(board.NEOPIXEL, numpixels, brightness=1.0) midi_note_C4 = note_parser("C4") # Turn NeoPixel on to represent a note using RGB x 10 # to represent 30 notes - doesn't do anything with pitch bend def noteLED(pix, pnote, pvel): note30 = (pnote - midi_note_C4) % (3 * numpixels) pos = note30 % numpixels r, g, b = pix[pos] if pvel == 0: brightness = 0 else: # max brightness will be 32 brightness = round(pvel / 127 * 30 + 2) # Pick R/G/B based on range within the 30 notes if note30 < 10: