mirror of
https://github.com/vgmstream/vgmstream.git
synced 2024-11-23 22:41:05 +01:00
cleanup: move defs around
This commit is contained in:
parent
8160794db5
commit
637273bcd9
@ -1,6 +1,7 @@
|
||||
#include <ctype.h>
|
||||
#include "../vgmstream.h"
|
||||
#include "../coding/coding.h"
|
||||
#include "../layout/layout.h"
|
||||
#include "mixing.h"
|
||||
#include "../util/channel_mappings.h"
|
||||
#include "../util/sf_utils.h"
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include "mixer.h"
|
||||
#include "mixer_priv.h"
|
||||
#include "sbuf.h"
|
||||
#include "../layout/layout.h"
|
||||
#include <math.h>
|
||||
#include <limits.h>
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "../vgmstream.h"
|
||||
#include "../util/channel_mappings.h"
|
||||
#include "../layout/layout.h"
|
||||
#include "mixing.h"
|
||||
#include "mixer_priv.h"
|
||||
#include <math.h>
|
||||
|
@ -8,6 +8,14 @@
|
||||
#include "../vgmstream.h"
|
||||
|
||||
|
||||
/* List supported formats and return elements in the list, for plugins that need to know.
|
||||
* The list disables some common formats that may conflict (.wav, .ogg, etc). */
|
||||
const char** vgmstream_get_formats(size_t* size);
|
||||
|
||||
/* same, but for common-but-disabled formats in the above list. */
|
||||
const char** vgmstream_get_common_formats(size_t* size);
|
||||
|
||||
|
||||
/* ****************************************** */
|
||||
/* CONTEXT: simplifies plugin code */
|
||||
/* ****************************************** */
|
||||
|
@ -3,135 +3,148 @@
|
||||
#include "../util.h"
|
||||
|
||||
/* Westwood Studios ADPCM */
|
||||
|
||||
/* Based on Valery V. Anisimovsky's WS-AUD.txt */
|
||||
|
||||
static char WSTable2bit[4] = { -2,-1,0,1 };
|
||||
static char WSTable4bit[16] = { -9,-8,-6,-5,-4,-3,-2,-1, 0, 1, 2, 3, 4, 5 ,6, 8 };
|
||||
static char WSTable2bit[4] = { -2, -1, 0, 1 };
|
||||
static char WSTable4bit[16] = { -9, -8, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 8 };
|
||||
|
||||
/* We pass in the VGMSTREAM here, unlike in other codings, because
|
||||
the decoder has to know about the block structure. */
|
||||
void decode_ws(VGMSTREAM * vgmstream, int channel, sample * outbuf, int channelspacing, int32_t first_sample,
|
||||
int32_t samples_to_do) {
|
||||
VGMSTREAMCHANNEL * stream = &(vgmstream->ch[channel]);
|
||||
/* We pass in the VGMSTREAM here, unlike in other codings, because the decoder has to know about the block structure. */
|
||||
void decode_ws(VGMSTREAM* vgmstream, int channel, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do) {
|
||||
VGMSTREAMCHANNEL* stream = &(vgmstream->ch[channel]);
|
||||
STREAMFILE* sf = stream->streamfile;
|
||||
int16_t hist = stream->adpcm_history1_16;
|
||||
off_t offset = stream->offset;
|
||||
int samples_left_in_frame = stream->samples_left_in_frame;
|
||||
off_t header_off = stream->frame_header_offset;
|
||||
int samples_left_in_frame = stream->ws_samples_left_in_frame;
|
||||
off_t header_offset = stream->ws_frame_header_offset;
|
||||
|
||||
int i;
|
||||
int32_t sample_count;
|
||||
//int i;
|
||||
int32_t sample_count = 0;
|
||||
|
||||
if (vgmstream->ws_output_size == vgmstream->current_block_size) {
|
||||
/* uncompressed, we just need to convert to 16-bit */
|
||||
for (i=first_sample,sample_count=0; i<first_sample+samples_to_do; i++,sample_count+=channelspacing,offset++) {
|
||||
outbuf[sample_count]=((uint8_t)read_8bit(offset,stream->streamfile)-0x80)*0x100;
|
||||
/* uncompressed pcm8 to pcm16 */
|
||||
for (int i = first_sample; i < first_sample + samples_to_do; i++) {
|
||||
outbuf[sample_count] = (read_u8(offset,sf) - 0x80) * 0x100;
|
||||
sample_count += channelspacing;
|
||||
offset++;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
if (first_sample == 0) {
|
||||
hist = 0x80;
|
||||
samples_left_in_frame = 0;
|
||||
}
|
||||
/* actually decompress */
|
||||
for (i=first_sample,sample_count=0; i<first_sample+samples_to_do; ) {
|
||||
uint8_t header;
|
||||
uint8_t count;
|
||||
|
||||
/* decompress */
|
||||
for (int i = first_sample; i < first_sample + samples_to_do; /* manually incremented */) {
|
||||
|
||||
if (samples_left_in_frame == 0) {
|
||||
header_off = offset;
|
||||
header_offset = offset;
|
||||
offset++;
|
||||
}
|
||||
|
||||
header = read_8bit(header_off,stream->streamfile);
|
||||
count = header & 0x3f;
|
||||
switch (header>>6) { /* code */
|
||||
uint8_t header = read_u8(header_offset, sf);
|
||||
uint8_t count = header & 0x3f;
|
||||
uint8_t code = header >> 6;
|
||||
switch (code) { /* code */
|
||||
case 0: /* 2-bit ADPCM */
|
||||
if (samples_left_in_frame == 0) {
|
||||
samples_left_in_frame = (count + 1)*4;
|
||||
}
|
||||
for (;samples_left_in_frame>0 && /* read this frame */
|
||||
i<first_sample+samples_to_do; /* up to samples_to_do */
|
||||
i++,sample_count+=channelspacing, /* done with writing a sample */
|
||||
samples_left_in_frame--) { /* done with reading a sample */
|
||||
int twobit = ((count + 1)*4-samples_left_in_frame)%4;
|
||||
uint8_t sample;
|
||||
sample = read_8bit(offset,stream->streamfile);
|
||||
sample = (sample >> (twobit*2)) & 0x3;
|
||||
if (samples_left_in_frame == 0)
|
||||
samples_left_in_frame = (count + 1) * 4;
|
||||
|
||||
/* read this frame up to samples_to_do */
|
||||
for ( ; samples_left_in_frame>0 && i < first_sample + samples_to_do; i++) {
|
||||
|
||||
int twobit = ((count + 1) * 4 - samples_left_in_frame) % 4;
|
||||
uint8_t sample = read_u8(offset,sf);
|
||||
sample = (sample >> (twobit * 2)) & 0x3;
|
||||
hist += WSTable2bit[sample];
|
||||
|
||||
if (hist < 0) hist = 0;
|
||||
if (hist > 0xff) hist = 0xff;
|
||||
outbuf[sample_count]=(hist-0x80)*0x100;
|
||||
else if (hist > 0xff) hist = 0xff;
|
||||
|
||||
outbuf[sample_count] = (hist - 0x80) * 0x100;
|
||||
sample_count += channelspacing;
|
||||
samples_left_in_frame--;
|
||||
|
||||
if (twobit == 3)
|
||||
offset++; /* done with that byte */
|
||||
}
|
||||
break;
|
||||
|
||||
case 1: /* 4-bit ADPCM */
|
||||
if (samples_left_in_frame == 0) {
|
||||
samples_left_in_frame = (count + 1)*2;
|
||||
}
|
||||
for (;samples_left_in_frame>0 && /* read this frame */
|
||||
i<first_sample+samples_to_do; /* up to samples_to_do */
|
||||
i++,sample_count+=channelspacing, /* done with writing a sample */
|
||||
samples_left_in_frame--) { /* done with reading a sample */
|
||||
int nibble = ((count + 1)*4-samples_left_in_frame)%2;
|
||||
uint8_t sample;
|
||||
sample = read_8bit(offset,stream->streamfile);
|
||||
if (samples_left_in_frame == 0)
|
||||
samples_left_in_frame = (count + 1) * 2;
|
||||
|
||||
/* read this frame up to samples_to_do */
|
||||
for ( ; samples_left_in_frame>0 && i < first_sample + samples_to_do; i++) {
|
||||
|
||||
int nibble = ((count + 1) * 4 - samples_left_in_frame) % 2;
|
||||
uint8_t sample = read_u8(offset, sf);
|
||||
if (nibble == 0)
|
||||
sample &= 0xf;
|
||||
else
|
||||
sample >>= 4;
|
||||
hist += WSTable4bit[sample];
|
||||
|
||||
if (hist < 0) hist = 0;
|
||||
if (hist > 0xff) hist = 0xff;
|
||||
outbuf[sample_count]=(hist-0x80)*0x100;
|
||||
else if (hist > 0xff) hist = 0xff;
|
||||
|
||||
outbuf[sample_count] = (hist - 0x80) * 0x100;
|
||||
sample_count += channelspacing;
|
||||
samples_left_in_frame--;
|
||||
|
||||
if (nibble == 1)
|
||||
offset++; /* done with that byte */
|
||||
}
|
||||
break;
|
||||
|
||||
case 2: /* no compression */
|
||||
if (count & 0x20) { /* delta */
|
||||
/* Note no checks against samples_to_do here,
|
||||
at the top of the for loop we can always do at
|
||||
least one sample */
|
||||
if (count & 0x20) { /* new delta */
|
||||
/* Note no checks against samples_to_do here, at the top of the for loop
|
||||
* we can always do at least one sample */
|
||||
|
||||
/* low 5 bits are a signed delta */
|
||||
if (count & 0x10) {
|
||||
hist -= ((count & 0xf)^0xf) + 1;
|
||||
hist -= ((count & 0x0f) ^ 0x0f) + 1;
|
||||
} else {
|
||||
hist += count & 0xf;
|
||||
hist += count & 0x0f;
|
||||
}
|
||||
|
||||
/* Valery doesn't specify this, but I will assume */
|
||||
/* Valery doesn't specify this, but clamp just in case */
|
||||
if (hist < 0) hist = 0;
|
||||
if (hist > 0xff) hist = 0xff;
|
||||
else if (hist > 0xff) hist = 0xff;
|
||||
|
||||
outbuf[sample_count]=(hist-0x80)*0x100;
|
||||
sample_count+=channelspacing;
|
||||
i++;
|
||||
|
||||
/* just one, and we got it */
|
||||
samples_left_in_frame = 0;
|
||||
} else { /* copy bytes verbatim */
|
||||
outbuf[sample_count] = (hist - 0x80) * 0x100;
|
||||
sample_count += channelspacing;
|
||||
samples_left_in_frame = 0; /* just one */
|
||||
}
|
||||
else {
|
||||
/* copy bytes verbatim */
|
||||
if (samples_left_in_frame == 0)
|
||||
samples_left_in_frame=count+1;
|
||||
for (;samples_left_in_frame>0 && /* read this frame */
|
||||
i<first_sample+samples_to_do; /* up to samples_to_do */
|
||||
offset++, /* done with a byte */
|
||||
i++,sample_count+=channelspacing, /* done with writing a sample */
|
||||
samples_left_in_frame--) { /* done with reading a sample */
|
||||
outbuf[sample_count]=((hist=(uint8_t)read_8bit(offset,stream->streamfile))-0x80)*0x100;
|
||||
samples_left_in_frame = (count + 1);
|
||||
|
||||
/* read this frame up to samples_to_do */
|
||||
for ( ; samples_left_in_frame > 0 && i < first_sample + samples_to_do; i++) {
|
||||
hist = read_u8(offset,sf);
|
||||
offset++;
|
||||
|
||||
outbuf[sample_count] = (hist - 0x80) * 0x100;
|
||||
sample_count += channelspacing;
|
||||
samples_left_in_frame--;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 3: /* RLE */
|
||||
if (samples_left_in_frame == 0)
|
||||
samples_left_in_frame=count+1;
|
||||
for (;samples_left_in_frame>0 && /* read this frame */
|
||||
i<first_sample+samples_to_do; /* up to samples_to_do */
|
||||
i++,sample_count+=channelspacing, /* done with writing a sample */
|
||||
samples_left_in_frame--) { /* done with reading a sample */
|
||||
outbuf[sample_count]=(hist-0x80)*0x100;
|
||||
samples_left_in_frame = (count + 1);
|
||||
|
||||
/* read this frame up to samples_to_do */
|
||||
for ( ; samples_left_in_frame > 0 && i < first_sample + samples_to_do; i++) {
|
||||
outbuf[sample_count] = (hist - 0x80) * 0x100;
|
||||
sample_count += channelspacing;
|
||||
samples_left_in_frame--;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
@ -141,6 +154,6 @@ void decode_ws(VGMSTREAM * vgmstream, int channel, sample * outbuf, int channels
|
||||
|
||||
stream->offset = offset;
|
||||
stream->adpcm_history1_16 = hist;
|
||||
stream->samples_left_in_frame = samples_left_in_frame;
|
||||
stream->frame_header_offset = header_off;
|
||||
stream->ws_samples_left_in_frame = samples_left_in_frame;
|
||||
stream->ws_frame_header_offset = header_offset;
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "vgmstream.h"
|
||||
#include "coding/coding.h"
|
||||
#include "layout/layout.h"
|
||||
|
||||
|
||||
/* Defines the list of accepted extensions. vgmstream doesn't use it internally so it's here
|
||||
@ -1237,7 +1238,7 @@ static const meta_info meta_info_list[] = {
|
||||
{meta_EB_SF0, "assumed Excitebots .sf0 by extension"},
|
||||
{meta_MTAF, "Konami MTAF header"},
|
||||
{meta_ALP, "High Voltage ALP header"},
|
||||
{meta_WPD, "WPD 'DPW' header"},
|
||||
{meta_WPD, "Navel WPD header"},
|
||||
{meta_MN_STR, "Mini Ninjas 'STR' header"},
|
||||
{meta_MSS, "Guerilla MCSS header"},
|
||||
{meta_PS2_HSF, "Lowrider 'HSF' header"},
|
||||
|
@ -6,6 +6,53 @@
|
||||
#include "../util/reader_sf.h"
|
||||
#include "../util/log.h"
|
||||
|
||||
/* basic layouts */
|
||||
void render_vgmstream_flat(sample_t* buffer, int32_t sample_count, VGMSTREAM* vgmstream);
|
||||
|
||||
void render_vgmstream_interleave(sample_t* buffer, int32_t sample_count, VGMSTREAM* vgmstream);
|
||||
|
||||
/* segmented layout */
|
||||
/* for files made of "continuous" segments, one per section of a song (using a complete sub-VGMSTREAM) */
|
||||
typedef struct {
|
||||
int segment_count;
|
||||
VGMSTREAM** segments;
|
||||
int current_segment;
|
||||
sample_t* buffer;
|
||||
int input_channels; /* internal buffer channels */
|
||||
int output_channels; /* resulting channels (after mixing, if applied) */
|
||||
int mixed_channels; /* segments have different number of channels */
|
||||
} segmented_layout_data;
|
||||
|
||||
void render_vgmstream_segmented(sample_t* buffer, int32_t sample_count, VGMSTREAM* vgmstream);
|
||||
segmented_layout_data* init_layout_segmented(int segment_count);
|
||||
int setup_layout_segmented(segmented_layout_data* data);
|
||||
void free_layout_segmented(segmented_layout_data* data);
|
||||
void reset_layout_segmented(segmented_layout_data* data);
|
||||
void seek_layout_segmented(VGMSTREAM* vgmstream, int32_t seek_sample);
|
||||
void loop_layout_segmented(VGMSTREAM* vgmstream, int32_t loop_sample);
|
||||
VGMSTREAM* allocate_segmented_vgmstream(segmented_layout_data* data, int loop_flag, int loop_start_segment, int loop_end_segment);
|
||||
|
||||
/* layered layout */
|
||||
/* for files made of "parallel" layers, one per group of channels (using a complete sub-VGMSTREAM) */
|
||||
typedef struct {
|
||||
int layer_count;
|
||||
VGMSTREAM** layers;
|
||||
sample_t* buffer;
|
||||
int input_channels; /* internal buffer channels */
|
||||
int output_channels; /* resulting channels (after mixing, if applied) */
|
||||
int external_looping; /* don't loop using per-layer loops, but layout's own looping */
|
||||
int curr_layer; /* helper */
|
||||
} layered_layout_data;
|
||||
|
||||
void render_vgmstream_layered(sample_t* buffer, int32_t sample_count, VGMSTREAM* vgmstream);
|
||||
layered_layout_data* init_layout_layered(int layer_count);
|
||||
int setup_layout_layered(layered_layout_data* data);
|
||||
void free_layout_layered(layered_layout_data* data);
|
||||
void reset_layout_layered(layered_layout_data* data);
|
||||
void seek_layout_layered(VGMSTREAM* vgmstream, int32_t seek_sample);
|
||||
void loop_layout_layered(VGMSTREAM* vgmstream, int32_t loop_sample);
|
||||
VGMSTREAM* allocate_layered_vgmstream(layered_layout_data* data);
|
||||
|
||||
/* blocked layouts */
|
||||
void render_vgmstream_blocked(sample_t* buffer, int32_t sample_count, VGMSTREAM* vgmstream);
|
||||
void block_update(off_t block_offset, VGMSTREAM* vgmstream);
|
||||
@ -51,27 +98,4 @@ void block_update_ubi_sce(off_t block_offset, VGMSTREAM* vgmstream);
|
||||
void block_update_tt_ad(off_t block_offset, VGMSTREAM* vgmstream);
|
||||
void block_update_vas(off_t block_offset, VGMSTREAM* vgmstream);
|
||||
|
||||
/* other layouts */
|
||||
void render_vgmstream_interleave(sample_t* buffer, int32_t sample_count, VGMSTREAM* vgmstream);
|
||||
|
||||
void render_vgmstream_flat(sample_t* buffer, int32_t sample_count, VGMSTREAM* vgmstream);
|
||||
|
||||
void render_vgmstream_segmented(sample_t* buffer, int32_t sample_count, VGMSTREAM* vgmstream);
|
||||
segmented_layout_data* init_layout_segmented(int segment_count);
|
||||
int setup_layout_segmented(segmented_layout_data* data);
|
||||
void free_layout_segmented(segmented_layout_data* data);
|
||||
void reset_layout_segmented(segmented_layout_data* data);
|
||||
void seek_layout_segmented(VGMSTREAM* vgmstream, int32_t seek_sample);
|
||||
void loop_layout_segmented(VGMSTREAM* vgmstream, int32_t loop_sample);
|
||||
VGMSTREAM *allocate_segmented_vgmstream(segmented_layout_data* data, int loop_flag, int loop_start_segment, int loop_end_segment);
|
||||
|
||||
void render_vgmstream_layered(sample_t* buffer, int32_t sample_count, VGMSTREAM* vgmstream);
|
||||
layered_layout_data* init_layout_layered(int layer_count);
|
||||
int setup_layout_layered(layered_layout_data* data);
|
||||
void free_layout_layered(layered_layout_data* data);
|
||||
void reset_layout_layered(layered_layout_data* data);
|
||||
void seek_layout_layered(VGMSTREAM* vgmstream, int32_t seek_sample);
|
||||
void loop_layout_layered(VGMSTREAM* vgmstream, int32_t loop_sample);
|
||||
VGMSTREAM *allocate_layered_vgmstream(layered_layout_data* data);
|
||||
|
||||
#endif
|
||||
|
@ -94,27 +94,28 @@ typedef struct {
|
||||
} play_state_t;
|
||||
|
||||
|
||||
/* info for a single vgmstream channel */
|
||||
/* info for a single vgmstream 'channel' (or rather, mono stream) */
|
||||
typedef struct {
|
||||
STREAMFILE* streamfile; /* file used by this channel */
|
||||
off_t channel_start_offset; /* where data for this channel begins */
|
||||
off_t offset; /* current location in the file */
|
||||
|
||||
off_t frame_header_offset; /* offset of the current frame header (for WS) */
|
||||
int samples_left_in_frame; /* for WS */
|
||||
/* format and channel specific */
|
||||
|
||||
/* format specific */
|
||||
|
||||
/* adpcm */
|
||||
int16_t adpcm_coef[16]; /* formats with decode coefficients built in (DSP, some ADX) */
|
||||
int32_t adpcm_coef_3by32[0x60]; /* Level-5 0x555 */
|
||||
int16_t vadpcm_coefs[8*2*8]; /* VADPCM: max 8 groups * max 2 order * fixed 8 subframe coefs */
|
||||
/* ADPCM with built or variable decode coefficients */
|
||||
union {
|
||||
int16_t adpcm_history1_16; /* previous sample */
|
||||
int16_t adpcm_coef[16]; /* DSP, some ADX (in rare cases may change per block) */
|
||||
int16_t vadpcm_coefs[8*2*8]; /* VADPCM: max 8 groups * max 2 order * fixed 8 subframe = 128 coefs */
|
||||
int32_t adpcm_coef_3by32[96]; /* Level-5 0x555 */
|
||||
};
|
||||
|
||||
/* previous ADPCM samples */
|
||||
union {
|
||||
int16_t adpcm_history1_16;
|
||||
int32_t adpcm_history1_32;
|
||||
};
|
||||
union {
|
||||
int16_t adpcm_history2_16; /* previous previous sample */
|
||||
int16_t adpcm_history2_16;
|
||||
int32_t adpcm_history2_32;
|
||||
};
|
||||
union {
|
||||
@ -129,14 +130,20 @@ typedef struct {
|
||||
//double adpcm_history1_double;
|
||||
//double adpcm_history2_double;
|
||||
|
||||
int adpcm_step_index; /* for IMA */
|
||||
int adpcm_scale; /* for MS ADPCM */
|
||||
/* for ADPCM decoders that store steps (IMA) or scales (MSADPCM) */
|
||||
union {
|
||||
int adpcm_step_index;
|
||||
int adpcm_scale;
|
||||
};
|
||||
|
||||
/* Westwood Studios decoder */
|
||||
off_t ws_frame_header_offset; /* offset of the current frame header */
|
||||
int ws_samples_left_in_frame; /* last decoded info */
|
||||
|
||||
/* state for G.721 decoder, sort of big but we might as well keep it around */
|
||||
struct g72x_state g72x_state;
|
||||
|
||||
/* ADX encryption */
|
||||
int adx_channels;
|
||||
uint16_t adx_xor;
|
||||
uint16_t adx_mult;
|
||||
uint16_t adx_add;
|
||||
@ -147,9 +154,9 @@ typedef struct {
|
||||
/* main vgmstream info */
|
||||
typedef struct {
|
||||
/* basic config */
|
||||
int32_t num_samples; /* the actual max number of samples */
|
||||
int channels; /* number of channels for the current stream */
|
||||
int32_t sample_rate; /* sample rate in Hz */
|
||||
int channels; /* number of channels */
|
||||
int32_t num_samples; /* the actual max number of samples */
|
||||
coding_t coding_type; /* type of encoding */
|
||||
layout_t layout_type; /* type of layout */
|
||||
meta_t meta_type; /* type of metadata */
|
||||
@ -180,13 +187,13 @@ typedef struct {
|
||||
int format_id; /* internal format ID */
|
||||
|
||||
/* layout/block state */
|
||||
size_t full_block_size; /* actual data size of an entire block (ie. may be fixed, include padding/headers, etc) */
|
||||
int32_t current_sample; /* sample point within the file (for loop detection) */
|
||||
int32_t samples_into_block; /* number of samples into the current block/interleave/segment/etc */
|
||||
off_t current_block_offset; /* start of this block (offset of block header) */
|
||||
size_t current_block_size; /* size in usable bytes of the block we're in now (used to calculate num_samples per block) */
|
||||
int32_t current_block_samples; /* size in samples of the block we're in now (used over current_block_size if possible) */
|
||||
off_t next_block_offset; /* offset of header of the next block */
|
||||
size_t full_block_size; /* actual data size of an entire block (ie. may be fixed, include padding/headers, etc) */
|
||||
|
||||
/* loop state (saved when loop is hit to restore later) */
|
||||
int32_t loop_current_sample; /* saved from current_sample (same as loop_start_sample, but more state-like) */
|
||||
@ -228,35 +235,13 @@ typedef struct {
|
||||
play_state_t pstate; /* player state (applied over decoding) */
|
||||
int loop_count; /* counter of complete loops (1=looped once) */
|
||||
int loop_target; /* max loops before continuing with the stream end (loops forever if not set) */
|
||||
|
||||
sample_t* tmpbuf; /* garbage buffer used for seeking/trimming */
|
||||
size_t tmpbuf_size; /* for all channels (samples = tmpbuf_size / channels) */
|
||||
|
||||
} VGMSTREAM;
|
||||
|
||||
|
||||
/* for files made of "continuous" segments, one per section of a song (using a complete sub-VGMSTREAM) */
|
||||
typedef struct {
|
||||
int segment_count;
|
||||
VGMSTREAM** segments;
|
||||
int current_segment;
|
||||
sample_t* buffer;
|
||||
int input_channels; /* internal buffer channels */
|
||||
int output_channels; /* resulting channels (after mixing, if applied) */
|
||||
int mixed_channels; /* segments have different number of channels */
|
||||
} segmented_layout_data;
|
||||
|
||||
/* for files made of "parallel" layers, one per group of channels (using a complete sub-VGMSTREAM) */
|
||||
typedef struct {
|
||||
int layer_count;
|
||||
VGMSTREAM** layers;
|
||||
sample_t* buffer;
|
||||
int input_channels; /* internal buffer channels */
|
||||
int output_channels; /* resulting channels (after mixing, if applied) */
|
||||
int external_looping; /* don't loop using per-layer loops, but layout's own looping */
|
||||
int curr_layer; /* helper */
|
||||
} layered_layout_data;
|
||||
|
||||
|
||||
// VGMStream description in structure format
|
||||
typedef struct {
|
||||
int sample_rate;
|
||||
@ -304,9 +289,6 @@ void reset_vgmstream(VGMSTREAM* vgmstream);
|
||||
/* close an open vgmstream */
|
||||
void close_vgmstream(VGMSTREAM* vgmstream);
|
||||
|
||||
/* calculate the number of samples to be played based on looping parameters */
|
||||
int32_t get_vgmstream_play_samples(double looptimes, double fadeseconds, double fadedelayseconds, VGMSTREAM* vgmstream);
|
||||
|
||||
/* Decode data into sample buffer. Returns < sample_count on stream end */
|
||||
int render_vgmstream(sample_t* buffer, int32_t sample_count, VGMSTREAM* vgmstream);
|
||||
|
||||
@ -321,20 +303,6 @@ void describe_vgmstream_info(VGMSTREAM* vgmstream, vgmstream_info* desc);
|
||||
/* Return the average bitrate in bps of all unique files contained within this stream. */
|
||||
int get_vgmstream_average_bitrate(VGMSTREAM* vgmstream);
|
||||
|
||||
/* List supported formats and return elements in the list, for plugins that need to know.
|
||||
* The list disables some common formats that may conflict (.wav, .ogg, etc). */
|
||||
const char** vgmstream_get_formats(size_t* size);
|
||||
|
||||
/* same, but for common-but-disabled formats in the above list. */
|
||||
const char** vgmstream_get_common_formats(size_t* size);
|
||||
|
||||
/* Force enable/disable internal looping. Should be done before playing anything (or after reset),
|
||||
* and not all codecs support arbitrary loop values ATM. */
|
||||
void vgmstream_force_loop(VGMSTREAM* vgmstream, int loop_flag, int loop_start_sample, int loop_end_sample);
|
||||
|
||||
/* Set number of max loops to do, then play up to stream end (for songs with proper endings) */
|
||||
void vgmstream_set_loop_target(VGMSTREAM* vgmstream, int loop_target);
|
||||
|
||||
/* Return 1 if vgmstream detects from the filename that said file can be used even if doesn't physically exist */
|
||||
int vgmstream_is_virtual_filename(const char* filename);
|
||||
|
||||
@ -358,5 +326,16 @@ void get_vgmstream_coding_description(VGMSTREAM* vgmstream, char* out, size_t ou
|
||||
void get_vgmstream_layout_description(VGMSTREAM* vgmstream, char* out, size_t out_size);
|
||||
void get_vgmstream_meta_description(VGMSTREAM* vgmstream, char* out, size_t out_size);
|
||||
|
||||
/* calculate the number of samples to be played based on looping parameters */
|
||||
int32_t get_vgmstream_play_samples(double looptimes, double fadeseconds, double fadedelayseconds, VGMSTREAM* vgmstream);
|
||||
|
||||
void setup_state_vgmstream(VGMSTREAM* vgmstream);
|
||||
|
||||
/* Force enable/disable internal looping. Should be done before playing anything (or after reset),
|
||||
* and not all codecs support arbitrary loop values ATM. */
|
||||
void vgmstream_force_loop(VGMSTREAM* vgmstream, int loop_flag, int loop_start_sample, int loop_end_sample);
|
||||
|
||||
/* Set number of max loops to do, then play up to stream end (for songs with proper endings) */
|
||||
void vgmstream_set_loop_target(VGMSTREAM* vgmstream, int loop_target);
|
||||
|
||||
#endif
|
||||
|
@ -237,8 +237,9 @@ void WINAPI xmplay_GetInfoText(char* format, char* length) {
|
||||
rate = vgmstream->sample_rate;
|
||||
samples = vgmstream->num_samples;
|
||||
bps = get_vgmstream_average_bitrate(vgmstream) / 1000;
|
||||
get_vgmstream_coding_description(vgmstream, fmt, sizeof(fmt));
|
||||
if (strcmp(fmt, "FFmpeg") == 0)
|
||||
|
||||
//get_vgmstream_coding_description(vgmstream, fmt, sizeof(fmt));
|
||||
//if (strcmp(fmt, "FFmpeg") == 0)
|
||||
{
|
||||
char buffer[1024];
|
||||
buffer[0] = '\0';
|
||||
|
Loading…
Reference in New Issue
Block a user