diff --git a/cli/api_example.c b/cli/api_example.c index 36a0f4d4..d7687082 100644 --- a/cli/api_example.c +++ b/cli/api_example.c @@ -5,6 +5,7 @@ #include #include "../src/base/api_internal.h" +#include "../src/streamfile.h" static void usage(const char* progname) { @@ -29,14 +30,14 @@ static libvgmstream_streamfile_t* get_streamfile(const char* filename) { } static int api_example(const char* infile) { -VGM_STEP(); + VGM_STEP(); int err; FILE* outfile = NULL; - bool fill_test; - int pcm16_samples; - int pcm16_bytes; - short* pcm16 = NULL; + bool fill_test = true; + int fill_pcm16_samples; + int fill_pcm16_bytes; + short* fill_pcm16 = NULL; // main init @@ -49,6 +50,7 @@ VGM_STEP(); //.loop_count = 1.0, //.fade_time = 10.0, .ignore_loop = true, + .force_pcm16 = fill_test, }; libvgmstream_setup(lib, &cfg); @@ -57,7 +59,7 @@ VGM_STEP(); libvgmstream_options_t opt = { .libsf = get_streamfile(infile) }; - err = libvgmstream_open(lib, &opt); + err = libvgmstream_open_song(lib, &opt); // external SF is not needed after _open libvgmstream_streamfile_close(opt.libsf); @@ -94,33 +96,28 @@ VGM_STEP(); printf("channels: %i\n", lib->format->channels); printf("sample rate: %i\n", lib->format->sample_rate); printf("codec: %s\n", lib->format->codec_name); - printf("samples: %i\n", (int32_t)lib->format->sample_count); + printf("samples: %i\n", (int32_t)lib->format->stream_samples); printf("\n"); + printf("- decoding: %i\n" , (int32_t)lib->format->play_samples); - - - fill_test = true; - pcm16_samples = 512; - pcm16_bytes = pcm16_samples * sizeof(short) * lib->format->channels; - pcm16 = malloc(pcm16_bytes); - if (!pcm16) goto fail; + fill_pcm16_samples = 512; + fill_pcm16_bytes = fill_pcm16_samples * sizeof(short) * lib->format->channels; + fill_pcm16 = malloc(fill_pcm16_bytes); + if (!fill_pcm16) goto fail; // play file and do something with decoded samples - while (true) { + while (!lib->decoder->done) { //int pos; void* buf; int buf_bytes = 0; - if (lib->decoder->done) - break; - // get current samples if (fill_test) { - err = libvgmstream_fill(lib, pcm16, pcm16_samples); + err = libvgmstream_fill(lib, fill_pcm16, fill_pcm16_samples); if (err < 0) goto fail; - buf = pcm16; + buf = fill_pcm16; buf_bytes = err * sizeof(short) * lib->format->channels; } else { @@ -140,12 +137,12 @@ VGM_STEP(); printf("\n"); // close current streamfile before opening new ones, optional - //libvgmstream_close(lib); + //libvgmstream_close_song(lib); // process done libvgmstream_free(lib); fclose(outfile); - free(pcm16); + free(fill_pcm16); printf("done\n"); return EXIT_SUCCESS; @@ -153,7 +150,7 @@ fail: // process failed libvgmstream_free(lib); fclose(outfile); - free(pcm16); + free(fill_pcm16); printf("failed!\n"); return EXIT_FAILURE; diff --git a/src/base/api_decode_open.c b/src/base/api_decode_open.c index 4a0d526f..6dc96367 100644 --- a/src/base/api_decode_open.c +++ b/src/base/api_decode_open.c @@ -9,9 +9,9 @@ static void load_vgmstream(libvgmstream_priv_t* priv, libvgmstream_options_t* op if (!sf_api) return; - //TODO: handle format_internal_id + //TODO: handle internal format_id - sf_api->stream_index = opt->subsong; + sf_api->stream_index = opt->subsong_index; priv->vgmstream = init_vgmstream_from_STREAMFILE(sf_api); close_streamfile(sf_api); } @@ -77,7 +77,7 @@ static void update_format_info(libvgmstream_priv_t* priv) { vgmstream_mixing_enable(v, 0, &fmt->input_channels, &fmt->channels); fmt->channel_layout = v->channel_layout; - fmt->sample_count = v->num_samples; + fmt->stream_samples = v->num_samples; fmt->loop_start = v->loop_start_sample; fmt->loop_end = v->loop_end_sample; fmt->loop_flag = v->loop_flag; @@ -85,6 +85,8 @@ static void update_format_info(libvgmstream_priv_t* priv) { fmt->play_forever = priv->pos.play_forever; fmt->play_samples = priv->pos.play_samples; + fmt->format_id = v->format_id; + fmt->stream_bitrate = get_vgmstream_average_bitrate(v); get_vgmstream_coding_description(v, fmt->codec_name, sizeof(fmt->codec_name)); @@ -94,18 +96,16 @@ static void update_format_info(libvgmstream_priv_t* priv) { if (v->stream_name[0] != '\0') { //snprintf UB for NULL args snprintf(fmt->stream_name, sizeof(fmt->stream_name), "%s", v->stream_name); } - - fmt->format_internal_id = 0; //TODO } -LIBVGMSTREAM_API int libvgmstream_open(libvgmstream_t* lib, libvgmstream_options_t* opt) { +LIBVGMSTREAM_API int libvgmstream_open_song(libvgmstream_t* lib, libvgmstream_options_t* opt) { if (!lib ||!lib->priv) return LIBVGMSTREAM_ERROR_GENERIC; - if (!opt || !opt->libsf || opt->subsong < 0) + if (!opt || !opt->libsf || opt->subsong_index < 0) return LIBVGMSTREAM_ERROR_GENERIC; // close loaded song if any + reset - libvgmstream_close(lib); + libvgmstream_close_song(lib); libvgmstream_priv_t* priv = lib->priv; @@ -123,7 +123,7 @@ LIBVGMSTREAM_API int libvgmstream_open(libvgmstream_t* lib, libvgmstream_options } -LIBVGMSTREAM_API void libvgmstream_close(libvgmstream_t* lib) { +LIBVGMSTREAM_API void libvgmstream_close_song(libvgmstream_t* lib) { if (!lib || !lib->priv) return; diff --git a/src/libvgmstream.h b/src/libvgmstream.h index 3287dcb1..bd7ca84a 100644 --- a/src/libvgmstream.h +++ b/src/libvgmstream.h @@ -3,7 +3,7 @@ #ifndef _LIBVGMSTREAM_H_ #define _LIBVGMSTREAM_H_ -//#define LIBVGMSTREAM_ENABLE 1 +#define LIBVGMSTREAM_ENABLE 1 #if LIBVGMSTREAM_ENABLE /* By default vgmstream behaves like a decoder (decode samples until stream end), but you can configure @@ -21,7 +21,7 @@ * Basic usage (also see api_example.c): * - libvgmstream_init(...) // base context * - libvgmstream_setup(...) // config if needed - * - libvgmstream_open(...) // setup format + * - libvgmstream_open_song(...) // setup format * - libvgmstream_play(...) // main decode * - output samples + repeat libvgmstream_play until stream is done * - libvgmstream_free(...) // cleanup @@ -104,7 +104,7 @@ typedef struct { //int frame_size; // when file has some configurable frame size /* sample info (may not be used depending on config) */ - int64_t sample_count; // file's max samples (not final play duration) + int64_t stream_samples; // file's max samples (not final play duration) int64_t loop_start; // loop start sample int64_t loop_end; // loop end sample bool loop_flag; // if file loops (false + defined loops means looping was forcefully disabled) @@ -130,7 +130,7 @@ typedef struct { /* misc */ //bool rough_samples; // signal cases where loop points or sample count can't exactly reflect actual behavior - int format_internal_id; // when reopening subfiles or similar formats without checking other all possible formats + int format_id; // when reopening subfiles or similar formats without checking other all possible formats // ** this value WILL change without warning between vgmstream versions/commits } libvgmstream_format_t; @@ -202,10 +202,10 @@ typedef struct { libvgmstream_streamfile_t* libsf; // custom IO streamfile that provides reader info for vgmstream // ** not needed after _open and should be closed, as vgmstream re-opens its own SFs internally as needed - int subsong; // target subsong (1..N) or 0 = default/first + int subsong_index; // target subsong (1..N) or 0 = default/first // ** to check if a file has subsongs, _open first + check format->total_subsongs (then _open 2nd, 3rd, etc) - int format_internal_id; // force a format (for example when loading new subsong of the same archive) + int format_id; // force a format (for example when loading new subsong of the same archive) int stereo_track; // forces vgmstream to decode one 2ch+2ch+2ch... 'track' and discard other channels, where 0 = disabled, 1..N = Nth track @@ -215,11 +215,11 @@ typedef struct { * - returns < 0 on error (file not recognised, invalid subsong index, etc) * - will close currently loaded song if needed */ -LIBVGMSTREAM_API int libvgmstream_open(libvgmstream_t* lib, libvgmstream_options_t* open_options); +LIBVGMSTREAM_API int libvgmstream_open_song(libvgmstream_t* lib, libvgmstream_options_t* open_options); /* Closes current song; may still use libvgmstream to open other songs */ -LIBVGMSTREAM_API void libvgmstream_close(libvgmstream_t* lib); +LIBVGMSTREAM_API void libvgmstream_close_song(libvgmstream_t* lib); /* Decodes next batch of samples