mirror of
https://github.com/vgmstream/vgmstream.git
synced 2025-01-18 15:54:05 +01:00
Implement skeleton JSON code
This commit is contained in:
parent
3d8e559d3d
commit
6c9de061f3
@ -31,6 +31,9 @@ extern int optind, opterr, optopt;
|
||||
|
||||
|
||||
static size_t make_wav_header(uint8_t* buf, size_t buf_size, int32_t sample_count, int32_t sample_rate, int channels, int smpl_chunk, int32_t loop_start, int32_t loop_end);
|
||||
#ifdef HAVE_JSON
|
||||
static void print_json_version();
|
||||
#endif
|
||||
|
||||
static void usage(const char* name, int is_full) {
|
||||
fprintf(stderr,"vgmstream CLI decoder " VERSION " " __DATE__ "\n"
|
||||
@ -56,6 +59,10 @@ static void usage(const char* name, int is_full) {
|
||||
" -g: decode and print oggenc command line to encode as OGG\n"
|
||||
" -b: decode and print batch variable commands\n"
|
||||
" -h: print extra commands (for testing)\n"
|
||||
#ifdef HAVE_JSON
|
||||
" -V: print version info and supported extensions as JSON\n"
|
||||
" -I: print requested file info as JSON\n"
|
||||
#endif
|
||||
, name);
|
||||
if (!is_full)
|
||||
return;
|
||||
@ -81,6 +88,9 @@ typedef struct {
|
||||
int play_sdtout;
|
||||
int play_wreckless;
|
||||
int print_metaonly;
|
||||
#ifdef HAVE_JSON
|
||||
int print_metajson;
|
||||
#endif
|
||||
int print_adxencd;
|
||||
int print_oggenc;
|
||||
int print_batchvar;
|
||||
@ -124,7 +134,11 @@ static int parse_config(cli_config* cfg, int argc, char** argv) {
|
||||
opterr = 0;
|
||||
|
||||
/* read config */
|
||||
while ((opt = getopt(argc, argv, "o:l:f:d:ipPcmxeLEFrgb2:s:t:Tk:K:hOvD:")) != -1) {
|
||||
while ((opt = getopt(argc, argv, "o:l:f:d:ipPcmxeLEFrgb2:s:t:Tk:K:hOvD:"
|
||||
#ifdef HAVE_JSON
|
||||
"VI"
|
||||
#endif
|
||||
)) != -1) {
|
||||
switch (opt) {
|
||||
case 'o':
|
||||
cfg->outfilename = optarg;
|
||||
@ -208,6 +222,15 @@ static int parse_config(cli_config* cfg, int argc, char** argv) {
|
||||
case 'h':
|
||||
usage(argv[0], 1);
|
||||
goto fail;
|
||||
#ifdef HAVE_JSON
|
||||
case 'V':
|
||||
print_json_version();
|
||||
goto fail;
|
||||
case 'I':
|
||||
cfg->print_metaonly = 1;
|
||||
cfg->print_metajson = 1;
|
||||
break;
|
||||
#endif
|
||||
case '?':
|
||||
fprintf(stderr, "Unknown option -%c found\n", optopt);
|
||||
goto fail;
|
||||
@ -367,6 +390,33 @@ static void print_title(VGMSTREAM* vgmstream, cli_config* cfg) {
|
||||
printf("title: %s\n", title);
|
||||
}
|
||||
|
||||
#ifdef HAVE_JSON
|
||||
void print_json_version() {
|
||||
size_t extension_list_len;
|
||||
const char** extension_list;
|
||||
extension_list = vgmstream_get_formats(&extension_list_len);
|
||||
|
||||
json_t* ext_list = json_array();
|
||||
|
||||
for (size_t i = 0; i < extension_list_len; ++i) {
|
||||
json_t* ext = json_string(extension_list[i]);
|
||||
json_array_append(ext_list, ext);
|
||||
json_decref(ext);
|
||||
}
|
||||
|
||||
json_t* version_string = json_string(VERSION);
|
||||
|
||||
json_t* final_object = json_object();
|
||||
json_object_set(final_object, "version", version_string);
|
||||
json_decref(version_string);
|
||||
|
||||
json_object_set(final_object, "extensions", ext_list);
|
||||
json_decref(ext_list);
|
||||
|
||||
json_dumpf(final_object, stdout, );
|
||||
}
|
||||
#endif
|
||||
|
||||
static void clean_filename(char* dst, int clean_paths) {
|
||||
int i;
|
||||
for (i = 0; i < strlen(dst); i++) {
|
||||
@ -582,9 +632,18 @@ int main(int argc, char** argv) {
|
||||
|
||||
|
||||
/* prints */
|
||||
print_info(vgmstream, &cfg);
|
||||
print_tags(&cfg);
|
||||
print_title(vgmstream, &cfg);
|
||||
#ifdef HAVE_JSON
|
||||
if (!cfg.print_metajson) {
|
||||
#endif
|
||||
print_info(vgmstream, &cfg);
|
||||
print_tags(&cfg);
|
||||
print_title(vgmstream, &cfg);
|
||||
#ifdef HAVE_JSON
|
||||
}
|
||||
else {
|
||||
print_json_info(vgmstream, &cfg);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* prints done */
|
||||
if (cfg.print_metaonly) {
|
||||
|
@ -1042,6 +1042,95 @@ void describe_vgmstream(VGMSTREAM* vgmstream, char* desc, int length) {
|
||||
}
|
||||
}
|
||||
|
||||
void describe_vgmstream_info(VGMSTREAM* vgmstream, vgmstream_info* info) {
|
||||
if (!info) {
|
||||
return;
|
||||
}
|
||||
|
||||
memset(info, 0, sizeof(*info));
|
||||
|
||||
if (!vgmstream) {
|
||||
return;
|
||||
}
|
||||
|
||||
info->sample_rate = vgmstream->sample_rate;
|
||||
|
||||
info->channels = vgmstream->channels;
|
||||
|
||||
{
|
||||
int output_channels = 0;
|
||||
mixing_info(vgmstream, NULL, &output_channels);
|
||||
|
||||
if (output_channels != vgmstream->channels) {
|
||||
info->mixing_info.input_channels = vgmstream->channels;
|
||||
info->mixing_info.output_channels = output_channels;
|
||||
}
|
||||
}
|
||||
|
||||
info->channel_layout = vgmstream->channel_layout;
|
||||
|
||||
if (vgmstream->loop_start_sample >= 0 && vgmstream->loop_end_sample > vgmstream->loop_start_sample) {
|
||||
info->loop_info.start = vgmstream->loop_start_sample;
|
||||
info->loop_info.end = vgmstream->loop_end_sample;
|
||||
}
|
||||
|
||||
info->num_samples = vgmstream->num_samples;
|
||||
|
||||
get_vgmstream_coding_description(vgmstream, info->encoding, sizeof(info->encoding));
|
||||
|
||||
get_vgmstream_layout_description(vgmstream, info->layout, sizeof(info->layout));
|
||||
|
||||
if (vgmstream->layout_type == layout_interleave && vgmstream->channels > 1) {
|
||||
info->interleave_info.value = vgmstream->interleave_block_size;
|
||||
|
||||
if (vgmstream->interleave_first_block_size && vgmstream->interleave_first_block_size != vgmstream->interleave_block_size) {
|
||||
info->interleave_info.first_block = vgmstream->interleave_first_block_size;
|
||||
}
|
||||
|
||||
if (vgmstream->interleave_last_block_size && vgmstream->interleave_last_block_size != vgmstream->interleave_block_size) {
|
||||
info->interleave_info.last_block = vgmstream->interleave_last_block_size;
|
||||
}
|
||||
}
|
||||
|
||||
/* codecs with configurable frame size */
|
||||
if (vgmstream->frame_size > 0 || vgmstream->interleave_block_size > 0) {
|
||||
int32_t frame_size = vgmstream->frame_size > 0 ? vgmstream->frame_size : vgmstream->interleave_block_size;
|
||||
switch (vgmstream->coding_type) {
|
||||
case coding_MSADPCM:
|
||||
case coding_MSADPCM_int:
|
||||
case coding_MSADPCM_ck:
|
||||
case coding_MS_IMA:
|
||||
case coding_MC3:
|
||||
case coding_WWISE_IMA:
|
||||
case coding_REF_IMA:
|
||||
case coding_PSX_cfg:
|
||||
info->frame_size = frame_size;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
get_vgmstream_meta_description(vgmstream, info->metadata, sizeof(info->metadata));
|
||||
|
||||
info->bitrate = get_vgmstream_average_bitrate(vgmstream);
|
||||
|
||||
/* only interesting if more than one */
|
||||
if (vgmstream->num_streams > 1) {
|
||||
info->stream_info.total = vgmstream->num_streams;
|
||||
}
|
||||
else {
|
||||
info->stream_info.total = 1;
|
||||
}
|
||||
|
||||
if (vgmstream->num_streams > 1) {
|
||||
info->stream_info.current = vgmstream->stream_index == 0 ? 1 : vgmstream->stream_index;
|
||||
}
|
||||
|
||||
if (vgmstream->stream_name[0] != '\0') {
|
||||
snprintf(info->stream_info.name, sizeof(info->stream_info.name), "%s", vgmstream->stream_name);
|
||||
}
|
||||
}
|
||||
|
||||
/* See if there is a second file which may be the second channel, given an already opened mono vgmstream.
|
||||
* If a suitable file is found, open it and change opened_vgmstream to a stereo vgmstream. */
|
||||
|
@ -1094,6 +1094,36 @@ typedef struct {
|
||||
#endif
|
||||
#endif //VGM_USE_MP4V2
|
||||
|
||||
// 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;
|
||||
|
||||
/* -------------------------------------------------------------------------*/
|
||||
/* vgmstream "public" API */
|
||||
@ -1123,6 +1153,7 @@ void seek_vgmstream(VGMSTREAM* vgmstream, int32_t seek_sample);
|
||||
/* 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 */
|
||||
void describe_vgmstream(VGMSTREAM* vgmstream, char* desc, int length);
|
||||
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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user