2008-01-31 07:04:26 +01:00
|
|
|
/*
|
2024-07-27 15:22:21 +02:00
|
|
|
* vgmstream.h - internal definitions for VGMSTREAM, encapsulating a multi-channel, looped audio stream
|
2008-01-31 07:04:26 +01:00
|
|
|
*/
|
2024-07-27 15:22:21 +02:00
|
|
|
#ifndef _VGMSTREAM_H_
|
|
|
|
#define _VGMSTREAM_H_
|
2008-01-31 07:04:26 +01:00
|
|
|
|
2023-05-07 23:06:13 +02:00
|
|
|
/* Due mostly to licensing issues, Vorbis, MPEG, G.722.1, etc decoding is done by external libraries.
|
|
|
|
* Libs are disabled by default, defined on compile-time for builds that support it */
|
|
|
|
//#define VGM_USE_VORBIS
|
|
|
|
//#define VGM_USE_MPEG
|
|
|
|
//#define VGM_USE_G7221
|
|
|
|
//#define VGM_USE_G719
|
|
|
|
//#define VGM_USE_MP4V2
|
|
|
|
//#define VGM_USE_FDKAAC
|
|
|
|
//#define VGM_USE_FFMPEG
|
|
|
|
//#define VGM_USE_ATRAC9
|
|
|
|
//#define VGM_USE_CELT
|
|
|
|
//#define VGM_USE_SPEEX
|
|
|
|
|
|
|
|
|
2019-03-11 14:49:29 +01:00
|
|
|
/* reasonable limits */
|
2024-07-14 21:40:37 +02:00
|
|
|
#include "util/vgmstream_limits.h"
|
2013-05-27 05:55:50 +02:00
|
|
|
|
2017-01-08 01:09:20 +01:00
|
|
|
#include "streamfile.h"
|
2023-05-07 23:06:13 +02:00
|
|
|
#include "vgmstream_types.h"
|
2017-01-08 01:09:20 +01:00
|
|
|
|
|
|
|
#include "coding/g72x_state.h"
|
|
|
|
|
2008-05-06 05:35:37 +02:00
|
|
|
|
2020-06-21 00:33:21 +02:00
|
|
|
typedef struct {
|
2024-07-27 14:42:43 +02:00
|
|
|
bool config_set; /* some of the mods below are set */
|
2020-07-26 11:19:52 +02:00
|
|
|
|
2020-07-21 19:22:17 +02:00
|
|
|
/* modifiers */
|
2024-07-27 14:42:43 +02:00
|
|
|
bool play_forever;
|
|
|
|
bool ignore_loop;
|
|
|
|
bool force_loop;
|
|
|
|
bool really_force_loop;
|
|
|
|
bool ignore_fade;
|
2020-07-21 19:22:17 +02:00
|
|
|
|
|
|
|
/* processing */
|
2020-07-22 23:29:38 +02:00
|
|
|
double loop_count;
|
2020-07-21 19:22:17 +02:00
|
|
|
int32_t pad_begin;
|
|
|
|
int32_t trim_begin;
|
2020-07-23 21:10:55 +02:00
|
|
|
int32_t body_time;
|
2020-07-21 19:22:17 +02:00
|
|
|
int32_t trim_end;
|
|
|
|
double fade_delay; /* not in samples for backwards compatibility */
|
2020-06-21 00:33:21 +02:00
|
|
|
double fade_time;
|
2020-07-21 19:22:17 +02:00
|
|
|
int32_t pad_end;
|
|
|
|
|
2020-07-22 23:29:38 +02:00
|
|
|
double pad_begin_s;
|
|
|
|
double trim_begin_s;
|
2020-07-23 21:10:55 +02:00
|
|
|
double body_time_s;
|
2020-07-22 23:29:38 +02:00
|
|
|
double trim_end_s;
|
|
|
|
//double fade_delay_s;
|
|
|
|
//double fade_time_s;
|
|
|
|
double pad_end_s;
|
|
|
|
|
2020-07-21 19:22:17 +02:00
|
|
|
/* internal flags */
|
2024-07-27 14:42:43 +02:00
|
|
|
bool pad_begin_set;
|
|
|
|
bool trim_begin_set;
|
|
|
|
bool body_time_set;
|
|
|
|
bool loop_count_set;
|
|
|
|
bool trim_end_set;
|
|
|
|
bool fade_delay_set;
|
|
|
|
bool fade_time_set;
|
|
|
|
bool pad_end_set;
|
2020-07-21 19:22:17 +02:00
|
|
|
|
2020-11-02 01:07:39 +01:00
|
|
|
/* for lack of a better place... */
|
2024-07-27 14:42:43 +02:00
|
|
|
bool is_txtp;
|
|
|
|
bool is_mini_txtp;
|
2020-07-22 23:29:38 +02:00
|
|
|
|
2020-06-21 00:33:21 +02:00
|
|
|
} play_config_t;
|
2017-01-08 01:09:20 +01:00
|
|
|
|
2020-07-17 22:35:32 +02:00
|
|
|
|
2020-07-21 19:22:17 +02:00
|
|
|
typedef struct {
|
|
|
|
int input_channels;
|
|
|
|
int output_channels;
|
|
|
|
|
2020-07-26 20:15:13 +02:00
|
|
|
int32_t pad_begin_duration;
|
2020-07-22 23:29:38 +02:00
|
|
|
int32_t pad_begin_left;
|
2020-07-26 20:15:13 +02:00
|
|
|
int32_t trim_begin_duration;
|
2020-07-22 23:29:38 +02:00
|
|
|
int32_t trim_begin_left;
|
2020-07-26 20:15:13 +02:00
|
|
|
int32_t body_duration;
|
2020-07-21 19:22:17 +02:00
|
|
|
int32_t fade_duration;
|
2020-07-22 23:29:38 +02:00
|
|
|
int32_t fade_left;
|
2020-07-26 20:15:13 +02:00
|
|
|
int32_t fade_start;
|
|
|
|
int32_t pad_end_duration;
|
2020-07-29 19:34:55 +02:00
|
|
|
//int32_t pad_end_left;
|
2020-07-26 20:15:13 +02:00
|
|
|
int32_t pad_end_start;
|
2020-07-21 19:22:17 +02:00
|
|
|
|
|
|
|
int32_t play_duration; /* total samples that the stream lasts (after applying all config) */
|
|
|
|
int32_t play_position; /* absolute sample where stream is */
|
2020-11-02 01:07:39 +01:00
|
|
|
|
2020-07-21 19:22:17 +02:00
|
|
|
} play_state_t;
|
|
|
|
|
|
|
|
|
2024-08-07 22:35:38 +02:00
|
|
|
/* info for a single vgmstream 'channel' (or rather, mono stream) */
|
2008-01-31 07:04:26 +01:00
|
|
|
typedef struct {
|
2020-07-17 22:35:32 +02:00
|
|
|
STREAMFILE* streamfile; /* file used by this channel */
|
2008-01-31 07:04:26 +01:00
|
|
|
off_t channel_start_offset; /* where data for this channel begins */
|
2019-02-15 22:28:20 +01:00
|
|
|
off_t offset; /* current location in the file */
|
2008-01-31 07:04:26 +01:00
|
|
|
|
2024-08-07 22:35:38 +02:00
|
|
|
/* format and channel specific */
|
2008-07-04 02:06:51 +02:00
|
|
|
|
2024-08-07 22:35:38 +02:00
|
|
|
/* ADPCM with built or variable decode coefficients */
|
|
|
|
union {
|
|
|
|
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 */
|
|
|
|
};
|
2008-01-31 07:04:26 +01:00
|
|
|
|
2024-08-07 22:35:38 +02:00
|
|
|
/* previous ADPCM samples */
|
2008-01-31 07:04:26 +01:00
|
|
|
union {
|
2024-08-07 22:35:38 +02:00
|
|
|
int16_t adpcm_history1_16;
|
2008-01-31 07:04:26 +01:00
|
|
|
int32_t adpcm_history1_32;
|
|
|
|
};
|
|
|
|
union {
|
2024-08-07 22:35:38 +02:00
|
|
|
int16_t adpcm_history2_16;
|
2008-01-31 07:04:26 +01:00
|
|
|
int32_t adpcm_history2_32;
|
|
|
|
};
|
2009-01-04 16:36:06 +01:00
|
|
|
union {
|
|
|
|
int16_t adpcm_history3_16;
|
|
|
|
int32_t adpcm_history3_32;
|
|
|
|
};
|
2016-12-21 20:44:16 +01:00
|
|
|
union {
|
|
|
|
int16_t adpcm_history4_16;
|
|
|
|
int32_t adpcm_history4_32;
|
|
|
|
};
|
2008-02-05 10:21:20 +01:00
|
|
|
|
2020-07-17 22:35:32 +02:00
|
|
|
//double adpcm_history1_double;
|
|
|
|
//double adpcm_history2_double;
|
2009-03-05 17:08:23 +01:00
|
|
|
|
2024-08-07 22:35:38 +02:00
|
|
|
/* 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 */
|
2008-02-14 23:10:08 +01:00
|
|
|
|
2017-01-08 01:09:20 +01:00
|
|
|
/* state for G.721 decoder, sort of big but we might as well keep it around */
|
|
|
|
struct g72x_state g72x_state;
|
2008-04-02 18:11:53 +02:00
|
|
|
|
2008-12-24 08:19:15 +01:00
|
|
|
/* ADX encryption */
|
|
|
|
uint16_t adx_xor;
|
|
|
|
uint16_t adx_mult;
|
|
|
|
uint16_t adx_add;
|
2009-01-10 01:07:12 +01:00
|
|
|
|
2008-01-31 07:04:26 +01:00
|
|
|
} VGMSTREAMCHANNEL;
|
|
|
|
|
2020-07-17 22:35:32 +02:00
|
|
|
|
2017-01-08 01:09:20 +01:00
|
|
|
/* main vgmstream info */
|
2008-01-31 07:04:26 +01:00
|
|
|
typedef struct {
|
2019-02-15 22:28:20 +01:00
|
|
|
/* basic config */
|
2024-08-07 22:35:38 +02:00
|
|
|
int channels; /* number of channels for the current stream */
|
2018-09-07 19:34:31 +02:00
|
|
|
int32_t sample_rate; /* sample rate in Hz */
|
2024-08-07 22:35:38 +02:00
|
|
|
int32_t num_samples; /* the actual max number of samples */
|
2018-09-07 19:34:31 +02:00
|
|
|
coding_t coding_type; /* type of encoding */
|
|
|
|
layout_t layout_type; /* type of layout */
|
|
|
|
meta_t meta_type; /* type of metadata */
|
|
|
|
|
2024-07-25 18:21:23 +02:00
|
|
|
/* loop config */
|
2024-07-27 14:42:43 +02:00
|
|
|
bool loop_flag; /* is this stream looped? */
|
2018-09-07 19:34:31 +02:00
|
|
|
int32_t loop_start_sample; /* first sample of the loop (included in the loop) */
|
|
|
|
int32_t loop_end_sample; /* last sample of the loop (not included in the loop) */
|
|
|
|
|
2019-02-15 22:28:20 +01:00
|
|
|
/* layouts/block config */
|
2018-09-07 19:34:31 +02:00
|
|
|
size_t interleave_block_size; /* interleave, or block/frame size (depending on the codec) */
|
2019-08-12 19:23:49 +02:00
|
|
|
size_t interleave_first_block_size; /* different interleave for first block */
|
|
|
|
size_t interleave_first_skip; /* data skipped before interleave first (needed to skip other channels) */
|
2018-09-07 19:34:31 +02:00
|
|
|
size_t interleave_last_block_size; /* smaller interleave for last block */
|
2019-10-20 01:24:59 +02:00
|
|
|
size_t frame_size; /* for codecs with configurable size */
|
2017-08-12 11:27:10 +02:00
|
|
|
|
2019-02-15 22:28:20 +01:00
|
|
|
/* subsong config */
|
2018-09-07 19:34:31 +02:00
|
|
|
int num_streams; /* for multi-stream formats (0=not set/one stream, 1=one stream) */
|
|
|
|
int stream_index; /* selected subsong (also 1-based) */
|
|
|
|
size_t stream_size; /* info to properly calculate bitrate in case of subsongs */
|
2017-11-16 19:47:42 +01:00
|
|
|
char stream_name[STREAM_NAME_SIZE]; /* name of the current stream (info), if the file stores it and it's filled */
|
2008-01-31 07:04:26 +01:00
|
|
|
|
2023-05-07 22:00:30 +02:00
|
|
|
/* mapping config (info for plugins) see channel_mappings.h */
|
2019-03-02 15:57:41 +01:00
|
|
|
uint32_t channel_layout; /* order: FL FR FC LFE BL BR FLC FRC BC SL SR etc (WAVEFORMATEX flags where FL=lowest bit set) */
|
|
|
|
|
2019-02-15 22:28:20 +01:00
|
|
|
/* other config */
|
2024-07-25 18:21:23 +02:00
|
|
|
bool allow_dual_stereo; /* search for dual stereo (file_L.ext + file_R.ext = single stereo file) */
|
2024-07-28 17:30:38 +02:00
|
|
|
int format_id; /* internal format ID */
|
2020-07-17 22:35:32 +02:00
|
|
|
|
2017-11-26 01:25:27 +01:00
|
|
|
/* layout/block state */
|
2020-07-17 22:35:32 +02:00
|
|
|
int32_t current_sample; /* sample point within the file (for loop detection) */
|
2018-08-25 20:46:54 +02:00
|
|
|
int32_t samples_into_block; /* number of samples into the current block/interleave/segment/etc */
|
2008-01-31 07:04:26 +01:00
|
|
|
off_t current_block_offset; /* start of this block (offset of block header) */
|
2017-07-01 23:02:24 +02:00
|
|
|
size_t current_block_size; /* size in usable bytes of the block we're in now (used to calculate num_samples per block) */
|
2020-07-17 22:35:32 +02:00
|
|
|
int32_t current_block_samples; /* size in samples of the block we're in now (used over current_block_size if possible) */
|
2008-01-31 07:04:26 +01:00
|
|
|
off_t next_block_offset; /* offset of header of the next block */
|
2024-08-07 22:35:38 +02:00
|
|
|
size_t full_block_size; /* actual data size of an entire block (ie. may be fixed, include padding/headers, etc) */
|
2020-07-17 22:35:32 +02:00
|
|
|
|
|
|
|
/* 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) */
|
2017-01-08 01:09:20 +01:00
|
|
|
int32_t loop_samples_into_block;/* saved from samples_into_block */
|
2008-01-31 07:04:26 +01:00
|
|
|
off_t loop_block_offset; /* saved from current_block_offset */
|
|
|
|
size_t loop_block_size; /* saved from current_block_size */
|
2020-07-17 22:35:32 +02:00
|
|
|
int32_t loop_block_samples; /* saved from current_block_samples */
|
2008-01-31 07:04:26 +01:00
|
|
|
off_t loop_next_block_offset; /* saved from next_block_offset */
|
2024-07-25 18:21:23 +02:00
|
|
|
bool hit_loop; /* save config when loop is hit, but first time only */
|
2008-01-31 07:04:26 +01:00
|
|
|
|
2017-05-18 19:55:00 +02:00
|
|
|
|
2019-02-15 22:28:20 +01:00
|
|
|
/* decoder config/state */
|
2017-04-11 19:59:29 +02:00
|
|
|
int codec_endian; /* little/big endian marker; name is left vague but usually means big endian */
|
2019-02-15 22:28:20 +01:00
|
|
|
int codec_config; /* flags for codecs or layouts with minor variations; meaning is up to them */
|
2024-06-12 22:24:53 +02:00
|
|
|
bool codec_internal_updates; /* temp(?) kludge (see vgmstream_open_stream/decode) */
|
2017-01-08 01:09:20 +01:00
|
|
|
int32_t ws_output_size; /* WS ADPCM: output bytes for this block */
|
2008-07-03 23:21:01 +02:00
|
|
|
|
2019-02-15 22:28:20 +01:00
|
|
|
|
|
|
|
/* main state */
|
2020-07-16 21:43:01 +02:00
|
|
|
VGMSTREAMCHANNEL* ch; /* array of channels */
|
|
|
|
VGMSTREAMCHANNEL* start_ch; /* shallow copy of channels as they were at the beginning of the stream (for resets) */
|
|
|
|
VGMSTREAMCHANNEL* loop_ch; /* shallow copy of channels as they were at the loop point (for loops) */
|
2019-02-15 22:28:20 +01:00
|
|
|
void* start_vgmstream; /* shallow copy of the VGMSTREAM as it was at the beginning of the stream (for resets) */
|
2008-12-12 00:16:09 +01:00
|
|
|
|
2024-07-23 23:51:44 +02:00
|
|
|
void* mixer; /* state for mixing effects */
|
2019-03-09 20:50:58 +01:00
|
|
|
|
|
|
|
/* Optional data the codec needs for the whole stream. This is for codecs too
|
2019-02-15 22:28:20 +01:00
|
|
|
* different from vgmstream's structure to be reasonably shoehorned.
|
2008-06-15 06:01:03 +02:00
|
|
|
* Note also that support must be added for resetting, looping and
|
|
|
|
* closing for every codec that uses this, as it will not be handled. */
|
2020-07-16 21:43:01 +02:00
|
|
|
void* codec_data;
|
2018-08-23 18:00:34 +02:00
|
|
|
/* Same, for special layouts. layout_data + codec_data may exist at the same time. */
|
2020-07-16 21:43:01 +02:00
|
|
|
void* layout_data;
|
2019-03-09 20:50:58 +01:00
|
|
|
|
2020-07-21 19:22:17 +02:00
|
|
|
|
|
|
|
/* play config/state */
|
2024-07-25 18:21:23 +02:00
|
|
|
bool config_enabled; /* config can be used */
|
2020-07-21 19:22:17 +02:00
|
|
|
play_config_t config; /* player config (applied over decoding) */
|
|
|
|
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) */
|
2024-08-07 22:35:38 +02:00
|
|
|
|
2020-08-03 23:15:59 +02:00
|
|
|
sample_t* tmpbuf; /* garbage buffer used for seeking/trimming */
|
|
|
|
size_t tmpbuf_size; /* for all channels (samples = tmpbuf_size / channels) */
|
2020-07-21 19:22:17 +02:00
|
|
|
|
2008-01-31 07:04:26 +01:00
|
|
|
} VGMSTREAM;
|
|
|
|
|
2008-06-15 06:01:03 +02:00
|
|
|
|
2020-09-28 03:07:10 +02:00
|
|
|
// VGMStream description in structure format
|
|
|
|
typedef struct {
|
|
|
|
int sample_rate;
|
|
|
|
int channels;
|
|
|
|
struct mixing_info {
|
|
|
|
int input_channels;
|
|
|
|
int output_channels;
|
|
|
|
} mixing_info;
|
|
|
|
int channel_layout;
|
|
|
|
struct loop_info {
|
|
|
|
int start;
|
|
|
|
int end;
|
|
|
|
} loop_info;
|
|
|
|
size_t num_samples;
|
|
|
|
char encoding[128];
|
|
|
|
char layout[128];
|
|
|
|
struct interleave_info {
|
|
|
|
int value;
|
|
|
|
int first_block;
|
|
|
|
int last_block;
|
|
|
|
} interleave_info;
|
|
|
|
int frame_size;
|
|
|
|
char metadata[128];
|
|
|
|
int bitrate;
|
|
|
|
struct stream_info {
|
|
|
|
int current;
|
|
|
|
int total;
|
|
|
|
char name[128];
|
|
|
|
} stream_info;
|
|
|
|
} vgmstream_info;
|
2017-12-06 16:55:41 +01:00
|
|
|
|
2017-01-08 01:09:20 +01:00
|
|
|
/* -------------------------------------------------------------------------*/
|
|
|
|
/* vgmstream "public" API */
|
|
|
|
/* -------------------------------------------------------------------------*/
|
|
|
|
|
2008-01-31 07:04:26 +01:00
|
|
|
/* do format detection, return pointer to a usable VGMSTREAM, or NULL on failure */
|
2020-07-18 00:12:44 +02:00
|
|
|
VGMSTREAM* init_vgmstream(const char* const filename);
|
2008-01-31 07:04:26 +01:00
|
|
|
|
2017-11-10 20:26:44 +01:00
|
|
|
/* init with custom IO via streamfile */
|
2020-07-17 22:35:32 +02:00
|
|
|
VGMSTREAM* init_vgmstream_from_STREAMFILE(STREAMFILE* sf);
|
2008-03-25 08:30:04 +01:00
|
|
|
|
2008-05-19 05:58:15 +02:00
|
|
|
/* reset a VGMSTREAM to start of stream */
|
2020-07-17 22:35:32 +02:00
|
|
|
void reset_vgmstream(VGMSTREAM* vgmstream);
|
2008-05-19 05:58:15 +02:00
|
|
|
|
2017-01-08 01:09:20 +01:00
|
|
|
/* close an open vgmstream */
|
2020-07-17 22:35:32 +02:00
|
|
|
void close_vgmstream(VGMSTREAM* vgmstream);
|
2008-01-31 07:04:26 +01:00
|
|
|
|
2020-07-26 17:16:46 +02:00
|
|
|
/* Decode data into sample buffer. Returns < sample_count on stream end */
|
|
|
|
int render_vgmstream(sample_t* buffer, int32_t sample_count, VGMSTREAM* vgmstream);
|
2008-01-31 07:04:26 +01:00
|
|
|
|
2020-07-29 19:34:55 +02:00
|
|
|
/* Seek to sample position (next render starts from that point). Use only after config is set (vgmstream_apply_config) */
|
2020-07-26 20:15:13 +02:00
|
|
|
void seek_vgmstream(VGMSTREAM* vgmstream, int32_t seek_sample);
|
|
|
|
|
2017-12-06 15:32:52 +01:00
|
|
|
/* Write a description of the stream into array pointed by desc, which must be length bytes long.
|
|
|
|
* Will always be null-terminated if length > 0 */
|
2020-07-17 22:35:32 +02:00
|
|
|
void describe_vgmstream(VGMSTREAM* vgmstream, char* desc, int length);
|
2020-09-28 03:07:10 +02:00
|
|
|
void describe_vgmstream_info(VGMSTREAM* vgmstream, vgmstream_info* desc);
|
2017-01-08 01:09:20 +01:00
|
|
|
|
2017-12-06 15:32:52 +01:00
|
|
|
/* Return the average bitrate in bps of all unique files contained within this stream. */
|
2020-07-17 22:35:32 +02:00
|
|
|
int get_vgmstream_average_bitrate(VGMSTREAM* vgmstream);
|
2017-01-08 01:09:20 +01:00
|
|
|
|
2019-09-15 15:47:41 +02:00
|
|
|
/* 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);
|
|
|
|
|
2017-01-08 01:09:20 +01:00
|
|
|
/* -------------------------------------------------------------------------*/
|
|
|
|
/* vgmstream "private" API */
|
|
|
|
/* -------------------------------------------------------------------------*/
|
|
|
|
|
2019-02-15 22:28:20 +01:00
|
|
|
/* Allocate initial memory for the VGMSTREAM */
|
2020-07-26 18:36:47 +02:00
|
|
|
VGMSTREAM* allocate_vgmstream(int channel_count, int looped);
|
2017-01-08 01:09:20 +01:00
|
|
|
|
2019-02-15 22:28:20 +01:00
|
|
|
/* Prepare the VGMSTREAM's initial state once parsed and ready, but before playing. */
|
2020-07-17 22:35:32 +02:00
|
|
|
void setup_vgmstream(VGMSTREAM* vgmstream);
|
2019-02-15 22:28:20 +01:00
|
|
|
|
|
|
|
/* Open the stream for reading at offset (taking into account layouts, channels and so on).
|
|
|
|
* Returns 0 on failure */
|
2020-07-17 22:35:32 +02:00
|
|
|
int vgmstream_open_stream(VGMSTREAM* vgmstream, STREAMFILE* sf, off_t start_offset);
|
|
|
|
int vgmstream_open_stream_bf(VGMSTREAM* vgmstream, STREAMFILE* sf, off_t start_offset, int force_multibuffer);
|
2017-01-14 00:59:54 +01:00
|
|
|
|
2019-02-15 22:28:20 +01:00
|
|
|
/* Get description info */
|
2020-07-17 22:35:32 +02:00
|
|
|
void get_vgmstream_coding_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);
|
2017-11-10 20:26:44 +01:00
|
|
|
|
2024-08-07 22:35:38 +02:00
|
|
|
/* 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);
|
|
|
|
|
2020-07-26 11:19:52 +02:00
|
|
|
void setup_state_vgmstream(VGMSTREAM* vgmstream);
|
2024-08-07 22:35:38 +02:00
|
|
|
|
|
|
|
/* 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);
|
|
|
|
|
2009-08-30 04:16:54 +02:00
|
|
|
#endif
|