Skip to content

Commit 12f6055

Browse files
committed
audiolive_rack says there is no pump instead of dying on its constructor
The generator lists every card in both galleries, and the Pyodide half has no audiopump: LiveAudio raises from why() there, which reached the page as a traceback and a black canvas. audiolive has available()/why() for exactly this case, so the card asks first and draws the sentence instead. Same for a firmware built without the audiodsp usermod.
1 parent b987106 commit 12f6055

1 file changed

Lines changed: 28 additions & 16 deletions

File tree

lib/examples/audiolive_rack.py

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -103,11 +103,19 @@ def color565(r, g, b):
103103
METER = color565(80, 220, 140)
104104
METER_BG = color565(38, 42, 54)
105105

106-
live = audiolive.LiveAudio(volume=audiolive.VOLUME)
107-
# Synthesised before anything is on screen: `riff` is 115 200 Python loop
108-
# iterations, and paying for it while a timer is already ticking is how an
109-
# example ends up looking wedged on its first frame.
110-
live.prepare("riff")
106+
# `available()` and `why()` exist for exactly this: a runtime without the pump
107+
# built in cannot play any of this, and an example that dies on its
108+
# constructor tells a reader nothing. The Pyodide half of the gallery is that
109+
# runtime, and so is a firmware built without the audiodsp usermod.
110+
_no_sound = None if audiolive.available() else audiolive.why()
111+
112+
live = None
113+
if _no_sound is None:
114+
live = audiolive.LiveAudio(volume=audiolive.VOLUME)
115+
# Synthesised before anything is on screen: `riff` is 115 200 Python loop
116+
# iterations, and paying for it while a timer is already ticking is how an
117+
# example ends up looking wedged on its first frame.
118+
live.prepare("riff")
111119

112120
# The pump's engine, through audiodev's accessor rather than a bare import:
113121
# `module()` is the supported way to ask for it, and `threaded()` is the
@@ -119,25 +127,26 @@ def color565(r, g, b):
119127
# pump fills a RAM ring and SOMEBODY has to drain it into a sink -- that is
120128
# true on a desktop as much as in a browser. Whether that somebody also has to
121129
# *run* the pump is the second question, and only WebAssembly answers yes.
122-
_drains = not live.on_board
130+
_drains = live is not None and not live.on_board
123131
_services = _drains and not pumpdev.threaded()
124132

125133
_sink = None
126134
_sink_open = False
127-
_sink_why = None
128135
if _drains:
129136
from audiodev import auto as audioauto # noqa: E402
130137

131138
try:
132139
_sink = audioauto.pcm_out()
133140
except Exception as exc: # a desktop with no audio backend installed
134-
_sink_why = str(exc)
141+
_no_sound = str(exc)
135142
_drains = _services = False
136143

137144
_WHERE = (
138-
"on the board, straight into I2S"
139-
if live.on_board
140-
else ("in the browser, serviced by a timer" if _services else "into a ring you drain")
145+
audiolive.why()
146+
if _no_sound is not None
147+
else ("on the board, straight into I2S" if live.on_board
148+
else ("in the browser, serviced by a timer" if _services
149+
else "into a ring you drain"))
141150
)
142151

143152
_buf = bytearray(DRAIN_BYTES)
@@ -167,8 +176,10 @@ def _sink_ready():
167176
there is no sink here at all -- the pump owns the I2S port itself.
168177
"""
169178
global _sink_open
179+
if _no_sound is not None:
180+
return False
170181
if _sink is None:
171-
return _sink_why is None
182+
return True
172183
if _sink_open:
173184
return True
174185
try:
@@ -299,10 +310,10 @@ def _draw_tick(_=None):
299310
y += 16 + 12
300311

301312
if not _started:
302-
if _sink_why is not None:
303-
pygraphics.text(display_drv, "NO AUDIO OUTPUT", pad, y, ACCENT, scale=2)
313+
if _no_sound is not None:
314+
pygraphics.text(display_drv, "NO SOUND HERE", pad, y, ACCENT, scale=2)
304315
y += 22
305-
for line in _wrap(_sink_why, COLS):
316+
for line in _wrap(_no_sound, COLS):
306317
pygraphics.text(display_drv, line, pad, y, DIM, scale=1)
307318
y += ROW
308319
return
@@ -355,7 +366,8 @@ def _draw_tick(_=None):
355366

356367

357368
def _on_quit(_e=None):
358-
live.stop()
369+
if live is not None:
370+
live.stop()
359371
if _sink is not None and _sink_open:
360372
_sink.close()
361373
display_drv.quit()

0 commit comments

Comments
 (0)