| 77 | } |
| 78 | |
| 79 | audio::Sample WasmAudioInput::read() { |
| 80 | if (!mRunning || isEmpty()) { |
| 81 | return audio::Sample(); // Return invalid sample |
| 82 | } |
| 83 | |
| 84 | // Read from tail |
| 85 | AudioBlock& block = mRingBuffer[mTail]; |
| 86 | |
| 87 | if (!block.valid) { |
| 88 | return audio::Sample(); // Shouldn't happen, but safety check |
| 89 | } |
| 90 | |
| 91 | // Create audio::Sample from block data |
| 92 | fl::span<const fl::i16> samples(block.samples, BLOCK_SIZE); |
| 93 | audio::Sample result(samples, block.timestamp); |
| 94 | |
| 95 | // Mark block as consumed and advance tail |
| 96 | block.valid = false; |
| 97 | mTail = nextIndex(mTail); |
| 98 | mReadBlocks++; |
| 99 | |
| 100 | if (mReadBlocks == 1) { |
| 101 | fl::printf("WasmAudioInput: First audio block consumed by sketch " |
| 102 | "(timestamp=%u ms)\n", (unsigned)block.timestamp); |
| 103 | } |
| 104 | |
| 105 | return result; |
| 106 | } |
| 107 | |
| 108 | void WasmAudioInput::pushSamples(const fl::i16* samples, int count, fl::u32 timestamp) { |
| 109 | if (!mRunning) { |