|
16 | 16 | from .loaders import ABCNotationLoader |
17 | 17 |
|
18 | 18 |
|
| 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 | + |
19 | 42 | @brick |
20 | 43 | class SoundGeneratorStreamer: |
21 | 44 | SAMPLE_RATE = 16000 |
@@ -90,6 +113,8 @@ def __init__( |
90 | 113 | notes = self._fill_node_frequencies(octave) |
91 | 114 | self._notes.update(notes) |
92 | 115 |
|
| 116 | + self._wav_cache = LRUDict(maxsize=10) |
| 117 | + |
93 | 118 | def start(self): |
94 | 119 | pass |
95 | 120 |
|
@@ -427,19 +452,15 @@ def play_wav(self, wav_file: str) -> tuple[bytes, float]: |
427 | 452 | if not file_path.exists() or not file_path.is_file(): |
428 | 453 | raise FileNotFoundError(f"WAV file not found: {wav_file}") |
429 | 454 |
|
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] |
434 | 457 |
|
435 | 458 | with wave.open(wav_file, "rb") as wav: |
436 | 459 | # Read all frames (raw PCM data) |
437 | 460 | duration = wav.getnframes() / wav.getframerate() |
438 | 461 | 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) |
443 | 464 | return (wav_data, duration) |
444 | 465 |
|
445 | 466 | return (None, None) |
|
0 commit comments