Skip to content

Commit b8414f8

Browse files
committed
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
1 parent 2c1ef09 commit b8414f8

File tree

2 files changed

+145
-0
lines changed

2 files changed

+145
-0
lines changed

MIDI_to_CV_Skull/code.py

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
# SPDX-FileCopyrightText: 2022 Liz Clark for Adafruit Industries
2+
# SPDX-License-Identifier: MIT
3+
4+
import board
5+
import simpleio
6+
import adafruit_mcp4725
7+
import usb_midi
8+
import adafruit_midi
9+
from digitalio import DigitalInOut, Direction
10+
from adafruit_midi.note_off import NoteOff
11+
from adafruit_midi.note_on import NoteOn
12+
from volts import volts
13+
14+
# midi channel setup
15+
midi_in_channel = 1
16+
midi_out_channel = 1
17+
18+
# USB midi setup
19+
midi = adafruit_midi.MIDI(
20+
midi_in=usb_midi.ports[0], in_channel=0, midi_out=usb_midi.ports[1], out_channel=0
21+
)
22+
23+
# gate output pin
24+
gate = DigitalInOut(board.A1)
25+
gate.direction = Direction.OUTPUT
26+
27+
# i2c setup
28+
i2c = board.I2C()
29+
# dac setup over i2c
30+
dac = adafruit_mcp4725.MCP4725(i2c)
31+
32+
# dac raw value (12 bit)
33+
dac.raw_value = 4095
34+
35+
# array for midi note numbers
36+
midi_notes = []
37+
# array for 12 bit 1v/oct values
38+
pitches = []
39+
40+
# function to map 1v/oct voltages to 12 bit values
41+
# these values are added to the pitches[] array
42+
def map_volts(n, volt, vref, bits):
43+
n = simpleio.map_range(volt, 0, vref, 0, bits)
44+
pitches.append(n)
45+
46+
# brings values from volts.py into individual arrays
47+
for v in volts:
48+
# map_volts function to map 1v/oct values to 12 bit
49+
# and append to pitches[]
50+
map_volts(v['label'], v['1vOct'], 5, 4095)
51+
# append midi note numbers to midi_notes[] array
52+
midi_notes.append(v['midi'])
53+
54+
while True:
55+
# read incoming midi messages
56+
msg = midi.receive()
57+
# if a midi msg comes in...
58+
if msg is not None:
59+
# if it's noteoff...
60+
if isinstance(msg, NoteOff):
61+
# send 0 volts on dac
62+
dac.raw_value = 0
63+
# turn off gate pin
64+
gate.value = False
65+
# if it's noteon...
66+
if isinstance(msg, NoteOn):
67+
# compare incoming note number to midi_notes[]
68+
z = midi_notes.index(msg.note)
69+
# limit note range to defined notes in volts.py
70+
if msg.note < 36:
71+
msg.note = 36
72+
if msg.note > 96:
73+
msg.note = 96
74+
# send corresponding 1v/oct value
75+
dac.raw_value = int(pitches[z])
76+
# turn on gate pin
77+
gate.value = True

MIDI_to_CV_Skull/volts.py

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# SPDX-FileCopyrightText: 2022 Liz Clark for Adafruit Industries
2+
# SPDX-License-Identifier: MIT
3+
4+
# Helper file for MIDI note number to 1V/oct voltage
5+
6+
volts = [
7+
{'label':"C-2",'midi':36,'1vOct':0.000},
8+
{'label':"C♯2",'midi':37,'1vOct':0.083},
9+
{'label':"D-2",'midi':38,'1vOct':0.167},
10+
{'label':"D♯2",'midi':39,'1vOct':0.250},
11+
{'label':"E-2",'midi':40,'1vOct':0.333},
12+
{'label':"F-2",'midi':41,'1vOct':0.417},
13+
{'label':"F♯2",'midi':42,'1vOct':0.500},
14+
{'label':"G-2",'midi':43,'1vOct':0.583},
15+
{'label':"G♯2",'midi':44,'1vOct':0.667},
16+
{'label':"A-2",'midi':45,'1vOct':0.750},
17+
{'label':"A♯2",'midi':46,'1vOct':0.833},
18+
{'label':"B-2",'midi':47,'1vOct':0.917},
19+
{'label':"C-3",'midi':48,'1vOct':1.000},
20+
{'label':"C♯3",'midi':49,'1vOct':1.083},
21+
{'label':"D-3",'midi':50,'1vOct':1.167},
22+
{'label':"D♯3",'midi':51,'1vOct':1.250},
23+
{'label':"E-3",'midi':52,'1vOct':1.333},
24+
{'label':"F-3",'midi':53,'1vOct':1.417},
25+
{'label':"F♯3",'midi':54,'1vOct':1.500},
26+
{'label':"G-3",'midi':55,'1vOct':1.583},
27+
{'label':"G♯3",'midi':56,'1vOct':1.667},
28+
{'label':"A-3",'midi':57,'1vOct':1.750},
29+
{'label':"A♯3",'midi':58,'1vOct':1.833},
30+
{'label':"B-3",'midi':59,'1vOct':1.917},
31+
{'label':"C-4",'midi':60,'1vOct':2.000},
32+
{'label':"C♯4",'midi':61,'1vOct':2.083},
33+
{'label':"D-4",'midi':62,'1vOct':2.167},
34+
{'label':"D♯4",'midi':63,'1vOct':2.250},
35+
{'label':"E-4",'midi':64,'1vOct':2.333},
36+
{'label':"F-4",'midi':65,'1vOct':2.417},
37+
{'label':"F♯4",'midi':66,'1vOct':2.500},
38+
{'label':"G-4",'midi':67,'1vOct':2.583},
39+
{'label':"G♯4",'midi':68,'1vOct':2.667},
40+
{'label':"A-4",'midi':69,'1vOct':2.750},
41+
{'label':"A♯4",'midi':70,'1vOct':2.833},
42+
{'label':"B-4",'midi':71,'1vOct':2.917},
43+
{'label':"C-5",'midi':72,'1vOct':3.000},
44+
{'label':"C♯5",'midi':73,'1vOct':3.083},
45+
{'label':"D-5",'midi':74,'1vOct':3.167},
46+
{'label':"D♯5",'midi':75,'1vOct':3.250},
47+
{'label':"E-5",'midi':76,'1vOct':3.333},
48+
{'label':"F-5",'midi':77,'1vOct':3.417},
49+
{'label':"F♯5",'midi':78,'1vOct':3.500},
50+
{'label':"G-5",'midi':79,'1vOct':3.583},
51+
{'label':"G♯5",'midi':80,'1vOct':3.667},
52+
{'label':"A-5",'midi':81,'1vOct':3.750},
53+
{'label':"A♯5",'midi':82,'1vOct':3.833},
54+
{'label':"B-5",'midi':83,'1vOct':3.917},
55+
{'label':"C-6",'midi':84,'1vOct':4.000},
56+
{'label':"C♯6",'midi':85,'1vOct':4.083},
57+
{'label':"D-6",'midi':86,'1vOct':4.167},
58+
{'label':"D♯6",'midi':87,'1vOct':4.250},
59+
{'label':"E-6",'midi':88,'1vOct':4.333},
60+
{'label':"F-6",'midi':89,'1vOct':4.417},
61+
{'label':"F♯6",'midi':90,'1vOct':4.500},
62+
{'label':"G-6",'midi':91,'1vOct':4.583},
63+
{'label':"G♯6",'midi':92,'1vOct':4.667},
64+
{'label':"A-6",'midi':93,'1vOct':4.750},
65+
{'label':"A♯6",'midi':94,'1vOct':4.833},
66+
{'label':"B-6",'midi':95,'1vOct':4.917},
67+
{'label':"C-7",'midi':96,'1vOct':5.000},
68+
]

0 commit comments

Comments
 (0)