Skip to content

Commit d1f8623

Browse files
rjtokenringdsammaruga
authored andcommitted
wav cache to reduce disk reads
1 parent 660f713 commit d1f8623

File tree

1 file changed

+29
-8
lines changed

1 file changed

+29
-8
lines changed

src/arduino/app_bricks/sound_generator/__init__.py

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,29 @@
1616
from .loaders import ABCNotationLoader
1717

1818

19+
class LRUDict(OrderedDict):
20+
"""A dictionary-like object with a fixed size that evicts the least recently used items."""
21+
22+
def __init__(self, maxsize=128, *args, **kwargs):
23+
self.maxsize = maxsize
24+
super().__init__(*args, **kwargs)
25+
26+
def __getitem__(self, key):
27+
value = super().__getitem__(key)
28+
self.move_to_end(key)
29+
return value
30+
31+
def __setitem__(self, key, value):
32+
if key in self:
33+
self.move_to_end(key)
34+
35+
super().__setitem__(key, value)
36+
37+
if len(self) > self.maxsize:
38+
# Evict the least recently used item (the first item)
39+
self.popitem(last=False)
40+
41+
1942
@brick
2043
class SoundGeneratorStreamer:
2144
SAMPLE_RATE = 16000
@@ -90,6 +113,8 @@ def __init__(
90113
notes = self._fill_node_frequencies(octave)
91114
self._notes.update(notes)
92115

116+
self._wav_cache = LRUDict(maxsize=10)
117+
93118
def start(self):
94119
pass
95120

@@ -427,19 +452,15 @@ def play_wav(self, wav_file: str) -> tuple[bytes, float]:
427452
if not file_path.exists() or not file_path.is_file():
428453
raise FileNotFoundError(f"WAV file not found: {wav_file}")
429454

430-
wav_cache = OrderedDict()
431-
432-
if wav_file in wav_cache:
433-
return wav_cache[wav_file]
455+
if wav_file in self._wav_cache:
456+
return self._wav_cache[wav_file]
434457

435458
with wave.open(wav_file, "rb") as wav:
436459
# Read all frames (raw PCM data)
437460
duration = wav.getnframes() / wav.getframerate()
438461
wav_data = wav.readframes(wav.getnframes())
439-
if len(wav_cache) < 250 * 1024: # 250 KB cache limit
440-
wav_cache[wav_file] = (wav_data, duration)
441-
if len(wav_cache) > 10:
442-
wav_cache.popitem(last=False)
462+
if len(self._wav_cache) < 250 * 1024: # 250 KB cache limit
463+
self._wav_cache[wav_file] = (wav_data, duration)
443464
return (wav_data, duration)
444465

445466
return (None, None)

0 commit comments

Comments
 (0)