From b8414f8e8fda18390e038b529806c46e3d07d121 Mon Sep 17 00:00:00 2001 From: BlitzCityDIY Date: Fri, 29 Jul 2022 11:59:53 -0400 Subject: [PATCH] Adding code for MIDI to CV guide Adding code for the MIDI to CV learn guide. Takes in MIDI messages over USB and outputs gate and 1V/oct. volts.py is a helper file for comparing MIDI note numbers and 1V/oct values --- MIDI_to_CV_Skull/code.py | 77 +++++++++++++++++++++++++++++++++++++++ MIDI_to_CV_Skull/volts.py | 68 ++++++++++++++++++++++++++++++++++ 2 files changed, 145 insertions(+) create mode 100644 MIDI_to_CV_Skull/code.py create mode 100644 MIDI_to_CV_Skull/volts.py diff --git a/MIDI_to_CV_Skull/code.py b/MIDI_to_CV_Skull/code.py new file mode 100644 index 000000000..e6257c2a2 --- /dev/null +++ b/MIDI_to_CV_Skull/code.py @@ -0,0 +1,77 @@ +# SPDX-FileCopyrightText: 2022 Liz Clark for Adafruit Industries +# SPDX-License-Identifier: MIT + +import board +import simpleio +import adafruit_mcp4725 +import usb_midi +import adafruit_midi +from digitalio import DigitalInOut, Direction +from adafruit_midi.note_off import NoteOff +from adafruit_midi.note_on import NoteOn +from volts import volts + +# midi channel setup +midi_in_channel = 1 +midi_out_channel = 1 + +# USB midi setup +midi = adafruit_midi.MIDI( + midi_in=usb_midi.ports[0], in_channel=0, midi_out=usb_midi.ports[1], out_channel=0 +) + +# gate output pin +gate = DigitalInOut(board.A1) +gate.direction = Direction.OUTPUT + +# i2c setup +i2c = board.I2C() +# dac setup over i2c +dac = adafruit_mcp4725.MCP4725(i2c) + +# dac raw value (12 bit) +dac.raw_value = 4095 + +# array for midi note numbers +midi_notes = [] +# array for 12 bit 1v/oct values +pitches = [] + +# function to map 1v/oct voltages to 12 bit values +# these values are added to the pitches[] array +def map_volts(n, volt, vref, bits): + n = simpleio.map_range(volt, 0, vref, 0, bits) + pitches.append(n) + +# brings values from volts.py into individual arrays +for v in volts: + # map_volts function to map 1v/oct values to 12 bit + # and append to pitches[] + map_volts(v['label'], v['1vOct'], 5, 4095) + # append midi note numbers to midi_notes[] array + midi_notes.append(v['midi']) + +while True: + # read incoming midi messages + msg = midi.receive() + # if a midi msg comes in... + if msg is not None: + # if it's noteoff... + if isinstance(msg, NoteOff): + # send 0 volts on dac + dac.raw_value = 0 + # turn off gate pin + gate.value = False + # if it's noteon... + if isinstance(msg, NoteOn): + # compare incoming note number to midi_notes[] + z = midi_notes.index(msg.note) + # limit note range to defined notes in volts.py + if msg.note < 36: + msg.note = 36 + if msg.note > 96: + msg.note = 96 + # send corresponding 1v/oct value + dac.raw_value = int(pitches[z]) + # turn on gate pin + gate.value = True diff --git a/MIDI_to_CV_Skull/volts.py b/MIDI_to_CV_Skull/volts.py new file mode 100644 index 000000000..fe0f0725a --- /dev/null +++ b/MIDI_to_CV_Skull/volts.py @@ -0,0 +1,68 @@ +# SPDX-FileCopyrightText: 2022 Liz Clark for Adafruit Industries +# SPDX-License-Identifier: MIT + +# Helper file for MIDI note number to 1V/oct voltage + +volts = [ + {'label':"C-2",'midi':36,'1vOct':0.000}, + {'label':"C♯2",'midi':37,'1vOct':0.083}, + {'label':"D-2",'midi':38,'1vOct':0.167}, + {'label':"D♯2",'midi':39,'1vOct':0.250}, + {'label':"E-2",'midi':40,'1vOct':0.333}, + {'label':"F-2",'midi':41,'1vOct':0.417}, + {'label':"F♯2",'midi':42,'1vOct':0.500}, + {'label':"G-2",'midi':43,'1vOct':0.583}, + {'label':"G♯2",'midi':44,'1vOct':0.667}, + {'label':"A-2",'midi':45,'1vOct':0.750}, + {'label':"A♯2",'midi':46,'1vOct':0.833}, + {'label':"B-2",'midi':47,'1vOct':0.917}, + {'label':"C-3",'midi':48,'1vOct':1.000}, + {'label':"C♯3",'midi':49,'1vOct':1.083}, + {'label':"D-3",'midi':50,'1vOct':1.167}, + {'label':"D♯3",'midi':51,'1vOct':1.250}, + {'label':"E-3",'midi':52,'1vOct':1.333}, + {'label':"F-3",'midi':53,'1vOct':1.417}, + {'label':"F♯3",'midi':54,'1vOct':1.500}, + {'label':"G-3",'midi':55,'1vOct':1.583}, + {'label':"G♯3",'midi':56,'1vOct':1.667}, + {'label':"A-3",'midi':57,'1vOct':1.750}, + {'label':"A♯3",'midi':58,'1vOct':1.833}, + {'label':"B-3",'midi':59,'1vOct':1.917}, + {'label':"C-4",'midi':60,'1vOct':2.000}, + {'label':"C♯4",'midi':61,'1vOct':2.083}, + {'label':"D-4",'midi':62,'1vOct':2.167}, + {'label':"D♯4",'midi':63,'1vOct':2.250}, + {'label':"E-4",'midi':64,'1vOct':2.333}, + {'label':"F-4",'midi':65,'1vOct':2.417}, + {'label':"F♯4",'midi':66,'1vOct':2.500}, + {'label':"G-4",'midi':67,'1vOct':2.583}, + {'label':"G♯4",'midi':68,'1vOct':2.667}, + {'label':"A-4",'midi':69,'1vOct':2.750}, + {'label':"A♯4",'midi':70,'1vOct':2.833}, + {'label':"B-4",'midi':71,'1vOct':2.917}, + {'label':"C-5",'midi':72,'1vOct':3.000}, + {'label':"C♯5",'midi':73,'1vOct':3.083}, + {'label':"D-5",'midi':74,'1vOct':3.167}, + {'label':"D♯5",'midi':75,'1vOct':3.250}, + {'label':"E-5",'midi':76,'1vOct':3.333}, + {'label':"F-5",'midi':77,'1vOct':3.417}, + {'label':"F♯5",'midi':78,'1vOct':3.500}, + {'label':"G-5",'midi':79,'1vOct':3.583}, + {'label':"G♯5",'midi':80,'1vOct':3.667}, + {'label':"A-5",'midi':81,'1vOct':3.750}, + {'label':"A♯5",'midi':82,'1vOct':3.833}, + {'label':"B-5",'midi':83,'1vOct':3.917}, + {'label':"C-6",'midi':84,'1vOct':4.000}, + {'label':"C♯6",'midi':85,'1vOct':4.083}, + {'label':"D-6",'midi':86,'1vOct':4.167}, + {'label':"D♯6",'midi':87,'1vOct':4.250}, + {'label':"E-6",'midi':88,'1vOct':4.333}, + {'label':"F-6",'midi':89,'1vOct':4.417}, + {'label':"F♯6",'midi':90,'1vOct':4.500}, + {'label':"G-6",'midi':91,'1vOct':4.583}, + {'label':"G♯6",'midi':92,'1vOct':4.667}, + {'label':"A-6",'midi':93,'1vOct':4.750}, + {'label':"A♯6",'midi':94,'1vOct':4.833}, + {'label':"B-6",'midi':95,'1vOct':4.917}, + {'label':"C-7",'midi':96,'1vOct':5.000}, +]