| 137 | } |
| 138 | |
| 139 | bool VorbisDecoderImpl::begin(fl::filebuf_ptr stream) { |
| 140 | end(); // Clean up any previous state |
| 141 | |
| 142 | if (!stream) { |
| 143 | mError = "Null stream"; |
| 144 | return false; |
| 145 | } |
| 146 | |
| 147 | // stb_vorbis pulldata API requires entire file in memory |
| 148 | // Read entire stream into buffer |
| 149 | mFileData.clear(); |
| 150 | fl::u8 buffer[1024]; |
| 151 | while (stream->available(1)) { |
| 152 | fl::size bytesRead = stream->read(buffer, sizeof(buffer)); |
| 153 | if (bytesRead == 0) break; |
| 154 | for (fl::size i = 0; i < bytesRead; ++i) { |
| 155 | mFileData.push_back(buffer[i]); |
| 156 | } |
| 157 | } |
| 158 | |
| 159 | if (mFileData.empty()) { |
| 160 | mError = "Empty stream"; |
| 161 | return false; |
| 162 | } |
| 163 | |
| 164 | // Open decoder |
| 165 | if (!mDecoder.openMemory(mFileData)) { |
| 166 | mError = "Failed to decode Vorbis stream"; |
| 167 | return false; |
| 168 | } |
| 169 | |
| 170 | mEndOfStream = false; |
| 171 | mError.clear(); |
| 172 | return true; |
| 173 | } |
| 174 | |
| 175 | void VorbisDecoderImpl::end() { |
| 176 | mDecoder.close(); |