Last active
December 2, 2023 01:56
-
-
Save jedgarpark/e5df9de1c05a7ce5eb17be19d8bb11ff to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# testing Wave Shape Fader v0.1 PCB | |
# john park 2023 | |
import time | |
import board | |
import busio | |
import ulab.numpy as np | |
import rotaryio | |
import neopixel | |
from digitalio import DigitalInOut, Pull | |
import displayio | |
from adafruit_display_shapes.rect import Rect | |
from adafruit_display_text import label | |
import terminalio | |
import synthio | |
import audiomixer | |
from adafruit_debouncer import Debouncer | |
import adafruit_ads7830.ads7830 as ADC | |
from adafruit_ads7830.analog_in import AnalogIn | |
import adafruit_displayio_ssd1306 | |
import adafruit_ad569x | |
import usb_midi | |
import adafruit_midi | |
from adafruit_midi.note_on import NoteOn | |
from adafruit_midi.note_off import NoteOff | |
displayio.release_displays() | |
midi = adafruit_midi.MIDI(midi_in=usb_midi.ports[0], in_channel=0 ) | |
debug_notes = True | |
ITSY_TYPE = 0 # 0=M4, 1=RP2040 | |
# neopixel setup | |
if ITSY_TYPE is 1: | |
pixel = neopixel.NeoPixel(board.NEOPIXEL, 1, brightness = 0.3) | |
pixel.fill(0x004444) | |
i2c = busio.I2C(board.SCL, board.SDA, frequency=1_000_000) | |
NUM_FADERS = 16 | |
num_voices = 3 # how many voices for each note | |
lpf_basef = 1500 # filter lowest frequency | |
lpf_resonance = 1.5 # filter q | |
faders_pos = [None] * NUM_FADERS | |
last_faders_pos = [None] * NUM_FADERS | |
# Initialize ADS7830 | |
adc_a = ADC.ADS7830(i2c, address=0x48) # default address 0x48 | |
adc_b = ADC.ADS7830(i2c, address=0x4A) # A0 jumper 0x49, A1 0x4A | |
faders = [] # list for fader objects on first ADC | |
for f in range(8): # add first group to list | |
faders.append(AnalogIn(adc_a, f)) | |
for f in range(8): # add second group | |
faders.append(AnalogIn(adc_b, f)) | |
# Initialize AD5693R for CV out | |
dac = adafruit_ad569x.Adafruit_AD569x(i2c) | |
dac.gain = True | |
dac.value = faders[0].value # set dac out to the slider level | |
# Rotary encoder setup | |
ENC_A = board.D9 | |
ENC_B = board.D10 | |
ENC_SW = board.D7 | |
button_in = DigitalInOut(ENC_SW) # defaults to input | |
button_in.pull = Pull.UP # turn on internal pull-up resistor | |
button = Debouncer(button_in) | |
encoder = rotaryio.IncrementalEncoder(ENC_A, ENC_B) | |
encoder_pos = encoder.position | |
last_encoder_pos = encoder.position | |
# display setup | |
OLED_RST =board.D13 | |
OLED_DC = board.D12 | |
OLED_CS = board.D11 | |
spi = board.SPI() | |
display_bus = displayio.FourWire(spi, command=OLED_DC, chip_select=OLED_CS, | |
reset=OLED_RST, baudrate=1000000) | |
display = adafruit_displayio_ssd1306.SSD1306(display_bus, width=128, height=64) | |
# Create display group | |
group = displayio.Group() | |
# Create background rectangle | |
bg_rect = Rect(0, 0, display.width, display.height, fill=0x0) | |
group.append(bg_rect) | |
# Set the font for the text label | |
font = terminalio.FONT | |
# Create text label to display the number | |
text = label.Label(font, text=str(faders[0].value//256), color=0xffffff) | |
text.x = display.width // 12 | |
text.y = display.height // 2 | |
text.anchor_point = (0.5, 0.5) | |
text.scale = 2 | |
group.append(text) | |
# Show the display group | |
display.show(group) | |
# Synthio setup | |
if ITSY_TYPE is 0: | |
import audioio | |
audio = audioio.AudioOut(left_channel=board.A0, right_channel=board.A1) # M4 built-in DAC | |
if ITSY_TYPE is 1: | |
import audiopwmio | |
audio = audiopwmio.PWMAudioOut(board.A1) | |
# if using I2S amp: | |
#audio = audiobusio.I2SOut(bit_clock=board.MOSI, word_select=board.MISO, data=board.SCK) | |
mixer = audiomixer.Mixer(channel_count=2, sample_rate = 44100, buffer_size=4096) | |
synth = synthio.Synthesizer(channel_count=2, sample_rate=44100) | |
audio.play(mixer) | |
mixer.voice[0].play(synth) | |
mixer.voice[0].level = 0.75 | |
wave_user = np.array( [0]*NUM_FADERS, dtype=np.int16) | |
amp_env = synthio.Envelope(attack_time=0.3, attack_level=1, sustain_level=0.65, release_time=0.3) | |
voices=[] # holds our currently sounding voices ('Notes' in synthio speak) | |
def faders_to_wave(): | |
for i in range(NUM_FADERS): | |
wave_user[i] = int(map_range(faders_pos[i], 0, 255, -32768, 32767)) | |
def note_on(n): | |
# print(" note on ", n ) | |
fo = synthio.midi_to_hz(n) | |
voices.clear() # delete any old voices | |
# wave_user = np.array([ | |
# int(map_range(faders_pos[0], 0, 255, -32768, 32767)), | |
# int(map_range(faders_pos[1], 0, 255, -32768, 32767)), | |
# int(map_range(faders_pos[2], 0, 255, -32768, 32767)), | |
# int(map_range(faders_pos[3], 0, 255, -32768, 32767)), | |
# int(map_range(faders_pos[4], 0, 255, -32768, 32767)), | |
# int(map_range(faders_pos[5], 0, 255, -32768, 32767)), | |
# int(map_range(faders_pos[6], 0, 255, -32768, 32767)), | |
# int(map_range(faders_pos[7], 0, 255, -32768, 32767)), | |
# int(map_range(faders_pos[8], 0, 255, -32768, 32767)), | |
# int(map_range(faders_pos[9], 0, 255, -32768, 32767)), | |
# int(map_range(faders_pos[10], 0, 255, -32768, 32767)), | |
# int(map_range(faders_pos[11], 0, 255, -32768, 32767)), | |
# int(map_range(faders_pos[12], 0, 255, -32768, 32767)), | |
# int(map_range(faders_pos[13], 0, 255, -32768, 32767)), | |
# int(map_range(faders_pos[14], 0, 255, -32768, 32767)), | |
# int(map_range(faders_pos[15], 0, 255, -32768, 32767)), | |
# ], dtype=np.int16) | |
for i in range(num_voices): | |
f = fo * (1 + i*0.007) | |
lpf_f = fo * 8 # a kind of key tracking | |
lpf = synth.low_pass_filter( lpf_f, lpf_resonance ) | |
voices.append( synthio.Note( frequency=f, filter=lpf, envelope=amp_env, waveform=wave_user) ) | |
synth.press(voices) | |
# call to turn off a note | |
def note_off(n): | |
# print(" note off", n) | |
synth.release(voices) | |
# simple range mapper, like Arduino map() | |
def map_range(s, a1, a2, b1, b2): return b1 + ((s - a1) * (b2 - b1) / (a2 - a1)) | |
while True: | |
msg = midi.receive() | |
if isinstance(msg, NoteOn) and msg.velocity != 0: | |
# print("noteOn: ", msg.note) | |
text.text=(str(msg.note)) | |
note_on( msg.note) | |
elif isinstance(msg,NoteOff) or isinstance(msg,NoteOn) and msg.velocity==0: | |
# print("noteOff:", msg.note) | |
note_off( msg.note) | |
button.update() | |
if button.fell: | |
note_on(45) | |
if button.rose: | |
note_off(45) | |
encoder_pos = encoder.position | |
if encoder_pos is not last_encoder_pos: | |
# print("encoder:", encoder.position) # starts at zero, goes neg or pos | |
last_encoder_pos = encoder.position | |
# | |
for i in range(len(faders)): | |
# print(faders[0].value) | |
faders_pos[i] = faders[i].value//256 | |
if faders_pos[i] is not last_faders_pos[i]: | |
faders_to_wave() | |
last_faders_pos[i] = faders_pos[i] | |
# if you want to send out a DAC value as a test: | |
# dac.value = faders[0].value | |
time.sleep(0.1) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Are you sorry you lied, or sorry you were caught, hmmmmm "Tod"?