| 88 | |
| 89 | |
| 90 | class BufferedAudioTracker: |
| 91 | def __init__(self, sample_rate: int): |
| 92 | self.sample_rate = sample_rate |
| 93 | self.start_time: Optional[float] = None |
| 94 | self.samples_emitted = 0 |
| 95 | |
| 96 | def add_chunk(self, chunk: np.ndarray) -> None: |
| 97 | if chunk.size == 0: |
| 98 | return |
| 99 | if self.start_time is None: |
| 100 | self.start_time = time.monotonic() |
| 101 | self.samples_emitted += int(chunk.size) |
| 102 | |
| 103 | def buffered_seconds(self) -> float: |
| 104 | if self.start_time is None: |
| 105 | return 0.0 |
| 106 | elapsed = time.monotonic() - self.start_time |
| 107 | buffered = self.samples_emitted / self.sample_rate - elapsed |
| 108 | return max(0.0, buffered) |
| 109 | |
| 110 | |
| 111 | class AudioFrameDecoder: |