Last active
November 20, 2017 18:07
-
-
Save abachman/4e154b384d32983d29a5b1724dcd5b61 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
# CircuitPlaygroundExpress Light Synth | |
# | |
# reads a potentiometer from A7, changes NeoPixels | |
# and audio tone | |
# | |
# slide switch turns off sound, button a changes sample | |
from analogio import AnalogIn | |
import board | |
import neopixel | |
import time | |
analogin = AnalogIn(board.A7) | |
def interp(val, fromMin, fromMax, toMin, toMax): | |
return ((val - fromMin) / (fromMax-fromMin)) * (toMax - toMin) + toMin | |
def getVoltage(pin): # helper | |
return (pin.value * 3.3) / 65536 | |
def wheel(pos): | |
# Input a value 0 to 255 to get a color value. | |
# The colours are a transition r - g - b - back to r. | |
if pos < 85: | |
return (int(pos*3), int(255 - (pos*3)), 0) | |
elif pos < 170: | |
pos -= 85 | |
return (int(255 - (pos*3)), 0, int(pos*3)) | |
else: | |
pos -= 170 | |
return (0, int(pos*3), int(255 - pos*3)) | |
# https://stackoverflow.com/questions/12332392/triangle-wave-shaped-array-in-python | |
def triangle(length, amplitude): | |
section = length // 4 | |
for direction in (1, -1): | |
for i in range(section): | |
yield i * (amplitude / section) * direction | |
for i in range(section): | |
yield (amplitude - (i * (amplitude / section))) * direction | |
pixels = neopixel.NeoPixel(board.NEOPIXEL, 10, brightness=.2) | |
pixels.fill((0,0,0)) | |
pixels.show() | |
from digitalio import DigitalInOut, Direction, Pull | |
import audioio | |
import math | |
import array | |
FREQUENCY = 440 # 440 Hz middle 'A' | |
SAMPLERATE = 8000 # 8000 samples/second, recommended! | |
# Generate one period of sine wav. | |
length = SAMPLERATE // FREQUENCY | |
print("generate wave with length %i" % (length)) | |
sine_wave = array.array("H", [0] * length) | |
square_wave = array.array("H", [0] * length) | |
triangle_wave = array.array("H", [ int(n) for n in triangle(length, FREQUENCY) ]) | |
for i in range(length): | |
sine_wave[i] = int(math.sin(math.pi * 2 * i / 18) * (2 ** 15) + 2 ** 15) | |
square_wave[i] = 0 if i < 6 == 0 else FREQUENCY | |
print(sine_wave) | |
print(square_wave) | |
print(triangle_wave) | |
waves = [ sine_wave, square_wave, triangle_wave ] | |
# enable the speaker | |
spkrenable = DigitalInOut(board.SPEAKER_ENABLE) | |
spkrenable.direction = Direction.OUTPUT | |
spkrenable.value = True | |
def get_sample(i): | |
return audioio.AudioOut(board.SPEAKER, waves[i]) | |
sample = get_sample(0) | |
switch = DigitalInOut(board.SLIDE_SWITCH) | |
switch.direction = Direction.INPUT | |
switch.pull = Pull.UP | |
button = DigitalInOut(board.BUTTON_A) | |
button.direction = Direction.INPUT | |
button.pull = Pull.DOWN | |
def tone(volt, samp): | |
samp.frequency = int(interp(volt, 0, 3.3, 6000, 8000)) | |
samp.play(loop=True) # keep playing the sample over and over | |
def stop(samp): | |
samp.stop() | |
last_volt = 0 | |
wave_idx = 0 | |
# this is the bit that repeats | |
while True: | |
volt = getVoltage(analogin) | |
pixels.fill(wheel(interp(volt, 0, 3.3, 0, 255))) | |
pixels.show() | |
if abs(volt - last_volt) > 0.2: | |
#print(volt) | |
if switch.value == True: # switch is pushed | |
sample.frequency = int(interp(volt, 0, 3.3, 6000, 8000)) | |
sample.play(loop=True) # keep playing the sample over and over | |
last_volt = volt | |
if button.value == True: | |
wave_idx = (wave_idx + 1) % len(waves) | |
stop(sample) | |
sample = get_sample(wave_idx) | |
sample.frequency = int(interp(volt, 0, 3.3, 6000, 8000)) | |
sample.play(loop=True) # keep playing the sample over and over | |
if switch.value == False: # switch is pushed | |
stop(sample) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment