Decodes a block of samples of size BLOCK_MS or less, and feeds it to AL. Returns the number of samples that have been decoded.
| 164 | /// Decodes a block of samples of size BLOCK_MS or less, and feeds it to AL. |
| 165 | /// Returns the number of samples that have been decoded. |
| 166 | u32 decode_samples() |
| 167 | { |
| 168 | if (!_stream) |
| 169 | return 0; |
| 170 | |
| 171 | if (_resource->stream_format == StreamFormat::OGG) { |
| 172 | const OggStreamMetadata *ogg = (OggStreamMetadata *)sound_resource::stream_metadata(_resource); |
| 173 | int used; |
| 174 | int skip_n = 0; |
| 175 | |
| 176 | // Open the stream. |
| 177 | if (_stream_data == NULL) { |
| 178 | const u32 stream_mem_size = 0 |
| 179 | + sizeof(stb_vorbis_alloc) + alignof(stb_vorbis_alloc) |
| 180 | + ogg->alloc_buffer_size |
| 181 | + ogg->headers_size |
| 182 | + ogg->max_frame_size |
| 183 | + _block_size*2 + alignof(f32) |
| 184 | ; |
| 185 | _stream_data = default_allocator().allocate(stream_mem_size); |
| 186 | |
| 187 | _vorbis_alloc = (stb_vorbis_alloc *)memory::align_top(_stream_data, alignof(stb_vorbis_alloc)); |
| 188 | _vorbis_alloc->alloc_buffer = (char *)&_vorbis_alloc[1]; |
| 189 | _vorbis_alloc->alloc_buffer_length_in_bytes = ogg->alloc_buffer_size; |
| 190 | |
| 191 | _vorbis_headers = (unsigned char *)&_vorbis_alloc[1] + ogg->alloc_buffer_size; |
| 192 | |
| 193 | _stream_encoded = (unsigned char *)_vorbis_headers + ogg->headers_size; |
| 194 | _stream_decoded = (u8 *)memory::align_top(_stream_encoded + ogg->max_frame_size, alignof(f32)); |
| 195 | _stream_pos = 0; |
| 196 | |
| 197 | _stream->read(_vorbis_headers, ogg->headers_size); |
| 198 | skip_n = ogg->num_samples_skip; |
| 199 | } |
| 200 | |
| 201 | if (_vorbis == NULL) { |
| 202 | int error; |
| 203 | _vorbis = stb_vorbis_open_pushdata(_vorbis_headers, ogg->headers_size, &used, &error, _vorbis_alloc); |
| 204 | CE_ENSURE(error == VORBIS__no_error); |
| 205 | CE_ENSURE(_vorbis != NULL); |
| 206 | CE_ENSURE(used == ogg->headers_size); |
| 207 | } |
| 208 | |
| 209 | // Decode _block_size samples or less. |
| 210 | f32 *dec = (f32 *)_stream_decoded; |
| 211 | u32 tot_n = 0; |
| 212 | while (tot_n < _block_samples) { |
| 213 | float **output; |
| 214 | int n; |
| 215 | int q = ogg->max_frame_size; |
| 216 | |
| 217 | retry: |
| 218 | if (q > int(_stream->size() - _stream_pos)) |
| 219 | q = _stream->size() - _stream_pos; |
| 220 | if ((int)_stream_pos < q) |
| 221 | _stream_pos += _stream->read(&_stream_encoded[_stream_pos], q - _stream_pos); |
| 222 | |
| 223 | used = stb_vorbis_decode_frame_pushdata(_vorbis |
nothing calls this directly
no test coverage detected