diff options
Diffstat (limited to 'lib/vgmstream/src/layout/interleave_byte.c')
-rw-r--r-- | lib/vgmstream/src/layout/interleave_byte.c | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/lib/vgmstream/src/layout/interleave_byte.c b/lib/vgmstream/src/layout/interleave_byte.c new file mode 100644 index 0000000000..c9f8eb0886 --- /dev/null +++ b/lib/vgmstream/src/layout/interleave_byte.c @@ -0,0 +1,62 @@ +#include "layout.h" +#include "../vgmstream.h" + +/* for formats where the interleave is smaller than a frame, so we need to + * deinterleave in memory before passing it along to a specialized decoder which + * reads from memory + */ + +/* just do one frame at a time */ + +void render_vgmstream_interleave_byte(sample * buffer, int32_t sample_count, VGMSTREAM * vgmstream) { + /* frame sizes are much smaller than this */ + uint8_t sample_data[0x400]; + int samples_written=0; + + int frame_size = get_vgmstream_frame_size(vgmstream); + int samples_per_frame = get_vgmstream_samples_per_frame(vgmstream); + int samples_this_block; + + samples_this_block = samples_per_frame; + + while (samples_written<sample_count) { + int samples_to_do; + + if (vgmstream->loop_flag && vgmstream_do_loop(vgmstream)) { + continue; + } + + samples_to_do = vgmstream_samples_to_do(samples_this_block, samples_per_frame, vgmstream); + + if (samples_written+samples_to_do > sample_count) + samples_to_do=sample_count-samples_written; + + { + int i,j; + for (j=0;j<vgmstream->channels;j++) { + for (i=0;i<frame_size;i++) { + sample_data[i] = read_8bit(vgmstream->ch[j].offset+ + i/vgmstream->interleave_block_size* + vgmstream->interleave_block_size* + vgmstream->channels+ + i%vgmstream->interleave_block_size, + vgmstream->ch[j].streamfile); + } + decode_vgmstream_mem(vgmstream, samples_written, + samples_to_do, buffer, sample_data, j); + } + } + + samples_written += samples_to_do; + vgmstream->current_sample += samples_to_do; + vgmstream->samples_into_block+=samples_to_do; + + if (vgmstream->samples_into_block==samples_this_block) { + int chan; + for (chan=0;chan<vgmstream->channels;chan++) + vgmstream->ch[chan].offset+=frame_size*vgmstream->channels; + vgmstream->samples_into_block=0; + } + + } +} |