Add vgmstream_force_loop, comments (API cleanup)

This commit is contained in:
bnnm 2017-12-06 16:55:41 +01:00
parent f74f9f0b24
commit 53698db7c3
3 changed files with 69 additions and 30 deletions

View File

@ -897,7 +897,22 @@ int32_t get_vgmstream_play_samples(double looptimes, double fadeseconds, double
} }
} }
/* decode data into sample buffer */ void vgmstream_force_loop(VGMSTREAM* vgmstream, int loop_flag, int loop_start_sample, int loop_end_sample) {
if (!vgmstream) return;
/* this requires a bit more messing with the VGMSTREAM than I'm comfortable with... */
if (loop_flag && !vgmstream->loop_flag && !vgmstream->loop_ch) {
vgmstream->loop_ch = calloc(vgmstream->channels,sizeof(VGMSTREAMCHANNEL));
/* loop_ch will be populated when decoded samples reach loop start */
}
vgmstream->loop_flag = loop_flag;
if (loop_flag) {
vgmstream->loop_start_sample = loop_start_sample;
vgmstream->loop_end_sample = loop_end_sample;
}
}
/* Decode data into sample buffer */
void render_vgmstream(sample * buffer, int32_t sample_count, VGMSTREAM * vgmstream) { void render_vgmstream(sample * buffer, int32_t sample_count, VGMSTREAM * vgmstream) {
switch (vgmstream->layout_type) { switch (vgmstream->layout_type) {
case layout_interleave: case layout_interleave:

View File

@ -1155,6 +1155,45 @@ typedef struct {
} ea_mt_codec_data; } ea_mt_codec_data;
#if 0
//possible future public/opaque API
/* define standard C param call and name mangling (to avoid __stdcall / .defs) */
#define VGMSTREAM_CALL __cdecl //needed?
/* define external function types (during compilation) */
#if defined(VGMSTREAM_EXPORT)
#define VGMSTREAM_API __declspec(dllexport) /* when exporting/creating vgmstream DLL */
#elif defined(VGMSTREAM_IMPORT)
#define VGMSTREAM_API __declspec(dllimport) /* when importing/linking vgmstream DLL */
#else
#define VGMSTREAM_API /* nothing, internal/default */
#endif
//VGMSTREAM_API void VGMSTREAM_CALL vgmstream_function(void);
//info for opaque VGMSTREAM
typedef struct {
int channels;
int sample_rate;
int num_samples;
int loop_start_sample;
int loop_end_sample;
int loop_flag;
int num_streams;
int current_sample;
int average_bitrate;
} VGMSTREAM_INFO;
void vgmstream_get_info(VGMSTREAM* vgmstream, VGMSTREAM_INFO *vgmstream_info);
//or maybe
enum vgmstream_value_t { VGMSTREAM_CHANNELS, VGMSTREAM_CURRENT_SAMPLE, ... };
int vgmstream_get_info(VGMSTREAM* vgmstream, vgmstream_value_t type);
// or
int vgmstream_get_current_sample(VGMSTREAM* vgmstream);
#endif
/* -------------------------------------------------------------------------*/ /* -------------------------------------------------------------------------*/
/* vgmstream "public" API */ /* vgmstream "public" API */
/* -------------------------------------------------------------------------*/ /* -------------------------------------------------------------------------*/
@ -1174,7 +1213,7 @@ void close_vgmstream(VGMSTREAM * vgmstream);
/* calculate the number of samples to be played based on looping parameters */ /* 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); int32_t get_vgmstream_play_samples(double looptimes, double fadeseconds, double fadedelayseconds, VGMSTREAM * vgmstream);
/* render! */ /* Decode data into sample buffer */
void render_vgmstream(sample * buffer, int32_t sample_count, VGMSTREAM * vgmstream); void render_vgmstream(sample * buffer, int32_t sample_count, VGMSTREAM * vgmstream);
/* Write a description of the stream into array pointed by desc, which must be length bytes long. /* Write a description of the stream into array pointed by desc, which must be length bytes long.
@ -1187,6 +1226,10 @@ int get_vgmstream_average_bitrate(VGMSTREAM * vgmstream);
/* List supported formats and return elements in the list, for plugins that need to know. */ /* List supported formats and return elements in the list, for plugins that need to know. */
const char ** vgmstream_get_formats(size_t * size); const char ** vgmstream_get_formats(size_t * size);
/* Force enable/disable internal looping. Should be done before playing anything,
* 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);
/* -------------------------------------------------------------------------*/ /* -------------------------------------------------------------------------*/
/* vgmstream "private" API */ /* vgmstream "private" API */
/* -------------------------------------------------------------------------*/ /* -------------------------------------------------------------------------*/

View File

@ -208,26 +208,16 @@ int main(int argc, char ** argv) {
} }
} }
/* force only if there aren't already loop points */
if (force_loop && !vgmstream->loop_flag) { if (force_loop && !vgmstream->loop_flag) {
/* this requires a bit more messing with the VGMSTREAM than I'm comfortable with... */ vgmstream_force_loop(vgmstream, 1, 0,vgmstream->num_samples);
vgmstream->loop_flag=1;
vgmstream->loop_start_sample=0;
vgmstream->loop_end_sample=vgmstream->num_samples;
vgmstream->loop_ch=calloc(vgmstream->channels,sizeof(VGMSTREAMCHANNEL));
} }
/* force even if there are loop points */
if (really_force_loop) { if (really_force_loop) {
if (!vgmstream->loop_flag) vgmstream_force_loop(vgmstream, 1, 0,vgmstream->num_samples);
vgmstream->loop_ch=calloc(vgmstream->channels,sizeof(VGMSTREAMCHANNEL));
vgmstream->loop_flag=1;
vgmstream->loop_start_sample=0;
vgmstream->loop_end_sample=vgmstream->num_samples;
} }
if (ignore_loop) { if (ignore_loop) {
vgmstream->loop_flag=0; vgmstream_force_loop(vgmstream, 0, 0,0);
} }
if (play_sdtout) { if (play_sdtout) {
@ -379,7 +369,8 @@ int main(int argc, char ** argv) {
} }
} }
if (write_lwav && vgmstream->loop_flag) { // Writing smpl chuck /* Writing "smpl" chunck at the end */
if (write_lwav && vgmstream->loop_flag) {
make_smpl_chunk((uint8_t*)buf, vgmstream->loop_start_sample, vgmstream->loop_end_sample); make_smpl_chunk((uint8_t*)buf, vgmstream->loop_start_sample, vgmstream->loop_end_sample);
fwrite(buf,1,0x44,outfile); fwrite(buf,1,0x44,outfile);
} }
@ -426,26 +417,16 @@ int main(int argc, char ** argv) {
/* these manipulations are undone by reset */ /* these manipulations are undone by reset */
/* force only if there aren't already loop points */
if (force_loop && !vgmstream->loop_flag) { if (force_loop && !vgmstream->loop_flag) {
/* this requires a bit more messing with the VGMSTREAM than I'm comfortable with... */ vgmstream_force_loop(vgmstream, 1, 0,vgmstream->num_samples);
vgmstream->loop_flag=1;
vgmstream->loop_start_sample=0;
vgmstream->loop_end_sample=vgmstream->num_samples;
vgmstream->loop_ch=calloc(vgmstream->channels,sizeof(VGMSTREAMCHANNEL));
} }
/* force even if there are loop points */
if (really_force_loop) { if (really_force_loop) {
if (!vgmstream->loop_flag) vgmstream_force_loop(vgmstream, 1, 0,vgmstream->num_samples);
vgmstream->loop_ch=calloc(vgmstream->channels,sizeof(VGMSTREAMCHANNEL));
vgmstream->loop_flag=1;
vgmstream->loop_start_sample=0;
vgmstream->loop_end_sample=vgmstream->num_samples;
} }
if (ignore_loop) { if (ignore_loop) {
vgmstream->loop_flag=0; vgmstream_force_loop(vgmstream, 0, 0,0);
} }
/* decode */ /* decode */
@ -521,7 +502,7 @@ static void make_wav_header(uint8_t * buf, int32_t sample_count, int32_t sample_
} }
static void make_smpl_chunk(uint8_t * buf, int32_t loop_start, int32_t loop_end) { static void make_smpl_chunk(uint8_t * buf, int32_t loop_start, int32_t loop_end) {
int i; int i;
memcpy(buf+0, "smpl", 4);/* header */ memcpy(buf+0, "smpl", 4);/* header */
put_32bitLE(buf+4, 0x3c);/* size */ put_32bitLE(buf+4, 0x3c);/* size */