Skip to content
70 changes: 42 additions & 28 deletions Fruit_Jam/Larsio_Paint_Music/sound_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,20 @@
import math
import time
import array
import json
import gc
import os
import digitalio
import busio


import adafruit_midi
import audiobusio
import audiocore
import audiopwmio
import audiobusio
import audiomixer
import synthio
import board
import adafruit_tlv320
import adafruit_pathlib as pathlib
import adafruit_fruitjam
from adafruit_midi.note_on import NoteOn
from adafruit_midi.note_off import NoteOff
import usb_midi
Expand Down Expand Up @@ -53,16 +53,20 @@ def __init__(self, audio_output="pwm", seconds_per_eighth=0.25):
self.audio_output_type = audio_output
self.tlv = None

# Initialize these variables to avoid use-before-assignment issues
i2c = None
bclck_pin = None
wsel_pin = None
din_pin = None

if self.audio_output_type == "pwm":
# Setup PWM audio output on D10
self.audio = audiopwmio.PWMAudioOut(board.D10)
else: # i2s
# optional configuration file for speaker/headphone setting
launcher_config = {}
for directory in ("/", "/sd/", "/saves/"):
launcher_config_path = directory + "launcher.conf.json"
if pathlib.Path(launcher_config_path).exists():
with open(launcher_config_path, "r") as f:
launcher_config = launcher_config | json.load(f)
if "audio" not in launcher_config:
launcher_config["audio"] = {}

try:
# Import libraries needed for I2S
#check for Metro RP2350 vs. Fruit Jam
Expand All @@ -76,11 +80,17 @@ def __init__(self, audio_output="pwm", seconds_per_eighth=0.25):
time.sleep(0.1) # Pause 100ms
reset_pin.value = True # Set high to release from reset

i2c = board.STEMMA_I2C() # initialize I2C
# Initialize TLV320
fjPeriphs = adafruit_fruitjam.Peripherals(
audio_output=launcher_config["audio"].get("output", "headphone"),
safe_volume_limit=launcher_config["audio"].get("volume_override_danger",12),
sample_rate=11025,
bit_depth=16,
i2c=board.STEMMA_I2C()
)

bclck_pin = board.D9
wsel_pin = board.D10
din_pin = board.D11
self.tlv = fjPeriphs.dac
fjPeriphs.audio = audiobusio.I2SOut(board.D9, board.D10, board.D11)

elif 'Fruit Jam' in board_type:
print("Fruit Jam setup")
Expand All @@ -90,24 +100,27 @@ def __init__(self, audio_output="pwm", seconds_per_eighth=0.25):
time.sleep(0.1)
reset_pin.value = True

i2c = busio.I2C(board.SCL, board.SDA)
# Initialize TLV320
fjPeriphs = adafruit_fruitjam.Peripherals(
audio_output=launcher_config["audio"].get("output", "headphone"),
safe_volume_limit=launcher_config["audio"].get("volume_override_danger",12),
sample_rate=11025,
bit_depth=16,
i2c=board.I2C()
)

bclck_pin = board.I2S_BCLK
wsel_pin = board.I2S_WS
din_pin = board.I2S_DIN
self.tlv = fjPeriphs.dac

# Initialize TLV320
self.tlv = adafruit_tlv320.TLV320DAC3100(i2c)
self.tlv.configure_clocks(sample_rate=11025, bit_depth=16)
self.tlv.headphone_output = True
self.tlv.headphone_volume = -15 # dB
# If volume was specified use it, otherwise use the fruitjam library default
if "volume_override_danger" in launcher_config["audio"]:
fjPeriphs.volume = launcher_config["audio"]["volume_override_danger"]
elif "volume" in launcher_config["audio"]:
fjPeriphs.volume = launcher_config["audio"]["volume"] # FruitJam vol (1-20)

# Setup I2S audio output - important to do this AFTER configuring the DAC
self.audio = audiobusio.I2SOut(
bit_clock=bclck_pin,
word_select=wsel_pin,
data=din_pin
)
# Fruitjam library actually does this before we modify the configuration
# but after the initial default configuration is performed
self.audio = fjPeriphs.audio

print("TLV320 I2S DAC initialized successfully")
except Exception as e:
Expand Down Expand Up @@ -595,6 +608,7 @@ def deinit(self):
try:
# For TLV320DAC3100, headphone_output = False will power down the output
self.tlv.headphone_output = False
self.tlv.speaker_output = False
except Exception:
pass

Expand Down
2 changes: 1 addition & 1 deletion Metro/Metro_RP2350_Chips_Challenge/audio.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ def __init__(self, audio_bus, sounds):
self.play(tuple(self._wav_files.keys())[0], wait=True)

def play(self, sound_name, wait=False):
if not PLAY_SOUNDS:
if not PLAY_SOUNDS or self._audio is None:
return
if sound_name in self._wav_files:
with open(self._wav_files[sound_name], "rb") as wave_file:
Expand Down
57 changes: 36 additions & 21 deletions Metro/Metro_RP2350_Chips_Challenge/code.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@
#
# SPDX-License-Identifier: MIT

import json
import time
import board
import picodvi
import framebufferio
import displayio
import adafruit_tlv320
import supervisor
import audiobusio
from audio import Audio
import adafruit_pathlib as pathlib
import adafruit_fruitjam.Peripherals
from game import Game
from definitions import SECOND_LENGTH, TICKS_PER_SECOND

Expand Down Expand Up @@ -37,28 +37,43 @@
"TIME_UP": "sounds/bell.wav"
}

displayio.release_displays()
# optional configuration file for speaker/headphone setting
launcher_config = {}
for directory in ("/", "/sd/", "/saves/"):
launcher_config_path = directory + "launcher.conf.json"
if pathlib.Path(launcher_config_path).exists():
with open(launcher_config_path, "r") as f:
launcher_config = launcher_config | json.load(f)
if "audio" not in launcher_config:
launcher_config["audio"] = {}

i2c = board.I2C()
dac = adafruit_tlv320.TLV320DAC3100(i2c)
dac.configure_clocks(sample_rate=44100, bit_depth=16)
dac.headphone_output = True
dac.headphone_volume = -15 # dB

if hasattr(board, "I2S_BCLK"):
audio_bus = audiobusio.I2SOut(board.I2S_BCLK, board.I2S_WS, board.I2S_DIN)
fjPeriphs = adafruit_fruitjam.Peripherals.Peripherals(
audio_output=launcher_config["audio"].get("output", "headphone"),
safe_volume_limit=launcher_config["audio"].get("volume_override_danger",12),
sample_rate=44100,
bit_depth=16,
i2c=board.I2C()
)
if not hasattr(board, "I2S_BCLK") and \
hasattr(board, "D9") and hasattr(board, "D10") and hasattr(board, "D11"):

fjPeriphs.audio = audiobusio.I2SOut(board.D9, board.D10, board.D11)

# If volume was specified use it, otherwise use the fruitjam library default
if "volume_override_danger" in launcher_config["audio"]:
fjPeriphs.volume = launcher_config["audio"]["volume_override_danger"]
elif "volume" in launcher_config["audio"]:
fjPeriphs.volume = launcher_config["audio"]["volume"] # FruitJam vol (1-20)

if fjPeriphs.audio is not None:
audio = Audio(fjPeriphs.audio, SOUND_EFFECTS)
else:
audio_bus = audiobusio.I2SOut(board.D9, board.D10, board.D11)
audio = Audio(audio_bus, SOUND_EFFECTS)
audio = None

fb = picodvi.Framebuffer(320, 240, clk_dp=board.CKP, clk_dn=board.CKN,
red_dp=board.D0P, red_dn=board.D0N,
green_dp=board.D1P, green_dn=board.D1N,
blue_dp=board.D2P, blue_dn=board.D2N,
color_depth=8)
display = framebufferio.FramebufferDisplay(fb)
adafruit_fruitjam.Peripherals.request_display_config(320, 240, 8)

game = Game(display, DATA_FILE, audio)
game = Game(supervisor.runtime.display, DATA_FILE, audio)
tick_length = SECOND_LENGTH / 1000 / TICKS_PER_SECOND
while True:
start = time.monotonic()
Expand Down
5 changes: 4 additions & 1 deletion Metro/Metro_RP2350_Chips_Challenge/savestate.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,10 @@ def _mount_sd_card(self):
except OSError:
pass

self._card_detect = DigitalInOut(board.SD_CARD_DETECT)
try:
self._card_detect = DigitalInOut(board.SD_CARD_DETECT)
except ValueError:
return False
self._card_detect.switch_to_input(pull=Pull.UP)
if self._card_detect.value:
return False
Expand Down