diff --git a/docs/badge/programming.rst b/docs/badge/programming.rst
index 57b99928f7588070727ed9146f494fdf6c1f5297..adccc6366f160244ca78ea70116ca8afcb341ef1 100644
--- a/docs/badge/programming.rst
+++ b/docs/badge/programming.rst
@@ -735,9 +735,8 @@ Currently the simulator supports the display, LEDs, the buttons, accelerometer
 (in 2D) and some static input values from the gyroscope, temperature sensor and
 pressure sensor.
 
-It does **not** support any audio API, and in fact currently doesn't even stub
-out the relevant API methods, so it will crash when attempting to run any Music
-app. It also does not support positional captouch APIs.
+It does **not** support most of the audio APIs. It also does not support
+positional captouch APIs.
 
 To set the simulator up, clone the repository and prepare a Python virtual
 environment with the required packages:
diff --git a/sim/fakes/bl00mbox.py b/sim/fakes/bl00mbox.py
index a7f292e72284f2240f79138afb07738bd7b8765b..92bedec458c12b623f115564b0f7240b7fbdd35e 100644
--- a/sim/fakes/bl00mbox.py
+++ b/sim/fakes/bl00mbox.py
@@ -1,41 +1,110 @@
-class tinysynth:
-    def __init__(self, a):
-        pass
+import pygame
+from _sim import path_replace
 
-    def decay_ms(self, a):
-        pass
 
-    def decay(self, a):
+class _mock(list):
+    def __init__(self, *args, **kwargs):
         pass
 
-    def waveform(self, a):
-        pass
+    def __getattr__(self, attr):
+        if attr in ["tone", "value"]:
+            return 0
+        if attr in ["trigger_state"]:
+            return lambda *args: 0
+        return _mock()
 
-    def tone(self, note):
-        pass
+    def __call__(self, *args, **kwargs):
+        return _mock()
 
-    def start(self):
-        pass
 
-    def sustain(self, a):
+class Channel:
+    def __init__(self, id):
         pass
 
-    def attack_ms(self, a):
-        pass
+    def new(self, a, *args, **kwargs):
+        return a(self, *args, **kwargs)
 
-    def release_ms(self, a):
+    def clear(self):
         pass
 
-    def volume(self, a):
-        pass
+    mixer = None
+    channel_num = 0
+    volume = 8000
 
-    def stop(self):
-        pass
 
+class _patches(_mock):
+    class sampler(_mock):
+        class Signals(_mock):
+            class Trigger(_mock):
+                def __init__(self, sampler):
+                    self._sampler = sampler
 
-class Channel:
-    def __init__(self, id):
-        pass
+                def start(self):
+                    self._sampler._sound.set_volume(
+                        self._sampler._channel.volume / 32767
+                    )
+                    self._sampler._sound.play()
 
-    def clear(self):
-        pass
+            def __init__(self, sampler):
+                self._sampler = sampler
+                self._trigger = patches.sampler.Signals.Trigger(sampler)
+
+            @property
+            def trigger(self):
+                return self._trigger
+
+            @trigger.setter
+            def trigger(self, val):
+                pass
+
+        def _convert_filename(self, filename):
+            if filename.startswith("/flash/") or filename.startswith("/sd/"):
+                return filename
+            elif filename.startswith("/"):
+                return "/flash/" + filename
+            else:
+                return "/flash/sys/samples/" + filename
+
+        def __init__(self, channel, path):
+            if type(path) == int:
+                self._signals = _mock()
+                return
+            self._sound = pygame.mixer.Sound(path_replace(self._convert_filename(path)))
+            self._signals = patches.sampler.Signals(self)
+            self._channel = channel
+
+        @property
+        def signals(self):
+            return self._signals
+
+
+class _helpers(_mock):
+    def sct_to_note_name(self, sct):
+        sct = sct - 18367 + 100
+        octave = ((sct + 9 * 200) // 2400) + 4
+        tones = ["A", "Bb", "B", "C", "Db", "D", "Eb", "E", "F", "Gb", "G", "Ab"]
+        tone = tones[(sct // 200) % 12]
+        return tone + str(octave)
+
+    def note_name_to_sct(self, name):
+        tones = ["A", "Bb", "B", "C", "Db", "D", "Eb", "E", "F", "Gb", "G", "Ab"]
+        semitones = tones.index(name[0])
+        if semitones > 2:
+            semitones -= 12
+        if name[1] == "b":
+            octave = int(name[2:])
+            semitones -= 1
+        elif name[1] == "#":
+            octave = int(name[2:])
+            semitones += 1
+        else:
+            octave = int(name[1:])
+        return 18367 + (octave - 4) * 2400 + (200 * semitones)
+
+    def sct_to_freq(sct):
+        return 440 * 2 ** ((sct - 18367) / 2400)
+
+
+plugins = _mock()
+patches = _patches()
+helpers = _helpers()