diff --git a/src/libvgmstream.vcproj b/src/libvgmstream.vcproj
index 8e13f764..75077171 100644
--- a/src/libvgmstream.vcproj
+++ b/src/libvgmstream.vcproj
@@ -281,7 +281,7 @@
>
-
+
@@ -133,7 +133,7 @@
-
+
diff --git a/src/libvgmstream.vcxproj.filters b/src/libvgmstream.vcxproj.filters
index 7b5afbf1..00c31baf 100644
--- a/src/libvgmstream.vcxproj.filters
+++ b/src/libvgmstream.vcxproj.filters
@@ -107,7 +107,7 @@
meta\Header Files
-
+
meta\Header Files
@@ -170,7 +170,7 @@
meta\Header Files
-
+
meta\Header Files
diff --git a/src/meta/awc_xma_streamfile.h b/src/meta/awc_xma_streamfile.h
index 54106624..17b9799c 100644
--- a/src/meta/awc_xma_streamfile.h
+++ b/src/meta/awc_xma_streamfile.h
@@ -1,245 +1,114 @@
-#ifndef _AWC_XMA_STREAMFILE_H_
-#define _AWC_XMA_STREAMFILE_H_
-#include "../streamfile.h"
-
-
-typedef struct {
- /* config */
- int channel;
- int channel_count;
- size_t block_size;
- off_t stream_offset;
- size_t stream_size;
-
- /* state */
- off_t logical_offset; /* offset that corresponds to physical_offset */
- off_t physical_offset; /* actual file offset */
-
- size_t skip_size; /* size to skip from a block start to reach data start */
- size_t data_size; /* logical size of the block */
-
- size_t logical_size;
-} awc_xma_io_data;
-
-
-static size_t get_block_header_size(STREAMFILE *streamFile, off_t offset, awc_xma_io_data *data);
-static size_t get_repeated_data_size(STREAMFILE *streamFile, off_t next_offset, size_t repeat_samples);
-static size_t get_block_skip_count(STREAMFILE *streamFile, off_t offset, int channel);
-
-/* Reads plain XMA data of a single stream. Each block has a header and channels have different num_samples/frames.
- * Channel data is separate within the block (first all frames of ch0, then ch1, etc), padded, and sometimes
- * the last few frames of a channel are repeated in the new block (marked with the "discard samples" field). */
-static size_t awc_xma_io_read(STREAMFILE *streamfile, uint8_t *dest, off_t offset, size_t length, awc_xma_io_data* data) {
- size_t total_read = 0;
- size_t frame_size = 0x800;
-
- /* ignore bad reads */
- if (offset < 0 || offset > data->logical_size) {
- return 0;
- }
-
- /* previous offset: re-start as we can't map logical<>physical offsets
- * (kinda slow as it trashes buffers, but shouldn't happen often) */
- if (offset < data->logical_offset) {
- data->logical_offset = 0x00;
- data->physical_offset = data->stream_offset;
- data->data_size = 0;
- }
-
- /* read blocks, one at a time */
- while (length > 0) {
-
- /* ignore EOF */
- if (data->logical_offset >= data->logical_size) {
- break;
- }
-
- /* process new block */
- if (data->data_size == 0) {
- size_t header_size = get_block_header_size(streamfile, data->physical_offset, data);
- /* header table entries = frames... I hope */
- size_t others_size = get_block_skip_count(streamfile, data->physical_offset, data->channel) * frame_size;
- //size_t skip_size = read_32bitBE(data->physical_offset + 0x10*data->channel + 0x00, streamfile) * frame_size;
- size_t data_size = read_32bitBE(data->physical_offset + 0x10*data->channel + 0x04, streamfile) * frame_size;
- size_t repeat_samples = read_32bitBE(data->physical_offset + 0x10*data->channel + 0x08, streamfile);
- size_t repeat_size = 0;
-
-
- /* if there are repeat samples current block repeats some frames from last block, find out size */
- if (repeat_samples) {
- off_t data_offset = data->physical_offset + header_size + others_size;
- repeat_size = get_repeated_data_size(streamfile, data_offset, repeat_samples);
- }
-
- data->skip_size = header_size + others_size + repeat_size;
- data->data_size = data_size - repeat_size;
- }
-
- /* move to next block */
- if (offset >= data->logical_offset + data->data_size) {
- data->physical_offset += data->block_size;
- data->logical_offset += data->data_size;
- data->data_size = 0;
- continue;
- }
-
- /* read data */
- {
- size_t bytes_consumed, bytes_done, to_read;
-
- bytes_consumed = offset - data->logical_offset;
-
- to_read = data->data_size - bytes_consumed;
- if (to_read > length)
- to_read = length;
- bytes_done = read_streamfile(dest, data->physical_offset + data->skip_size + bytes_consumed, to_read, streamfile);
-
- offset += bytes_done;
- total_read += bytes_done;
- length -= bytes_done;
- dest += bytes_done;
-
- if (bytes_done != to_read || bytes_done == 0) {
- break; /* error/EOF */
- }
- }
-
- }
-
- return total_read;
-}
-
-static size_t awc_xma_io_size(STREAMFILE *streamfile, awc_xma_io_data* data) {
- off_t physical_offset, max_physical_offset;
- size_t frame_size = 0x800;
- size_t logical_size = 0;
-
- if (data->logical_size)
- return data->logical_size;
-
- physical_offset = data->stream_offset;
- max_physical_offset = data->stream_offset + data->stream_size;
-
- /* get size of the logical stream */
- while (physical_offset < max_physical_offset) {
- size_t header_size = get_block_header_size(streamfile, physical_offset, data);
- /* header table entries = frames... I hope */
- size_t skip_size = get_block_skip_count(streamfile, physical_offset, data->channel) * frame_size;
- //size_t skip_size = read_32bitBE(physical_offset + 0x10*data->channel + 0x00, streamfile) * frame_size;
- size_t data_size = read_32bitBE(physical_offset + 0x10*data->channel + 0x04, streamfile) * frame_size;
- size_t repeat_samples = read_32bitBE(physical_offset + 0x10*data->channel + 0x08, streamfile);
- size_t repeat_size = 0;
-
- /* if there are repeat samples current block repeats some frames from last block, find out size */
- if (repeat_samples) {
- off_t data_offset = physical_offset + header_size + skip_size;
- repeat_size = get_repeated_data_size(streamfile, data_offset, repeat_samples);
- }
-
- logical_size += data_size - repeat_size;
- physical_offset += data->block_size;
- }
-
- data->logical_size = logical_size;
- return data->logical_size;
-}
-
-
-/* Prepares custom IO for AWC XMA, which is interleaved XMA in AWC blocks */
-static STREAMFILE* setup_awc_xma_streamfile(STREAMFILE *streamFile, off_t stream_offset, size_t stream_size, size_t block_size, int channel_count, int channel) {
- STREAMFILE *temp_streamFile = NULL, *new_streamFile = NULL;
- awc_xma_io_data io_data = {0};
- size_t io_data_size = sizeof(awc_xma_io_data);
-
- io_data.channel = channel;
- io_data.channel_count = channel_count;
- io_data.stream_offset = stream_offset;
- io_data.stream_size = stream_size;
- io_data.block_size = block_size;
- io_data.physical_offset = stream_offset;
- io_data.logical_size = awc_xma_io_size(streamFile, &io_data); /* force init */
-
- if (io_data.logical_size > io_data.stream_size) {
- VGM_LOG("AWC XMA: wrong logical size\n");
- goto fail;
- }
-
- /* setup subfile */
- new_streamFile = open_wrap_streamfile(streamFile);
- if (!new_streamFile) goto fail;
- temp_streamFile = new_streamFile;
-
- new_streamFile = open_io_streamfile(temp_streamFile, &io_data,io_data_size, awc_xma_io_read,awc_xma_io_size);
- if (!new_streamFile) goto fail;
- temp_streamFile = new_streamFile;
-
- new_streamFile = open_buffer_streamfile(new_streamFile,0);
- if (!new_streamFile) goto fail;
- temp_streamFile = new_streamFile;
-
- return temp_streamFile;
-
-fail:
- close_streamfile(temp_streamFile);
- return NULL;
-}
-
-/* block header size, aligned/padded to 0x800 */
-static size_t get_block_header_size(STREAMFILE *streamFile, off_t offset, awc_xma_io_data *data) {
- size_t header_size = 0;
- int i;
- int entries = data->channel_count;
-
- for (i = 0; i < entries; i++) {
- header_size += 0x10;
- header_size += read_32bitBE(offset + 0x10*i + 0x04, streamFile) * 0x04; /* entries in the table */
- }
-
- if (header_size % 0x800) /* padded */
- header_size += 0x800 - (header_size % 0x800);
-
- return header_size;
-}
-
-
-/* find data that repeats in the beginning of a new block at the end of last block */
-static size_t get_repeated_data_size(STREAMFILE *streamFile, off_t next_offset, size_t repeat_samples) {
- const size_t frame_size = 0x800;
- const size_t samples_per_subframe = 512;
- size_t samples_this_frame;
- uint8_t subframes;
-
- //todo: fix this
- /* Repeat samples are the number of decoded samples to discard, but in this streamfile we can't do that.
- * Also XMA is VBR, and may encode silent frames with up to 63 subframes yet we may have few repeat samples.
- * We could find out how many subframes of 512 samples to skip, then adjust the XMA frame header, though
- * output will be slightly off since subframes are related.
- *
- * For now just skip a full frame depending on the number of subframes vs repeat samples.
- * Most files work ok-ish but channels may desync slightly. */
-
- subframes = ((uint8_t)read_8bit(next_offset,streamFile) >> 2) & 0x3F; /* peek into frame header */
- samples_this_frame = subframes*samples_per_subframe;
- if (repeat_samples >= (int)(samples_this_frame*0.13)) { /* skip mosts */
- return frame_size;
- }
- else {
- return 0;
- }
-}
-
-/* header has a skip value, but somehow it's sometimes bigger than expected (WHY!?!?) so just sum all */
-static size_t get_block_skip_count(STREAMFILE *streamFile, off_t offset, int channel) {
- size_t skip_count = 0;
- int i;
-
- //skip_size = read_32bitBE(offset + 0x10*channel + 0x00, streamFile); /* wrong! */
- for (i = 0; i < channel; i++) {
- skip_count += read_32bitBE(offset + 0x10*i + 0x04, streamFile); /* number of frames of this channel */
- }
-
- return skip_count;
-}
-
-
-#endif /* _AWC_XMA_STREAMFILE_H_ */
+#ifndef _AWC_XMA_STREAMFILE_H_
+#define _AWC_XMA_STREAMFILE_H_
+#include "deblock_streamfile.h"
+
+
+static size_t get_block_header_size(STREAMFILE* sf, off_t offset, int channels);
+static size_t get_repeated_data_size(STREAMFILE* sf, off_t next_offset, size_t repeat_samples);
+static size_t get_block_skip_count(STREAMFILE* sf, off_t offset, int channel);
+
+static void block_callback(STREAMFILE *sf, deblock_io_data* data) {
+ const size_t frame_size = 0x800;
+ int channel = data->cfg.track_number;
+ int channels = data->cfg.track_count;
+
+ /* Blocks have a header then data per channel, each with a different num_samples/frames,
+ * separate (first all frames of ch0, then ch1, etc), padded, and sometimes the last few
+ * frames of a channel are repeated in the new block (marked with "repeat samples"). */
+ size_t header_size = get_block_header_size(sf, data->physical_offset, channels);
+ /* header table entries = frames... I hope */
+ size_t others_size = get_block_skip_count(sf, data->physical_offset, channel) * frame_size;
+ //size_t skip_size = read_u32be(data->physical_offset + 0x10*channel + 0x00, sf) * frame_size;
+ size_t data_size = read_u32be(data->physical_offset + 0x10*channel + 0x04, sf) * frame_size;
+ size_t repeat_samples = read_u32be(data->physical_offset + 0x10*channel + 0x08, sf);
+ size_t repeat_size = 0;
+
+ data->block_size = data->cfg.chunk_size;
+
+ /* if there are repeat samples current block repeats some frames from last block, find out size */
+ if (repeat_samples) {
+ off_t data_offset = data->physical_offset + header_size + others_size;
+ repeat_size = get_repeated_data_size(sf, data_offset, repeat_samples);
+ }
+
+ data->skip_size = header_size + others_size + repeat_size;
+ data->data_size = data_size - repeat_size;
+}
+
+/* block header size, aligned/padded to 0x800 */
+static size_t get_block_header_size(STREAMFILE* sf, off_t offset, int channels) {
+ size_t header_size = 0;
+ int i;
+
+ for (i = 0; i < channels; i++) {
+ header_size += 0x10;
+ header_size += read_u32be(offset + 0x10*i + 0x04, sf) * 0x04; /* entries in the table */
+ }
+
+ if (header_size % 0x800) /* padded */
+ header_size += 0x800 - (header_size % 0x800);
+
+ return header_size;
+}
+
+/* find data that repeats in the beginning of a new block at the end of last block */
+static size_t get_repeated_data_size(STREAMFILE* sf, off_t next_offset, size_t repeat_samples) {
+ const size_t frame_size = 0x800;
+ const size_t samples_per_subframe = 512;
+ size_t samples_this_frame;
+ uint8_t subframes;
+
+ //todo: fix this
+ /* Repeat samples are the number of decoded samples to discard, but in this streamfile we can't do that.
+ * Also XMA is VBR, and may encode silent frames with up to 63 subframes yet we may have few repeat samples.
+ * We could find out how many subframes of 512 samples to skip, then adjust the XMA frame header, though
+ * output will be slightly off since subframes are related.
+ *
+ * For now just skip a full frame depending on the number of subframes vs repeat samples.
+ * Most files work ok-ish but channels may desync slightly. */
+
+ subframes = ((uint8_t)read_8bit(next_offset,sf) >> 2) & 0x3F; /* peek into frame header */
+ samples_this_frame = subframes*samples_per_subframe;
+ if (repeat_samples >= (int)(samples_this_frame*0.13)) { /* skip mosts */
+ return frame_size;
+ }
+ else {
+ return 0;
+ }
+}
+
+/* header has a skip value, but somehow it's sometimes bigger than expected (WHY!?!?) so just sum all */
+static size_t get_block_skip_count(STREAMFILE* sf, off_t offset, int channel) {
+ size_t skip_count = 0;
+ int i;
+
+ //skip_size = read_u32be(offset + 0x10*channel + 0x00, sf); /* wrong! */
+ for (i = 0; i < channel; i++) {
+ skip_count += read_u32be(offset + 0x10*i + 0x04, sf); /* number of frames of this channel */
+ }
+
+ return skip_count;
+}
+
+
+/* Deblocks interleaved XMA in AWC blocks */
+static STREAMFILE* setup_awc_xma_streamfile(STREAMFILE *sf, off_t stream_offset, size_t stream_size, size_t block_size, int channel_count, int channel) {
+ STREAMFILE *new_sf = NULL;
+ deblock_config_t cfg = {0};
+
+ cfg.track_number = channel;
+ cfg.track_count = channel_count;
+ cfg.stream_start = stream_offset;
+ cfg.stream_size = stream_size;
+ cfg.chunk_size = block_size;
+ //cfg.physical_offset = stream_offset;
+ //cfg.logical_size = awc_xma_io_size(sf, &cfg); /* force init */
+ cfg.block_callback = block_callback;
+
+ new_sf = open_wrap_streamfile(sf);
+ new_sf = open_io_deblock_streamfile_f(new_sf, &cfg);
+ //new_sf = open_buffer_streamfile_f(new_sf, 0);
+ return new_sf;
+}
+
+#endif /* _AWC_XMA_STREAMFILE_H_ */
diff --git a/src/meta/fsb5.c b/src/meta/fsb5.c
index 9dafb211..58107cd4 100644
--- a/src/meta/fsb5.c
+++ b/src/meta/fsb5.c
@@ -1,7 +1,7 @@
#include "meta.h"
#include "../coding/coding.h"
#include "../layout/layout.h"
-#include "fsb5_interleave_streamfile.h"
+#include "fsb5_streamfile.h"
typedef struct {
@@ -533,7 +533,7 @@ static layered_layout_data* build_layered_fsb5_celt(STREAMFILE *streamFile, fsb5
goto fail;
#endif
- temp_streamFile = setup_fsb5_interleave_streamfile(streamFile, fsb5->stream_offset, fsb5->stream_size, layers, i, FSB5_INT_CELT, interleave);
+ temp_streamFile = setup_fsb5_streamfile(streamFile, fsb5->stream_offset, fsb5->stream_size, layers, i, interleave);
if (!temp_streamFile) goto fail;
if (!vgmstream_open_stream(data->layers[i], temp_streamFile, 0x00))
@@ -609,7 +609,7 @@ static layered_layout_data* build_layered_fsb5_atrac9(STREAMFILE *streamFile, fs
goto fail;
#endif
- temp_streamFile = setup_fsb5_interleave_streamfile(streamFile, fsb5->stream_offset, fsb5->stream_size, layers, i, FSB5_INT_ATRAC9, interleave);
+ temp_streamFile = setup_fsb5_streamfile(streamFile, fsb5->stream_offset, fsb5->stream_size, layers, i, interleave);
if (!temp_streamFile) goto fail;
if (!vgmstream_open_stream(data->layers[i], temp_streamFile, 0x00))
diff --git a/src/meta/fsb5_interleave_streamfile.h b/src/meta/fsb5_interleave_streamfile.h
deleted file mode 100644
index d9cb14c2..00000000
--- a/src/meta/fsb5_interleave_streamfile.h
+++ /dev/null
@@ -1,201 +0,0 @@
-#ifndef _FSB5_INTERLEAVE_STREAMFILE_H_
-#define _FSB5_INTERLEAVE_STREAMFILE_H_
-#include "../streamfile.h"
-
-typedef enum { FSB5_INT_CELT, FSB5_INT_ATRAC9 } fsb_interleave_codec_t;
-typedef struct {
- /* state */
- off_t logical_offset; /* offset that corresponds to physical_offset */
- off_t physical_offset; /* actual file offset */
- int skip_frames; /* frames to skip from other streams at points */
-
- /* config */
- fsb_interleave_codec_t codec;
- size_t interleave;
- int stream_count;
- int stream_number;
- size_t stream_size;
- off_t start_offset; /* pointing to the stream's beginning */
- size_t total_size; /* size of the resulting substream */
-} fsb_interleave_io_data;
-
-
-
-/* Reads skipping other streams */
-static size_t fsb_interleave_io_read(STREAMFILE *streamfile, uint8_t *dest, off_t offset, size_t length, fsb_interleave_io_data* data) {
- size_t total_read = 0;
-
- /* ignore bad reads */
- if (offset < 0 || offset > data->total_size) {
- return total_read;
- }
-
- /* previous offset: re-start as we can't map logical<>physical offsets
- * (kinda slow as it trashes buffers, but shouldn't happen often) */
- if (offset < data->logical_offset) {
- data->physical_offset = data->start_offset;
- data->logical_offset = 0x00;
- data->skip_frames = data->stream_number;
- }
-
- /* read doing one frame at a time */
- while (length > 0) {
- size_t to_read, bytes_read;
- off_t intrablock_offset, intradata_offset;
- uint32_t data_size;
-
- if (offset >= data->total_size)
- break;
-
- /* get current data */
- switch (data->codec) {
- case FSB5_INT_CELT:
- case FSB5_INT_ATRAC9:
- data_size = data->interleave;
- break;
-
- default:
- return 0;
- }
-
- /* skip frames from other streams */
- if (data->skip_frames) {
- data->physical_offset += data_size;
- data->skip_frames--;
- continue;
- }
-
- /* requested offset is outside current block, try next */
- if (offset >= data->logical_offset + data_size) {
- data->physical_offset += data_size;
- data->logical_offset += data_size;
- data->skip_frames = data->stream_count - 1;
- continue;
- }
-
- /* reads could fall in the middle of the block */
- intradata_offset = offset - data->logical_offset;
- intrablock_offset = intradata_offset;
-
- /* clamp reads up to this block's end */
- to_read = (data_size - intradata_offset);
- if (to_read > length)
- to_read = length;
- if (to_read == 0)
- break; /* should never happen... */
-
- /* finally read and move buffer/offsets */
- bytes_read = read_streamfile(dest, data->physical_offset + intrablock_offset, to_read, streamfile);
- total_read += bytes_read;
- if (bytes_read != to_read)
- break; /* couldn't read fully */
-
- dest += bytes_read;
- offset += bytes_read;
- length -= bytes_read;
-
- /* block fully read, go next */
- if (intradata_offset + bytes_read == data_size) {
- data->physical_offset += data_size;
- data->logical_offset += data_size;
- data->skip_frames = data->stream_count - 1;
- }
- }
-
- return total_read;
-}
-
-static size_t fsb_interleave_io_size(STREAMFILE *streamfile, fsb_interleave_io_data* data) {
- off_t physical_offset, max_physical_offset;
- size_t total_size = 0;
- int skip_frames = 0;
-
- if (data->total_size)
- return data->total_size;
-
- physical_offset = data->start_offset;
- max_physical_offset = physical_offset + data->stream_size;
- skip_frames = data->stream_number;
-
- /* get size of the underlying stream, skipping other streams
- * (all streams should have the same frame count) */
- while (physical_offset < max_physical_offset) {
- size_t data_size;
-
- data_size = data->interleave;
- switch(data->codec) {
- case FSB5_INT_CELT:
- case FSB5_INT_ATRAC9:
- data_size = data->interleave;
- break;
-
- default:
- return 0;
- }
-
- /* there may be padding at the end, so this doubles as EOF marker */
- if (data_size == 0)
- break;
- if (physical_offset+data_size > max_physical_offset)
- break;
-
- /* skip frames from other streams */
- if (skip_frames) {
- physical_offset += data_size;
- skip_frames--;
- continue;
- }
-
- physical_offset += data_size;
- total_size += data_size;
- skip_frames = data->stream_count - 1;
- }
-
- data->total_size = total_size;
- return data->total_size;
-}
-
-
-/* Prepares custom IO for multistreams, interleaves 1 packet per stream */
-static STREAMFILE* setup_fsb5_interleave_streamfile(STREAMFILE *streamFile, off_t start_offset, size_t stream_size, int stream_count, int stream_number, fsb_interleave_codec_t codec, size_t interleave) {
- STREAMFILE *temp_streamFile = NULL, *new_streamFile = NULL;
- fsb_interleave_io_data io_data = {0};
- size_t io_data_size = sizeof(fsb_interleave_io_data);
-
- io_data.start_offset = start_offset;
- io_data.physical_offset = start_offset;
- io_data.skip_frames = stream_number; /* adjust since start_offset points to the first */
- io_data.codec = codec;
- io_data.interleave = interleave;
- io_data.stream_count = stream_count;
- io_data.stream_number = stream_number;
- io_data.stream_size = stream_size; /* full size for all streams */
-
- io_data.total_size = fsb_interleave_io_size(streamFile, &io_data); /* force init, size of a single stream */
-
- if (io_data.total_size == 0 || io_data.total_size > io_data.stream_size) {
- VGM_LOG("FSB5 INTERLEAVE: wrong total_size %x vs %x\n", io_data.total_size,io_data.stream_size);
- goto fail;
- }
-
- /* setup subfile */
- new_streamFile = open_wrap_streamfile(streamFile);
- if (!new_streamFile) goto fail;
- temp_streamFile = new_streamFile;
-
- new_streamFile = open_io_streamfile(temp_streamFile, &io_data,io_data_size, fsb_interleave_io_read,fsb_interleave_io_size);
- if (!new_streamFile) goto fail;
- temp_streamFile = new_streamFile;
-
- new_streamFile = open_buffer_streamfile(new_streamFile,0);
- if (!new_streamFile) goto fail;
- temp_streamFile = new_streamFile;
-
- return temp_streamFile;
-
-fail:
- close_streamfile(temp_streamFile);
- return NULL;
-}
-
-#endif /* _FSB_INTERLEAVE_STREAMFILE_H_ */
diff --git a/src/meta/fsb5_streamfile.h b/src/meta/fsb5_streamfile.h
new file mode 100644
index 00000000..19175148
--- /dev/null
+++ b/src/meta/fsb5_streamfile.h
@@ -0,0 +1,21 @@
+#ifndef _FSB5_STREAMFILE_H_
+#define _FSB5_STREAMFILE_H_
+#include "deblock_streamfile.h"
+
+static STREAMFILE* setup_fsb5_streamfile(STREAMFILE* sf, off_t stream_start, size_t stream_size, int stream_count, int stream_number, size_t interleave) {
+ STREAMFILE* new_sf = NULL;
+ deblock_config_t cfg = {0};
+
+ cfg.stream_start = stream_start;
+ cfg.stream_size = stream_size;
+ cfg.chunk_size = interleave;
+ cfg.step_start = stream_number;
+ cfg.step_count = stream_count;
+
+ /* setup sf */
+ new_sf = open_wrap_streamfile(sf);
+ new_sf = open_io_deblock_streamfile_f(new_sf, &cfg);
+ return new_sf;
+}
+
+#endif /* _FSB5_STREAMFILE_H_ */
diff --git a/src/meta/opus.c b/src/meta/opus.c
index 5213a065..932ecef2 100644
--- a/src/meta/opus.c
+++ b/src/meta/opus.c
@@ -172,7 +172,7 @@ VGMSTREAM * init_vgmstream_opus_capcom(STREAMFILE *streamFile) {
/* 0x30+: extra chunks (0x00: 0x7f, 0x04: num_sample), alt loop starts/regions? */
if (channel_count == 6) {
- /* 2ch multistream hacky-hacks, don't try this at home. We'll end up with:
+ /* 2ch multistream hacky-hacks in RE:RE, don't try this at home. We'll end up with:
* main vgmstream > N vgmstream layers > substream IO deinterleaver > opus meta > Opus IO transmogrifier (phew) */
layered_layout_data* data = NULL;
int layers = channel_count / 2;
@@ -193,11 +193,11 @@ VGMSTREAM * init_vgmstream_opus_capcom(STREAMFILE *streamFile) {
/* open each layer subfile */
for (i = 0; i < layers; i++) {
- STREAMFILE* temp_streamFile = setup_opus_interleave_streamfile(streamFile, offset+0x28*i, layers);
- if (!temp_streamFile) goto fail;
+ STREAMFILE* temp_sf = setup_opus_interleave_streamfile(streamFile, offset, i, layers);
+ if (!temp_sf) goto fail;
- data->layers[i] = init_vgmstream_opus(temp_streamFile, meta_OPUS, 0x00, num_samples,loop_start,loop_end);
- close_streamfile(temp_streamFile);
+ data->layers[i] = init_vgmstream_opus(temp_sf, meta_OPUS, 0x00, num_samples,loop_start,loop_end);
+ close_streamfile(temp_sf);
if (!data->layers[i]) goto fail;
}
diff --git a/src/meta/opus_interleave_streamfile.h b/src/meta/opus_interleave_streamfile.h
index 503e8341..4985e403 100644
--- a/src/meta/opus_interleave_streamfile.h
+++ b/src/meta/opus_interleave_streamfile.h
@@ -1,136 +1,47 @@
-#ifndef _OPUS_INTERLEAVE_STREAMFILE_H_
-#define _OPUS_INTERLEAVE_STREAMFILE_H_
-#include "../streamfile.h"
-
-
-typedef struct {
- /* config */
- int streams;
- off_t stream_offset;
-
- /* state */
- off_t logical_offset; /* offset that corresponds to physical_offset */
- off_t physical_offset; /* actual file offset */
- int skip_frames; /* frames to skip from other streams at points */
-
- size_t logical_size;
-} opus_interleave_io_data;
-
-
-/* Reads skipping other streams */
-static size_t opus_interleave_io_read(STREAMFILE *streamfile, uint8_t *dest, off_t offset, size_t length, opus_interleave_io_data* data) {
- size_t total_read = 0;
-
- /* ignore bad reads */
- if (offset < 0 || offset > data->logical_size) {
- return total_read;
- }
-
- /* previous offset: re-start as we can't map logical<>physical offsets (may be VBR) */
- if (offset < data->logical_offset) {
- data->physical_offset = data->stream_offset;
- data->logical_offset = 0x00;
- data->skip_frames = 0;
- }
-
- /* read doing one frame at a time */
- while (length > 0) {
- size_t data_size;
-
- /* ignore EOF */
- if (data->logical_offset >= data->logical_size) {
- break;
- }
-
- /* process block (must be read every time since skip frame sizes may vary) */
- {
- data_size = read_32bitBE(data->physical_offset,streamfile);
- if ((uint32_t)data_size == 0x01000080) //todo not ok if offset between 0 and header_size
- data_size = read_32bitLE(data->physical_offset+0x10,streamfile) + 0x08;
- else
- data_size += 0x08;
- }
-
- /* skip frames from other streams */
- if (data->skip_frames) {
- data->physical_offset += data_size;
- data->skip_frames--;
- continue;
- }
-
- /* move to next block */
- if (offset >= data->logical_offset + data_size) {
- data->physical_offset += data_size;
- data->logical_offset += data_size;
- data->skip_frames = data->streams - 1;
- continue;
- }
-
- /* read data */
- {
- size_t bytes_consumed, bytes_done, to_read;
-
- bytes_consumed = offset - data->logical_offset;
- to_read = data_size - bytes_consumed;
- if (to_read > length)
- to_read = length;
- bytes_done = read_streamfile(dest, data->physical_offset + bytes_consumed, to_read, streamfile);
-
- offset += bytes_done;
- total_read += bytes_done;
- length -= bytes_done;
- dest += bytes_done;
-
- if (bytes_done != to_read || bytes_done == 0) {
- break; /* error/EOF */
- }
- }
- }
-
- return total_read;
-}
-
-static size_t opus_interleave_io_size(STREAMFILE *streamfile, opus_interleave_io_data* data) {
- off_t info_offset;
-
- if (data->logical_size)
- return data->logical_size;
-
- info_offset = read_32bitLE(data->stream_offset+0x10,streamfile);
- data->logical_size = (0x08+info_offset) + read_32bitLE(data->stream_offset+info_offset+0x04,streamfile);
- return data->logical_size;
-}
-
-
-/* Prepares custom IO for multistream, interleaves 1 packet per stream */
-static STREAMFILE* setup_opus_interleave_streamfile(STREAMFILE *streamFile, off_t start_offset, int streams) {
- STREAMFILE *temp_streamFile = NULL, *new_streamFile = NULL;
- opus_interleave_io_data io_data = {0};
- size_t io_data_size = sizeof(opus_interleave_io_data);
-
- io_data.stream_offset = start_offset;
- io_data.streams = streams;
- io_data.physical_offset = start_offset;
- io_data.logical_size = opus_interleave_io_size(streamFile, &io_data); /* force init */
-
- /* setup subfile */
- new_streamFile = open_wrap_streamfile(streamFile);
- if (!new_streamFile) goto fail;
- temp_streamFile = new_streamFile;
-
- new_streamFile = open_io_streamfile(temp_streamFile, &io_data,io_data_size, opus_interleave_io_read,opus_interleave_io_size);
- if (!new_streamFile) goto fail;
- temp_streamFile = new_streamFile;
-
- new_streamFile = open_buffer_streamfile(new_streamFile,0);
- if (!new_streamFile) goto fail;
- temp_streamFile = new_streamFile;
-
- return temp_streamFile;
-
-fail:
- close_streamfile(temp_streamFile);
- return NULL;
-}
-
-#endif /* _OPUS_INTERLEAVE_STREAMFILE_H_ */
+#ifndef _OPUS_INTERLEAVE_STREAMFILE_H_
+#define _OPUS_INTERLEAVE_STREAMFILE_H_
+#include "deblock_streamfile.h"
+
+
+static void block_callback(STREAMFILE* sf, deblock_io_data* data) {
+ uint32_t chunk_size = read_u32be(data->physical_offset, sf);
+
+ //todo not ok if offset between 0 and header_size
+ if (chunk_size == 0x01000080) /* header */
+ chunk_size = read_u32le(data->physical_offset + 0x10, sf) + 0x08;
+ else
+ chunk_size += 0x08;
+ data->block_size = chunk_size;
+ data->data_size = data->block_size;
+}
+
+/* Deblocks NXOPUS streams that interleave 1 packet per stream */
+static STREAMFILE* setup_opus_interleave_streamfile(STREAMFILE* sf, off_t start_offset, int stream_number, int stream_count) {
+ STREAMFILE* new_sf = NULL;
+ deblock_config_t cfg = {0};
+
+ cfg.stream_start = start_offset;
+ cfg.step_start = stream_number;
+ cfg.step_count = stream_count;
+ {
+ int i;
+ off_t offset = start_offset;
+ /* read full size from NXOPUS header N */
+ for (i = 0; i < stream_number + 1; i++) {
+ off_t start = read_s32le(offset + 0x10, sf);
+ off_t size = read_s32le(offset + start + 0x04, sf);
+
+ if (i == stream_number)
+ cfg.logical_size = 0x08 + start + size;
+ offset += 0x08 + start;
+ }
+ }
+ cfg.block_callback = block_callback;
+
+ new_sf = open_wrap_streamfile(sf);
+ new_sf = open_io_deblock_streamfile_f(new_sf, &cfg);
+ //new_sf = open_buffer_streamfile_f(new_sf, 0);
+ return new_sf;
+}
+
+#endif /* _OPUS_INTERLEAVE_STREAMFILE_H_ */
diff --git a/src/meta/sqex_sead_streamfile.h b/src/meta/sqex_sead_streamfile.h
index 98cad928..25f567c8 100644
--- a/src/meta/sqex_sead_streamfile.h
+++ b/src/meta/sqex_sead_streamfile.h
@@ -1,86 +1,67 @@
-#ifndef _SQEX_SEAD_STREAMFILE_H_
-#define _SQEX_SEAD_STREAMFILE_H_
-#include "../streamfile.h"
-
-static STREAMFILE* setup_sqex_sead_streamfile(STREAMFILE *streamFile, off_t subfile_offset, size_t subfile_size, int encryption, size_t header_size, size_t key_start);
-
-
-typedef struct {
- size_t header_size;
- size_t key_start;
-} sqex_sead_decryption_data;
-
-
-static size_t sqex_sead_decryption_read(STREAMFILE *streamfile, uint8_t *dest, off_t offset, size_t length, sqex_sead_decryption_data* data) {
- /* Found in FFXII_TZA.exe (same key in SCD Ogg V3) */
- static const uint8_t encryption_key[0x100] = {
- 0x3A,0x32,0x32,0x32,0x03,0x7E,0x12,0xF7,0xB2,0xE2,0xA2,0x67,0x32,0x32,0x22,0x32, // 00-0F
- 0x32,0x52,0x16,0x1B,0x3C,0xA1,0x54,0x7B,0x1B,0x97,0xA6,0x93,0x1A,0x4B,0xAA,0xA6, // 10-1F
- 0x7A,0x7B,0x1B,0x97,0xA6,0xF7,0x02,0xBB,0xAA,0xA6,0xBB,0xF7,0x2A,0x51,0xBE,0x03, // 20-2F
- 0xF4,0x2A,0x51,0xBE,0x03,0xF4,0x2A,0x51,0xBE,0x12,0x06,0x56,0x27,0x32,0x32,0x36, // 30-3F
- 0x32,0xB2,0x1A,0x3B,0xBC,0x91,0xD4,0x7B,0x58,0xFC,0x0B,0x55,0x2A,0x15,0xBC,0x40, // 40-4F
- 0x92,0x0B,0x5B,0x7C,0x0A,0x95,0x12,0x35,0xB8,0x63,0xD2,0x0B,0x3B,0xF0,0xC7,0x14, // 50-5F
- 0x51,0x5C,0x94,0x86,0x94,0x59,0x5C,0xFC,0x1B,0x17,0x3A,0x3F,0x6B,0x37,0x32,0x32, // 60-6F
- 0x30,0x32,0x72,0x7A,0x13,0xB7,0x26,0x60,0x7A,0x13,0xB7,0x26,0x50,0xBA,0x13,0xB4, // 70-7F
- 0x2A,0x50,0xBA,0x13,0xB5,0x2E,0x40,0xFA,0x13,0x95,0xAE,0x40,0x38,0x18,0x9A,0x92, // 80-8F
- 0xB0,0x38,0x00,0xFA,0x12,0xB1,0x7E,0x00,0xDB,0x96,0xA1,0x7C,0x08,0xDB,0x9A,0x91, // 90-9F
- 0xBC,0x08,0xD8,0x1A,0x86,0xE2,0x70,0x39,0x1F,0x86,0xE0,0x78,0x7E,0x03,0xE7,0x64, // A0-AF
- 0x51,0x9C,0x8F,0x34,0x6F,0x4E,0x41,0xFC,0x0B,0xD5,0xAE,0x41,0xFC,0x0B,0xD5,0xAE, // B0-BF
- 0x41,0xFC,0x3B,0x70,0x71,0x64,0x33,0x32,0x12,0x32,0x32,0x36,0x70,0x34,0x2B,0x56, // C0-CF
- 0x22,0x70,0x3A,0x13,0xB7,0x26,0x60,0xBA,0x1B,0x94,0xAA,0x40,0x38,0x00,0xFA,0xB2, // D0-DF
- 0xE2,0xA2,0x67,0x32,0x32,0x12,0x32,0xB2,0x32,0x32,0x32,0x32,0x75,0xA3,0x26,0x7B, // E0-EF
- 0x83,0x26,0xF9,0x83,0x2E,0xFF,0xE3,0x16,0x7D,0xC0,0x1E,0x63,0x21,0x07,0xE3,0x01, // F0-FF
- };
- size_t bytes_read;
- off_t encrypted_offset = data->header_size;
- int i;
-
- bytes_read = streamfile->read(streamfile, dest, offset, length);
-
- /* decrypt data (xor) */
- if (offset >= encrypted_offset) {
- for (i = 0; i < bytes_read; i++) {
- dest[i] ^= encryption_key[(data->key_start + (offset - encrypted_offset) + i) % 0x100];
- }
- }
-
- return bytes_read;
-}
-
-/* decrypts subfile if neccessary */
-static STREAMFILE* setup_sqex_sead_streamfile(STREAMFILE *streamFile, off_t subfile_offset, size_t subfile_size, int encryption, size_t header_size, size_t key_start) {
- STREAMFILE *temp_streamFile = NULL, *new_streamFile = NULL;
-
- /* setup subfile */
- new_streamFile = open_wrap_streamfile(streamFile);
- if (!new_streamFile) goto fail;
- temp_streamFile = new_streamFile;
-
- new_streamFile = open_clamp_streamfile(temp_streamFile, subfile_offset,subfile_size);
- if (!new_streamFile) goto fail;
- temp_streamFile = new_streamFile;
-
- if (encryption) {
- sqex_sead_decryption_data io_data = {0};
- size_t io_data_size = sizeof(sqex_sead_decryption_data);
-
- io_data.header_size = header_size;
- io_data.key_start = key_start;
-
- new_streamFile = open_io_streamfile(temp_streamFile, &io_data,io_data_size, sqex_sead_decryption_read,NULL);
- if (!new_streamFile) goto fail;
- temp_streamFile = new_streamFile;
- }
-
- new_streamFile = open_fakename_streamfile(temp_streamFile, NULL,"hca");
- if (!new_streamFile) goto fail;
- temp_streamFile = new_streamFile;
-
- return temp_streamFile;
-
-fail:
- close_streamfile(temp_streamFile);
- return NULL;
-}
-
-#endif /* _SQEX_SEAD_STREAMFILE_H_ */
+#ifndef _SQEX_SEAD_STREAMFILE_H_
+#define _SQEX_SEAD_STREAMFILE_H_
+#include "../streamfile.h"
+
+
+typedef struct {
+ size_t start;
+ size_t key_start;
+} sqex_sead_io_data;
+
+
+static size_t sqex_sead_io_read(STREAMFILE *sf, uint8_t *dest, off_t offset, size_t length, sqex_sead_io_data* data) {
+ /* Found in FFXII_TZA.exe (same key in SCD Ogg V3) */
+ static const uint8_t key[0x100] = {
+ 0x3A,0x32,0x32,0x32,0x03,0x7E,0x12,0xF7,0xB2,0xE2,0xA2,0x67,0x32,0x32,0x22,0x32, // 00-0F
+ 0x32,0x52,0x16,0x1B,0x3C,0xA1,0x54,0x7B,0x1B,0x97,0xA6,0x93,0x1A,0x4B,0xAA,0xA6, // 10-1F
+ 0x7A,0x7B,0x1B,0x97,0xA6,0xF7,0x02,0xBB,0xAA,0xA6,0xBB,0xF7,0x2A,0x51,0xBE,0x03, // 20-2F
+ 0xF4,0x2A,0x51,0xBE,0x03,0xF4,0x2A,0x51,0xBE,0x12,0x06,0x56,0x27,0x32,0x32,0x36, // 30-3F
+ 0x32,0xB2,0x1A,0x3B,0xBC,0x91,0xD4,0x7B,0x58,0xFC,0x0B,0x55,0x2A,0x15,0xBC,0x40, // 40-4F
+ 0x92,0x0B,0x5B,0x7C,0x0A,0x95,0x12,0x35,0xB8,0x63,0xD2,0x0B,0x3B,0xF0,0xC7,0x14, // 50-5F
+ 0x51,0x5C,0x94,0x86,0x94,0x59,0x5C,0xFC,0x1B,0x17,0x3A,0x3F,0x6B,0x37,0x32,0x32, // 60-6F
+ 0x30,0x32,0x72,0x7A,0x13,0xB7,0x26,0x60,0x7A,0x13,0xB7,0x26,0x50,0xBA,0x13,0xB4, // 70-7F
+ 0x2A,0x50,0xBA,0x13,0xB5,0x2E,0x40,0xFA,0x13,0x95,0xAE,0x40,0x38,0x18,0x9A,0x92, // 80-8F
+ 0xB0,0x38,0x00,0xFA,0x12,0xB1,0x7E,0x00,0xDB,0x96,0xA1,0x7C,0x08,0xDB,0x9A,0x91, // 90-9F
+ 0xBC,0x08,0xD8,0x1A,0x86,0xE2,0x70,0x39,0x1F,0x86,0xE0,0x78,0x7E,0x03,0xE7,0x64, // A0-AF
+ 0x51,0x9C,0x8F,0x34,0x6F,0x4E,0x41,0xFC,0x0B,0xD5,0xAE,0x41,0xFC,0x0B,0xD5,0xAE, // B0-BF
+ 0x41,0xFC,0x3B,0x70,0x71,0x64,0x33,0x32,0x12,0x32,0x32,0x36,0x70,0x34,0x2B,0x56, // C0-CF
+ 0x22,0x70,0x3A,0x13,0xB7,0x26,0x60,0xBA,0x1B,0x94,0xAA,0x40,0x38,0x00,0xFA,0xB2, // D0-DF
+ 0xE2,0xA2,0x67,0x32,0x32,0x12,0x32,0xB2,0x32,0x32,0x32,0x32,0x75,0xA3,0x26,0x7B, // E0-EF
+ 0x83,0x26,0xF9,0x83,0x2E,0xFF,0xE3,0x16,0x7D,0xC0,0x1E,0x63,0x21,0x07,0xE3,0x01, // F0-FF
+ };
+ int i;
+ size_t bytes = read_streamfile(dest, offset, length, sf);
+
+ /* decrypt data (xor) */
+ //if (offset >= data->start) {
+ for (i = 0; i < bytes; i++) {
+ if (offset + i >= data->start) { //todo recheck
+ dest[i] ^= key[(data->key_start + (offset - data->start) + i) % sizeof(key)];
+ }
+ }
+ //}
+
+ return bytes;
+}
+
+/* decrypts subfile if needed */
+static STREAMFILE* setup_sqex_sead_streamfile(STREAMFILE* sf, off_t subfile_offset, size_t subfile_size, int encryption, size_t header_size, size_t key_start) {
+ STREAMFILE* new_sf = NULL;
+
+ /* setup sf */
+ new_sf = open_wrap_streamfile(sf);
+ new_sf = open_clamp_streamfile_f(new_sf, subfile_offset, subfile_size);
+ if (encryption) {
+ sqex_sead_io_data io_data = {0};
+
+ io_data.start = header_size;
+ io_data.key_start = key_start;
+
+ new_sf = open_io_streamfile_f(new_sf, &io_data, sizeof(sqex_sead_io_data), sqex_sead_io_read, NULL);
+ }
+
+ new_sf = open_fakename_streamfile_f(new_sf, NULL, "hca");
+ return new_sf;
+}
+
+#endif /* _SQEX_SEAD_STREAMFILE_H_ */
diff --git a/src/meta/ubi_lyn.c b/src/meta/ubi_lyn.c
index 90f1897c..4e8200b8 100644
--- a/src/meta/ubi_lyn.c
+++ b/src/meta/ubi_lyn.c
@@ -1,9 +1,8 @@
#include "meta.h"
#include "../layout/layout.h"
#include "../coding/coding.h"
-#include "ubi_lyn_ogg_streamfile.h"
+#include "ubi_lyn_streamfile.h"
-static STREAMFILE* setup_lyn_streamfile(STREAMFILE *streamFile, off_t subfile_offset, size_t subfile_size);
/* LyN RIFF - from Ubisoft LyN engine games [Red Steel 2 (Wii), Adventures of Tintin (Multi), From Dust (Multi), Just Dance 3/4 (multi)] */
VGMSTREAM * init_vgmstream_ubi_lyn(STREAMFILE *streamFile) {
@@ -111,7 +110,7 @@ VGMSTREAM * init_vgmstream_ubi_lyn(STREAMFILE *streamFile) {
#ifdef VGM_USE_VORBIS
case 0x3157: { /* Ogg (PC), interleaved 1ch */
- size_t interleave_size, stride_size;
+ size_t interleave_size;
layered_layout_data* data = NULL;
int i;
@@ -119,7 +118,6 @@ VGMSTREAM * init_vgmstream_ubi_lyn(STREAMFILE *streamFile) {
goto fail;
interleave_size = read_32bitLE(start_offset+0x04,streamFile);
- stride_size = interleave_size * channel_count;
/* interleave is adjusted so there is no smaller last block, it seems */
vgmstream->coding_type = coding_OGG_VORBIS;
@@ -132,15 +130,15 @@ VGMSTREAM * init_vgmstream_ubi_lyn(STREAMFILE *streamFile) {
/* open each layer subfile */
for (i = 0; i < channel_count; i++) {
- STREAMFILE* temp_streamFile = NULL;
- size_t total_size = read_32bitLE(start_offset+0x08 + 0x04*i,streamFile);
- off_t layer_offset = start_offset+0x08 + 0x04*channel_count + interleave_size*i;
+ STREAMFILE* temp_sf = NULL;
+ size_t logical_size = read_32bitLE(start_offset+0x08 + 0x04*i,streamFile);
+ off_t layer_offset = start_offset + 0x08 + 0x04*channel_count; //+ interleave_size*i;
- temp_streamFile = setup_lyn_ogg_streamfile(streamFile, layer_offset, interleave_size, stride_size, total_size);
- if (!temp_streamFile) goto fail;
+ temp_sf = setup_ubi_lyn_streamfile(streamFile, layer_offset, interleave_size, i, channel_count, logical_size);
+ if (!temp_sf) goto fail;
- data->layers[i] = init_vgmstream_ogg_vorbis(temp_streamFile);
- close_streamfile(temp_streamFile);
+ data->layers[i] = init_vgmstream_ogg_vorbis(temp_sf);
+ close_streamfile(temp_sf);
if (!data->layers[i]) goto fail;
/* could validate between layers, meh */
@@ -229,7 +227,7 @@ fail:
/* LyN RIFF in containers */
VGMSTREAM * init_vgmstream_ubi_lyn_container(STREAMFILE *streamFile) {
VGMSTREAM *vgmstream = NULL;
- STREAMFILE *temp_streamFile = NULL;
+ STREAMFILE *temp_sf = NULL;
off_t subfile_offset;
size_t subfile_size;
@@ -259,35 +257,16 @@ VGMSTREAM * init_vgmstream_ubi_lyn_container(STREAMFILE *streamFile) {
subfile_size = read_32bitLE(subfile_offset+0x04,streamFile) + 0x04+0x04;
- temp_streamFile = setup_lyn_streamfile(streamFile, subfile_offset,subfile_size);
- if (!temp_streamFile) goto fail;
+ temp_sf = setup_subfile_streamfile(streamFile, subfile_offset, subfile_size, NULL);
+ if (!temp_sf) goto fail;
- vgmstream = init_vgmstream_ubi_lyn(temp_streamFile);
+ vgmstream = init_vgmstream_ubi_lyn(temp_sf);
- close_streamfile(temp_streamFile);
+ close_streamfile(temp_sf);
return vgmstream;
fail:
- close_streamfile(temp_streamFile);
+ close_streamfile(temp_sf);
close_vgmstream(vgmstream);
return NULL;
}
-
-static STREAMFILE* setup_lyn_streamfile(STREAMFILE *streamFile, off_t subfile_offset, size_t subfile_size) {
- STREAMFILE *temp_streamFile = NULL, *new_streamFile = NULL;
-
- /* setup subfile */
- new_streamFile = open_wrap_streamfile(streamFile);
- if (!new_streamFile) goto fail;
- temp_streamFile = new_streamFile;
-
- new_streamFile = open_clamp_streamfile(temp_streamFile, subfile_offset,subfile_size);
- if (!new_streamFile) goto fail;
- temp_streamFile = new_streamFile;
-
- return temp_streamFile;
-
-fail:
- close_streamfile(temp_streamFile);
- return NULL;
-}
diff --git a/src/meta/ubi_lyn_ogg_streamfile.h b/src/meta/ubi_lyn_ogg_streamfile.h
deleted file mode 100644
index 364718d3..00000000
--- a/src/meta/ubi_lyn_ogg_streamfile.h
+++ /dev/null
@@ -1,92 +0,0 @@
-#ifndef _LYN_OGG_STREAMFILE_H_
-#define _LYN_OGG_STREAMFILE_H_
-#include "../streamfile.h"
-
-
-typedef struct {
- off_t start_physical_offset; /* interleaved data start, for this substream */
- size_t interleave_block_size; /* max size that can be read before encountering other substreams */
- size_t stride_size; /* step size between interleave blocks (interleave*channels) */
- size_t total_size; /* final size of the deinterleaved substream */
-} lyn_ogg_io_data;
-
-
-/* Handles deinterleaving of complete files, skipping portions or other substreams. */
-static size_t lyn_ogg_io_read(STREAMFILE *streamfile, uint8_t *dest, off_t offset, size_t length, lyn_ogg_io_data* data) {
- size_t total_read = 0;
-
- while (length > 0) {
- size_t to_read;
- size_t length_available;
- off_t block_num;
- off_t intrablock_offset;
- off_t physical_offset;
-
- block_num = offset / data->interleave_block_size;
- intrablock_offset = offset % data->interleave_block_size;
- physical_offset = data->start_physical_offset + block_num*data->stride_size + intrablock_offset;
- length_available = data->interleave_block_size - intrablock_offset;
-
- if (length < length_available) {
- to_read = length;
- }
- else {
- to_read = length_available;
- }
-
- if (to_read > 0) {
- size_t bytes_read;
-
- bytes_read = read_streamfile(dest, physical_offset, to_read, streamfile);
- total_read += bytes_read;
-
- if (bytes_read != to_read) {
- return total_read;
- }
-
- dest += bytes_read;
- offset += bytes_read;
- length -= bytes_read;
- }
- }
-
- return total_read;
-}
-
-static size_t lyn_ogg_io_size(STREAMFILE *streamfile, lyn_ogg_io_data* data) {
- return data->total_size;
-}
-
-
-static STREAMFILE* setup_lyn_ogg_streamfile(STREAMFILE *streamFile, off_t start_offset, size_t interleave_block_size, size_t stride_size, size_t total_size) {
- STREAMFILE *temp_streamFile = NULL, *new_streamFile = NULL;
- lyn_ogg_io_data io_data = {0};
- size_t io_data_size = sizeof(lyn_ogg_io_data);
-
- io_data.start_physical_offset = start_offset;
- io_data.interleave_block_size = interleave_block_size;
- io_data.stride_size = stride_size;
- io_data.total_size = total_size;
-
-
- /* setup subfile */
- new_streamFile = open_wrap_streamfile(streamFile);
- if (!new_streamFile) goto fail;
- temp_streamFile = new_streamFile;
-
- new_streamFile = open_io_streamfile(temp_streamFile, &io_data,io_data_size, lyn_ogg_io_read,lyn_ogg_io_size);
- if (!new_streamFile) goto fail;
- temp_streamFile = new_streamFile;
-
- new_streamFile = open_fakename_streamfile(temp_streamFile, NULL,"ogg");
- if (!new_streamFile) goto fail;
- temp_streamFile = new_streamFile;
-
- return temp_streamFile;
-
-fail:
- close_streamfile(temp_streamFile);
- return NULL;
-}
-
-#endif /* _LYN_OGG_STREAMFILE_H_ */
diff --git a/src/meta/ubi_lyn_streamfile.h b/src/meta/ubi_lyn_streamfile.h
new file mode 100644
index 00000000..ecef0f6d
--- /dev/null
+++ b/src/meta/ubi_lyn_streamfile.h
@@ -0,0 +1,23 @@
+#ifndef _UBI_LYN_STREAMFILE_H_
+#define _UBI_LYN_STREAMFILE_H_
+#include "deblock_streamfile.h"
+
+/* Deinterleaves LYN streams */
+static STREAMFILE* setup_ubi_lyn_streamfile(STREAMFILE* sf, off_t stream_offset, size_t interleave_size, int stream_number, int stream_count, size_t logical_size) {
+ STREAMFILE *new_sf = NULL;
+ deblock_config_t cfg = {0};
+VGM_LOG("so=%lx, chu=%x, n=%i, c=%i, lo=%x\n", stream_offset, interleave_size, stream_number, stream_count, logical_size);
+ cfg.stream_start = stream_offset;
+ cfg.chunk_size = interleave_size;
+ cfg.step_start = stream_number;
+ cfg.step_count = stream_count;
+ cfg.logical_size = logical_size;
+
+ new_sf = open_wrap_streamfile(sf);
+ new_sf = open_io_deblock_streamfile_f(new_sf, &cfg);
+ //new_sf = open_buffer_streamfile_f(new_sf, 0);
+ new_sf = open_fakename_streamfile_f(new_sf, NULL, "ogg");
+ return new_sf;
+}
+
+#endif /* _UBI_LYN_STREAMFILE_H_ */
diff --git a/src/meta/xwma_konami_streamfile.h b/src/meta/xwma_konami_streamfile.h
index d95df459..2332695c 100644
--- a/src/meta/xwma_konami_streamfile.h
+++ b/src/meta/xwma_konami_streamfile.h
@@ -1,125 +1,26 @@
-#ifndef _XWMA_KONAMI_STREAMFILE_H_
-#define _XWMA_KONAMI_STREAMFILE_H_
-#include "../streamfile.h"
-
-
-typedef struct {
- /* config */
- off_t stream_offset;
- size_t stream_size;
- size_t block_align;
-
- /* state */
- off_t logical_offset; /* fake offset */
- off_t physical_offset; /* actual offset */
- size_t block_size; /* current size */
- size_t skip_size; /* size from block start to reach data */
- size_t data_size; /* usable size in a block */
-
- size_t logical_size;
-} xwma_konami_io_data;
-
-
-static size_t xwma_konami_io_read(STREAMFILE *streamfile, uint8_t *dest, off_t offset, size_t length, xwma_konami_io_data* data) {
- size_t total_read = 0;
-
-
- /* re-start when previous offset (can't map logical<>physical offsets) */
- if (data->logical_offset < 0 || offset < data->logical_offset) {
- data->physical_offset = data->stream_offset;
- data->logical_offset = 0x00;
- data->data_size = 0;
- }
-
- /* read blocks */
- while (length > 0) {
-
- /* ignore EOF */
- if (offset < 0 || data->physical_offset >= data->stream_offset + data->stream_size) {
- break;
- }
-
- /* process new block */
- if (data->data_size == 0) {
- data->block_size = align_size_to_block(data->block_align, 0x10);
- data->data_size = data->block_align;
- data->skip_size = 0x00;
- }
-
- /* move to next block */
- if (data->data_size == 0 || offset >= data->logical_offset + data->data_size) {
- data->physical_offset += data->block_size;
- data->logical_offset += data->data_size;
- data->data_size = 0;
- continue;
- }
-
- /* read data */
- {
- size_t bytes_consumed, bytes_done, to_read;
-
- bytes_consumed = offset - data->logical_offset;
- to_read = data->data_size - bytes_consumed;
- if (to_read > length)
- to_read = length;
- bytes_done = read_streamfile(dest, data->physical_offset + data->skip_size + bytes_consumed, to_read, streamfile);
-
- total_read += bytes_done;
- dest += bytes_done;
- offset += bytes_done;
- length -= bytes_done;
-
- if (bytes_done != to_read || bytes_done == 0) {
- break; /* error/EOF */
- }
- }
- }
-
- return total_read;
-}
-
-static size_t xwma_konami_io_size(STREAMFILE *streamfile, xwma_konami_io_data* data) {
- uint8_t buf[1];
-
- if (data->logical_size)
- return data->logical_size;
-
- /* force a fake read at max offset, to get max logical_offset (will be reset next read) */
- xwma_konami_io_read(streamfile, buf, 0x7FFFFFFF, 1, data);
- data->logical_size = data->logical_offset;
-
- return data->logical_size;
-}
-
-/* Handles de-padding Konami XWMA blocked streams */
-static STREAMFILE* setup_xwma_konami_streamfile(STREAMFILE *streamFile, off_t stream_offset, size_t block_align) {
- STREAMFILE *temp_streamFile = NULL, *new_streamFile = NULL;
- xwma_konami_io_data io_data = {0};
- size_t io_data_size = sizeof(xwma_konami_io_data);
-
- io_data.stream_offset = stream_offset;
- io_data.stream_size = get_streamfile_size(streamFile) - stream_offset;
- io_data.block_align = block_align;
- io_data.logical_offset = -1; /* force phys offset reset */
-
- /* setup subfile */
- new_streamFile = open_wrap_streamfile(streamFile);
- if (!new_streamFile) goto fail;
- temp_streamFile = new_streamFile;
-
- new_streamFile = open_io_streamfile(new_streamFile, &io_data,io_data_size, xwma_konami_io_read,xwma_konami_io_size);
- if (!new_streamFile) goto fail;
- temp_streamFile = new_streamFile;
-
- new_streamFile = open_buffer_streamfile(new_streamFile,0);
- if (!new_streamFile) goto fail;
- temp_streamFile = new_streamFile;
-
- return temp_streamFile;
-
-fail:
- close_streamfile(temp_streamFile);
- return NULL;
-}
-
-#endif /* _XWMA_KONAMI_STREAMFILE_H_ */
+#ifndef _XWMA_KONAMI_STREAMFILE_H_
+#define _XWMA_KONAMI_STREAMFILE_H_
+#include "deblock_streamfile.h"
+
+static void block_callback(STREAMFILE* sf, deblock_io_data* data) {
+ data->block_size = align_size_to_block(data->cfg.chunk_size, 0x10);
+ data->data_size = data->cfg.chunk_size;
+ data->skip_size = 0x00;
+}
+
+/* De-pads Konami XWMA streams */
+static STREAMFILE* setup_xwma_konami_streamfile(STREAMFILE* sf, off_t stream_offset, size_t block_align) {
+ STREAMFILE* new_sf = NULL;
+ deblock_config_t cfg = {0};
+
+ cfg.stream_start = stream_offset;
+ cfg.chunk_size = block_align;
+ cfg.block_callback = block_callback;
+
+ new_sf = open_wrap_streamfile(sf);
+ new_sf = open_io_deblock_streamfile_f(new_sf, &cfg);
+ //new_sf = open_buffer_streamfile_f(new_sf, 0);
+ return new_sf;
+}
+
+#endif /* _XWMA_KONAMI_STREAMFILE_H_ */