Last active
December 16, 2023 02:41
-
-
Save connornishijima/c55ee765ad6f832085fcd5bdac8734d2 to your computer and use it in GitHub Desktop.
"Lovely Music Generator" For CircuitPython by LIXIE LABS
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
# ---------------------------------------------------------------------------- | |
# LOVELY MUSIC GENERATOR by LIXIE LABS | |
# https://leds.social/@lixielabs | |
# | |
# Plays random notes/chords from the Amaj7 scale in a pleasing fashion using | |
# audiopwmio to drive a speaker with five synthio sine voices and ADSR envelopes. | |
# Import dependencies | |
import time | |
import board | |
import synthio | |
import audiopwmio | |
import array | |
import math | |
import random | |
# ---------------------------------------------------------------------------- | |
# USER VARIABLES | |
# You can use the speaker directly, but it's MUCH louder to use a PAM8503 3W Audio Amplifier PCB (https://www.amazon.com/ALAMSCN-Speaker-Loudspeaker-Amplifier-Replacement/dp/B0953B5KMJ/ref=sr_1_6) | |
SPEAKER_PWM_PIN = board.GP15 | |
# Some of the AMaj7 scale in MIDI note numbers: | |
MUSICAL_SCALE = [40, 42, 44, 45, 47, 49, 50, 52, 54, 56, 57, 59, 61, 62, 64, 66, 68, 69, 71, 73, 74, 76, 78] | |
# How much to transpose the scale (default +2 octaves) | |
TRANSPOSITION = 12 | |
# Should the ADSR envelope evolve slightly over time? | |
envelope_changes = True | |
# ---------------------------------------------------------------------------- | |
# AUDIO SETUP SECTION | |
# Initialize PWM audio output on SPEAKER_PIN | |
audio = audiopwmio.PWMAudioOut(SPEAKER_PWM_PIN, quiescent_value = 32768) | |
# Render waveform data for use by synthio (single sine cycle) | |
synth_waveform = array.array('h') | |
wave_sample_count = 1024 | |
for i in range(wave_sample_count): | |
sine_value = math.sin(2 * math.pi * (i / wave_sample_count)) * 0.2 | |
adjusted_value = int(((sine_value + 1) / 2) * 65535) - 32768 | |
synth_waveform.append(adjusted_value) | |
# Define the note ADSR envelope timings | |
adsr_envelope = synthio.Envelope( | |
attack_time = 0.05, # Attack time in seconds | |
decay_time = 0.50, # Decay time in seconds | |
release_time = 1.00, # Release time in seconds | |
attack_level = 1.00, # Peak volume of the attack phase (0.0 to 1.0) | |
sustain_level = 0.40 # Volume of the sustain phase relative to the attack level (0.0 to 1.0) | |
) | |
# Initialize the synthesizer | |
synth = synthio.Synthesizer(sample_rate=44100, envelope=adsr_envelope, waveform=synth_waveform) | |
# Start the audio engine | |
audio.play(synth) | |
# ---------------------------------------------------------------------------- | |
# LOVELY MUSIC SECTION | |
# This stores currently playing notes | |
notes = [0, 0, 0, 0, 0] | |
# Start looping forever now | |
while True: | |
# Iterate through 5 voices | |
for i in range(len(notes)): | |
# If 1 in 10 chance: | |
if random.randint(0, 10) < 1: | |
# Play random new note from MUSICAL_SCALE + TRANSPOSITION using this voice | |
synth.release((notes[i])) | |
notes[i] = MUSICAL_SCALE[random.randint(0, len(MUSICAL_SCALE) - 1)] + TRANSPOSITION | |
synth.press((notes[i])) | |
# If 1 in 10 chance: (1 in 100 since note changes are already 1 in 10) alter the ADSR envelope | |
if random.randint(0, 10) < 1 and envelope_changes == True: | |
new_adsr_envelope = synthio.Envelope( | |
attack_time = (random.randint(10,100) / 500.0), # Attack time in seconds | |
decay_time = (random.randint(10,100) / 500.0), # Decay time in seconds | |
release_time = (random.randint(10,100) / 150.0), # Release time in seconds | |
attack_level = 1.00, # Peak volume of the attack phase (0.0 to 1.0) | |
sustain_level = 0.10 # Volume of the sustain phase relative to the attack level (0.0 to 1.0) | |
) | |
synth.envelope = new_adsr_envelope | |
# Keeps playback speed in check | |
time.sleep(0.4) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment