mirror of
https://github.com/vgmstream/vgmstream.git
synced 2024-11-12 01:30:49 +01:00
cleanup: move defs around
This commit is contained in:
parent
8160794db5
commit
637273bcd9
@ -1,6 +1,7 @@
|
|||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include "../vgmstream.h"
|
#include "../vgmstream.h"
|
||||||
#include "../coding/coding.h"
|
#include "../coding/coding.h"
|
||||||
|
#include "../layout/layout.h"
|
||||||
#include "mixing.h"
|
#include "mixing.h"
|
||||||
#include "../util/channel_mappings.h"
|
#include "../util/channel_mappings.h"
|
||||||
#include "../util/sf_utils.h"
|
#include "../util/sf_utils.h"
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include "mixer.h"
|
#include "mixer.h"
|
||||||
#include "mixer_priv.h"
|
#include "mixer_priv.h"
|
||||||
#include "sbuf.h"
|
#include "sbuf.h"
|
||||||
|
#include "../layout/layout.h"
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "../vgmstream.h"
|
#include "../vgmstream.h"
|
||||||
#include "../util/channel_mappings.h"
|
#include "../util/channel_mappings.h"
|
||||||
|
#include "../layout/layout.h"
|
||||||
#include "mixing.h"
|
#include "mixing.h"
|
||||||
#include "mixer_priv.h"
|
#include "mixer_priv.h"
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
@ -8,6 +8,14 @@
|
|||||||
#include "../vgmstream.h"
|
#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 */
|
/* CONTEXT: simplifies plugin code */
|
||||||
/* ****************************************** */
|
/* ****************************************** */
|
||||||
|
@ -3,135 +3,148 @@
|
|||||||
#include "../util.h"
|
#include "../util.h"
|
||||||
|
|
||||||
/* Westwood Studios ADPCM */
|
/* Westwood Studios ADPCM */
|
||||||
|
|
||||||
/* Based on Valery V. Anisimovsky's WS-AUD.txt */
|
/* Based on Valery V. Anisimovsky's WS-AUD.txt */
|
||||||
|
|
||||||
static char WSTable2bit[4] = { -2,-1,0,1 };
|
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 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
|
/* We pass in the VGMSTREAM here, unlike in other codings, because the decoder has to know about the block structure. */
|
||||||
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) {
|
||||||
void decode_ws(VGMSTREAM * vgmstream, int channel, sample * outbuf, int channelspacing, int32_t first_sample,
|
VGMSTREAMCHANNEL* stream = &(vgmstream->ch[channel]);
|
||||||
int32_t samples_to_do) {
|
STREAMFILE* sf = stream->streamfile;
|
||||||
VGMSTREAMCHANNEL * stream = &(vgmstream->ch[channel]);
|
|
||||||
int16_t hist = stream->adpcm_history1_16;
|
int16_t hist = stream->adpcm_history1_16;
|
||||||
off_t offset = stream->offset;
|
off_t offset = stream->offset;
|
||||||
int samples_left_in_frame = stream->samples_left_in_frame;
|
int samples_left_in_frame = stream->ws_samples_left_in_frame;
|
||||||
off_t header_off = stream->frame_header_offset;
|
off_t header_offset = stream->ws_frame_header_offset;
|
||||||
|
|
||||||
int i;
|
//int i;
|
||||||
int32_t sample_count;
|
int32_t sample_count = 0;
|
||||||
|
|
||||||
if (vgmstream->ws_output_size == vgmstream->current_block_size) {
|
if (vgmstream->ws_output_size == vgmstream->current_block_size) {
|
||||||
/* uncompressed, we just need to convert to 16-bit */
|
/* uncompressed pcm8 to pcm16 */
|
||||||
for (i=first_sample,sample_count=0; i<first_sample+samples_to_do; i++,sample_count+=channelspacing,offset++) {
|
for (int i = first_sample; i < first_sample + samples_to_do; i++) {
|
||||||
outbuf[sample_count]=((uint8_t)read_8bit(offset,stream->streamfile)-0x80)*0x100;
|
outbuf[sample_count] = (read_u8(offset,sf) - 0x80) * 0x100;
|
||||||
|
sample_count += channelspacing;
|
||||||
|
offset++;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
if (first_sample == 0) {
|
if (first_sample == 0) {
|
||||||
hist = 0x80;
|
hist = 0x80;
|
||||||
samples_left_in_frame = 0;
|
samples_left_in_frame = 0;
|
||||||
}
|
}
|
||||||
/* actually decompress */
|
|
||||||
for (i=first_sample,sample_count=0; i<first_sample+samples_to_do; ) {
|
/* decompress */
|
||||||
uint8_t header;
|
for (int i = first_sample; i < first_sample + samples_to_do; /* manually incremented */) {
|
||||||
uint8_t count;
|
|
||||||
|
|
||||||
if (samples_left_in_frame == 0) {
|
if (samples_left_in_frame == 0) {
|
||||||
header_off = offset;
|
header_offset = offset;
|
||||||
offset++;
|
offset++;
|
||||||
}
|
}
|
||||||
|
|
||||||
header = read_8bit(header_off,stream->streamfile);
|
uint8_t header = read_u8(header_offset, sf);
|
||||||
count = header & 0x3f;
|
uint8_t count = header & 0x3f;
|
||||||
switch (header>>6) { /* code */
|
uint8_t code = header >> 6;
|
||||||
|
switch (code) { /* code */
|
||||||
case 0: /* 2-bit ADPCM */
|
case 0: /* 2-bit ADPCM */
|
||||||
if (samples_left_in_frame == 0) {
|
if (samples_left_in_frame == 0)
|
||||||
samples_left_in_frame = (count + 1)*4;
|
samples_left_in_frame = (count + 1) * 4;
|
||||||
}
|
|
||||||
for (;samples_left_in_frame>0 && /* read this frame */
|
/* read this frame up to samples_to_do */
|
||||||
i<first_sample+samples_to_do; /* up to samples_to_do */
|
for ( ; samples_left_in_frame>0 && i < first_sample + samples_to_do; i++) {
|
||||||
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;
|
||||||
int twobit = ((count + 1)*4-samples_left_in_frame)%4;
|
uint8_t sample = read_u8(offset,sf);
|
||||||
uint8_t sample;
|
sample = (sample >> (twobit * 2)) & 0x3;
|
||||||
sample = read_8bit(offset,stream->streamfile);
|
|
||||||
sample = (sample >> (twobit*2)) & 0x3;
|
|
||||||
hist += WSTable2bit[sample];
|
hist += WSTable2bit[sample];
|
||||||
|
|
||||||
if (hist < 0) hist = 0;
|
if (hist < 0) hist = 0;
|
||||||
if (hist > 0xff) hist = 0xff;
|
else if (hist > 0xff) hist = 0xff;
|
||||||
outbuf[sample_count]=(hist-0x80)*0x100;
|
|
||||||
|
outbuf[sample_count] = (hist - 0x80) * 0x100;
|
||||||
|
sample_count += channelspacing;
|
||||||
|
samples_left_in_frame--;
|
||||||
|
|
||||||
if (twobit == 3)
|
if (twobit == 3)
|
||||||
offset++; /* done with that byte */
|
offset++; /* done with that byte */
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1: /* 4-bit ADPCM */
|
case 1: /* 4-bit ADPCM */
|
||||||
if (samples_left_in_frame == 0) {
|
if (samples_left_in_frame == 0)
|
||||||
samples_left_in_frame = (count + 1)*2;
|
samples_left_in_frame = (count + 1) * 2;
|
||||||
}
|
|
||||||
for (;samples_left_in_frame>0 && /* read this frame */
|
/* read this frame up to samples_to_do */
|
||||||
i<first_sample+samples_to_do; /* up to samples_to_do */
|
for ( ; samples_left_in_frame>0 && i < first_sample + samples_to_do; i++) {
|
||||||
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;
|
||||||
int nibble = ((count + 1)*4-samples_left_in_frame)%2;
|
uint8_t sample = read_u8(offset, sf);
|
||||||
uint8_t sample;
|
|
||||||
sample = read_8bit(offset,stream->streamfile);
|
|
||||||
if (nibble == 0)
|
if (nibble == 0)
|
||||||
sample &= 0xf;
|
sample &= 0xf;
|
||||||
else
|
else
|
||||||
sample >>= 4;
|
sample >>= 4;
|
||||||
hist += WSTable4bit[sample];
|
hist += WSTable4bit[sample];
|
||||||
|
|
||||||
if (hist < 0) hist = 0;
|
if (hist < 0) hist = 0;
|
||||||
if (hist > 0xff) hist = 0xff;
|
else if (hist > 0xff) hist = 0xff;
|
||||||
outbuf[sample_count]=(hist-0x80)*0x100;
|
|
||||||
|
outbuf[sample_count] = (hist - 0x80) * 0x100;
|
||||||
|
sample_count += channelspacing;
|
||||||
|
samples_left_in_frame--;
|
||||||
|
|
||||||
if (nibble == 1)
|
if (nibble == 1)
|
||||||
offset++; /* done with that byte */
|
offset++; /* done with that byte */
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2: /* no compression */
|
case 2: /* no compression */
|
||||||
if (count & 0x20) { /* delta */
|
if (count & 0x20) { /* new delta */
|
||||||
/* Note no checks against samples_to_do here,
|
/* Note no checks against samples_to_do here, at the top of the for loop
|
||||||
at the top of the for loop we can always do at
|
* we can always do at least one sample */
|
||||||
least one sample */
|
|
||||||
/* low 5 bits are a signed delta */
|
/* low 5 bits are a signed delta */
|
||||||
if (count & 0x10) {
|
if (count & 0x10) {
|
||||||
hist -= ((count & 0xf)^0xf) + 1;
|
hist -= ((count & 0x0f) ^ 0x0f) + 1;
|
||||||
} else {
|
} 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 < 0) hist = 0;
|
||||||
if (hist > 0xff) hist = 0xff;
|
else if (hist > 0xff) hist = 0xff;
|
||||||
|
|
||||||
outbuf[sample_count]=(hist-0x80)*0x100;
|
|
||||||
sample_count+=channelspacing;
|
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
/* just one, and we got it */
|
outbuf[sample_count] = (hist - 0x80) * 0x100;
|
||||||
samples_left_in_frame = 0;
|
sample_count += channelspacing;
|
||||||
} else { /* copy bytes verbatim */
|
samples_left_in_frame = 0; /* just one */
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* copy bytes verbatim */
|
||||||
if (samples_left_in_frame == 0)
|
if (samples_left_in_frame == 0)
|
||||||
samples_left_in_frame=count+1;
|
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 */
|
/* read this frame up to samples_to_do */
|
||||||
offset++, /* done with a byte */
|
for ( ; samples_left_in_frame > 0 && i < first_sample + samples_to_do; i++) {
|
||||||
i++,sample_count+=channelspacing, /* done with writing a sample */
|
hist = read_u8(offset,sf);
|
||||||
samples_left_in_frame--) { /* done with reading a sample */
|
offset++;
|
||||||
outbuf[sample_count]=((hist=(uint8_t)read_8bit(offset,stream->streamfile))-0x80)*0x100;
|
|
||||||
|
outbuf[sample_count] = (hist - 0x80) * 0x100;
|
||||||
|
sample_count += channelspacing;
|
||||||
|
samples_left_in_frame--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3: /* RLE */
|
case 3: /* RLE */
|
||||||
if (samples_left_in_frame == 0)
|
if (samples_left_in_frame == 0)
|
||||||
samples_left_in_frame=count+1;
|
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 */
|
/* read this frame up to samples_to_do */
|
||||||
i++,sample_count+=channelspacing, /* done with writing a sample */
|
for ( ; samples_left_in_frame > 0 && i < first_sample + samples_to_do; i++) {
|
||||||
samples_left_in_frame--) { /* done with reading a sample */
|
outbuf[sample_count] = (hist - 0x80) * 0x100;
|
||||||
outbuf[sample_count]=(hist-0x80)*0x100;
|
sample_count += channelspacing;
|
||||||
|
samples_left_in_frame--;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -141,6 +154,6 @@ void decode_ws(VGMSTREAM * vgmstream, int channel, sample * outbuf, int channels
|
|||||||
|
|
||||||
stream->offset = offset;
|
stream->offset = offset;
|
||||||
stream->adpcm_history1_16 = hist;
|
stream->adpcm_history1_16 = hist;
|
||||||
stream->samples_left_in_frame = samples_left_in_frame;
|
stream->ws_samples_left_in_frame = samples_left_in_frame;
|
||||||
stream->frame_header_offset = header_off;
|
stream->ws_frame_header_offset = header_offset;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "vgmstream.h"
|
#include "vgmstream.h"
|
||||||
#include "coding/coding.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
|
/* 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_EB_SF0, "assumed Excitebots .sf0 by extension"},
|
||||||
{meta_MTAF, "Konami MTAF header"},
|
{meta_MTAF, "Konami MTAF header"},
|
||||||
{meta_ALP, "High Voltage ALP 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_MN_STR, "Mini Ninjas 'STR' header"},
|
||||||
{meta_MSS, "Guerilla MCSS header"},
|
{meta_MSS, "Guerilla MCSS header"},
|
||||||
{meta_PS2_HSF, "Lowrider 'HSF' header"},
|
{meta_PS2_HSF, "Lowrider 'HSF' header"},
|
||||||
|
@ -6,6 +6,53 @@
|
|||||||
#include "../util/reader_sf.h"
|
#include "../util/reader_sf.h"
|
||||||
#include "../util/log.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 */
|
/* blocked layouts */
|
||||||
void render_vgmstream_blocked(sample_t* buffer, int32_t sample_count, VGMSTREAM* vgmstream);
|
void render_vgmstream_blocked(sample_t* buffer, int32_t sample_count, VGMSTREAM* vgmstream);
|
||||||
void block_update(off_t block_offset, 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_tt_ad(off_t block_offset, VGMSTREAM* vgmstream);
|
||||||
void block_update_vas(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
|
#endif
|
||||||
|
@ -94,27 +94,28 @@ typedef struct {
|
|||||||
} play_state_t;
|
} play_state_t;
|
||||||
|
|
||||||
|
|
||||||
/* info for a single vgmstream channel */
|
/* info for a single vgmstream 'channel' (or rather, mono stream) */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
STREAMFILE* streamfile; /* file used by this channel */
|
STREAMFILE* streamfile; /* file used by this channel */
|
||||||
off_t channel_start_offset; /* where data for this channel begins */
|
off_t channel_start_offset; /* where data for this channel begins */
|
||||||
off_t offset; /* current location in the file */
|
off_t offset; /* current location in the file */
|
||||||
|
|
||||||
off_t frame_header_offset; /* offset of the current frame header (for WS) */
|
/* format and channel specific */
|
||||||
int samples_left_in_frame; /* for WS */
|
|
||||||
|
|
||||||
/* format specific */
|
/* ADPCM with built or variable decode coefficients */
|
||||||
|
|
||||||
/* 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 */
|
|
||||||
union {
|
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;
|
int32_t adpcm_history1_32;
|
||||||
};
|
};
|
||||||
union {
|
union {
|
||||||
int16_t adpcm_history2_16; /* previous previous sample */
|
int16_t adpcm_history2_16;
|
||||||
int32_t adpcm_history2_32;
|
int32_t adpcm_history2_32;
|
||||||
};
|
};
|
||||||
union {
|
union {
|
||||||
@ -129,14 +130,20 @@ typedef struct {
|
|||||||
//double adpcm_history1_double;
|
//double adpcm_history1_double;
|
||||||
//double adpcm_history2_double;
|
//double adpcm_history2_double;
|
||||||
|
|
||||||
int adpcm_step_index; /* for IMA */
|
/* for ADPCM decoders that store steps (IMA) or scales (MSADPCM) */
|
||||||
int adpcm_scale; /* for MS ADPCM */
|
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 */
|
/* state for G.721 decoder, sort of big but we might as well keep it around */
|
||||||
struct g72x_state g72x_state;
|
struct g72x_state g72x_state;
|
||||||
|
|
||||||
/* ADX encryption */
|
/* ADX encryption */
|
||||||
int adx_channels;
|
|
||||||
uint16_t adx_xor;
|
uint16_t adx_xor;
|
||||||
uint16_t adx_mult;
|
uint16_t adx_mult;
|
||||||
uint16_t adx_add;
|
uint16_t adx_add;
|
||||||
@ -147,9 +154,9 @@ typedef struct {
|
|||||||
/* main vgmstream info */
|
/* main vgmstream info */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
/* basic config */
|
/* 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 */
|
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 */
|
coding_t coding_type; /* type of encoding */
|
||||||
layout_t layout_type; /* type of layout */
|
layout_t layout_type; /* type of layout */
|
||||||
meta_t meta_type; /* type of metadata */
|
meta_t meta_type; /* type of metadata */
|
||||||
@ -180,13 +187,13 @@ typedef struct {
|
|||||||
int format_id; /* internal format ID */
|
int format_id; /* internal format ID */
|
||||||
|
|
||||||
/* layout/block state */
|
/* 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 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 */
|
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) */
|
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) */
|
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) */
|
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 */
|
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) */
|
/* 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) */
|
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) */
|
play_state_t pstate; /* player state (applied over decoding) */
|
||||||
int loop_count; /* counter of complete loops (1=looped once) */
|
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) */
|
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 */
|
sample_t* tmpbuf; /* garbage buffer used for seeking/trimming */
|
||||||
size_t tmpbuf_size; /* for all channels (samples = tmpbuf_size / channels) */
|
size_t tmpbuf_size; /* for all channels (samples = tmpbuf_size / channels) */
|
||||||
|
|
||||||
} VGMSTREAM;
|
} 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
|
// VGMStream description in structure format
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int sample_rate;
|
int sample_rate;
|
||||||
@ -304,9 +289,6 @@ void reset_vgmstream(VGMSTREAM* vgmstream);
|
|||||||
/* close an open vgmstream */
|
/* close an open vgmstream */
|
||||||
void close_vgmstream(VGMSTREAM* 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 */
|
/* Decode data into sample buffer. Returns < sample_count on stream end */
|
||||||
int render_vgmstream(sample_t* buffer, int32_t sample_count, VGMSTREAM* vgmstream);
|
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. */
|
/* Return the average bitrate in bps of all unique files contained within this stream. */
|
||||||
int get_vgmstream_average_bitrate(VGMSTREAM* vgmstream);
|
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 */
|
/* 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);
|
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_layout_description(VGMSTREAM* vgmstream, char* out, size_t out_size);
|
||||||
void get_vgmstream_meta_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);
|
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
|
#endif
|
||||||
|
@ -237,8 +237,9 @@ void WINAPI xmplay_GetInfoText(char* format, char* length) {
|
|||||||
rate = vgmstream->sample_rate;
|
rate = vgmstream->sample_rate;
|
||||||
samples = vgmstream->num_samples;
|
samples = vgmstream->num_samples;
|
||||||
bps = get_vgmstream_average_bitrate(vgmstream) / 1000;
|
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];
|
char buffer[1024];
|
||||||
buffer[0] = '\0';
|
buffer[0] = '\0';
|
||||||
|
Loading…
Reference in New Issue
Block a user