diff --git a/.gitignore b/.gitignore index cef08245..fa8918da 100644 --- a/.gitignore +++ b/.gitignore @@ -45,3 +45,6 @@ Release /**/test.zip /**/foo_input_vgmstream.fb2k-component + +/build +/cmake-build* \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index dbc580a0..418609a6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -111,6 +111,17 @@ else() endif() endif() + # Only build JSON dumping capabilities on Linux + pkg_check_modules(JANSSON jansson>=2.3) + if (JANSSON_FOUND) + set(USE_JANSSON ON) + set(JANSSON_PKG libjansson) + include_directories(${JANSSON_INCLUDE_DIRS}) + link_directories(${JANSSON_LIBRARY_DIRS}) + else (JANSSON_FOUND) + set(USE_JANSSON OFF) + endif (JANSSON_FOUND) + # If building Audacious, we need to make sure we can find its pkg-config module as well as GTK's if(BUILD_AUDACIOUS) include(FindPkgConfig) @@ -120,6 +131,7 @@ else() endif() endif() + # Set compiler flags if(CMAKE_CXX_COMPILER_ID MATCHES Clang OR CMAKE_CXX_COMPILER_ID MATCHES GNU) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall") @@ -230,11 +242,13 @@ message(STATUS " Building") message(STATUS "=========================") if(WIN32) message(STATUS " CLI: ${BUILD_CLI}") + message(STATUS " JSON dumping: ${USE_JANSSON}") message(STATUS "foobar2000 component: ${BUILD_FB2K}") message(STATUS " Winamp plugin: ${BUILD_WINAMP}") message(STATUS " XMPlay plugin: ${BUILD_XMPLAY}") else() message(STATUS "CLI/vgmstream123: ${BUILD_CLI}") + message(STATUS " JSON dumping: ${USE_JANSSON}") message(STATUS "Audacious plugin: ${BUILD_AUDACIOUS}") endif() message(STATUS "") diff --git a/appveyor.yml b/appveyor.yml index 846e1636..9f2128d4 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -27,7 +27,7 @@ for: init: - sudo apt-get update - sudo apt-get install -y libmpg123-dev libvorbis-dev libavformat-dev libavcodec-dev libavutil-dev libswresample-dev - - sudo apt-get install -y libao-dev audacious-dev + - sudo apt-get install -y libao-dev audacious-dev libjansson-dev - sudo apt-get install -y cmake install: - cmake . diff --git a/cli/CMakeLists.txt b/cli/CMakeLists.txt index c3683096..bfd954a8 100644 --- a/cli/CMakeLists.txt +++ b/cli/CMakeLists.txt @@ -6,6 +6,12 @@ add_executable(vgmstream_cli # Link to the vgmstream library target_link_libraries(vgmstream_cli libvgmstream) +# Link to Jansson, if we have it +if (JANSSON_FOUND) + target_compile_definitions(vgmstream_cli PRIVATE HAVE_JSON) + target_link_libraries(vgmstream_cli jansson) +endif() + setup_target(vgmstream_cli TRUE) if(WIN32) @@ -42,6 +48,8 @@ elseif(VGMSTREAM_VERSION) target_compile_definitions(vgmstream_cli PRIVATE VERSION="${VGMSTREAM_VERSION}") endif() + + # Install the CLI program install(TARGETS vgmstream_cli RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/bin) @@ -68,6 +76,8 @@ if(NOT WIN32) # Include the version string target_compile_definitions(vgmstream123 PRIVATE VERSION="${VGMSTREAM_VERSION}") + + # Install vgmstream123 install(TARGETS vgmstream123 RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/bin) diff --git a/cli/vgmstream_cli.c b/cli/vgmstream_cli.c index 850644b4..c636cabd 100644 --- a/cli/vgmstream_cli.c +++ b/cli/vgmstream_cli.c @@ -21,6 +21,10 @@ #define VERSION "(unknown version)" #endif +#ifdef HAVE_JSON +#include "jansson.h" +#endif + /* low values are ok as there is very little performance difference, but higher * may improve write I/O in some systems as this*channels doubles as output buffer */ #define SAMPLE_BUFFER_SIZE 32768 @@ -31,9 +35,6 @@ 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" @@ -118,6 +119,10 @@ typedef struct { int lwav_loop_start; int lwav_loop_end; } cli_config; +#ifdef HAVE_JSON +static void print_json_version(); +static void print_json_info(VGMSTREAM* vgm, cli_config* cfg); +#endif static int parse_config(cli_config* cfg, int argc, char** argv) { @@ -413,7 +418,7 @@ void print_json_version() { json_object_set(final_object, "extensions", ext_list); json_decref(ext_list); - json_dumpf(final_object, stdout, ); + json_dumpf(final_object, stdout, JSON_COMPACT); } #endif @@ -810,7 +815,72 @@ fail: return EXIT_FAILURE; } +#ifdef HAVE_JSON +static void print_json_info(VGMSTREAM* vgm, cli_config* cfg) { + vgmstream_info info; + describe_vgmstream_info(vgm, &info); + json_t* mixing_info = NULL; + if (info.mixing_info.input_channels > 0) { + json_t* mixing_info = json_pack("{sisi}", + "inputChannels", info.mixing_info.input_channels, + "outputChannels", info.mixing_info.output_channels); + } + + json_t* loop_info = NULL; + + if (info.loop_info.end > info.loop_info.start) { + loop_info = json_pack("{sisi}", + "start", info.loop_info.start, + "end", info.loop_info.end); + } + + json_t* interleave_info = NULL; + + if (info.interleave_info.value > 0) { + interleave_info = json_pack("{sisisi}", + "value", info.interleave_info.value, + "firstBlock", info.interleave_info.first_block, + "lastBlock", info.interleave_info.last_block + ); + } + + json_t* stream_info = json_pack("{sisssi}", + "current", info.stream_info.current, + "name", info.stream_info.name, + "total", info.stream_info.total + ); + + json_t* final_object = json_pack( + "{sisiso*siso*so*sisssssisssiso?}", + "sampleRate", info.sample_rate, + "channels", info.channels, + "mixingInfo", mixing_info, + "channelLayout", info.channel_layout, + "loopingInfo", loop_info, + "interleaveInfo", interleave_info, + "numberOfSamples", info.num_samples, + "encoding", info.encoding, + "layout", info.layout, + "frameSize", info.frame_size, + "metadataSource", info.metadata, + "bitrate", info.bitrate, + "streamInfo", stream_info + ); + + if (info.frame_size == 0) { + json_object_del(final_object, "frameSize"); + } + + if (info.channel_layout == 0) { + json_object_del(final_object, "channelLayout"); + } + + json_dumpf(final_object, stdout, JSON_INDENT(4)); + + json_decref(final_object); +} +#endif static void make_smpl_chunk(uint8_t* buf, int32_t loop_start, int32_t loop_end) { int i; diff --git a/configure.ac b/configure.ac index 309c88e8..06f7aba6 100644 --- a/configure.ac +++ b/configure.ac @@ -56,6 +56,11 @@ PKG_CHECK_MODULES(AO, [ao >= 1.1.0], have_libao=yes, [AC_MSG_WARN([Cannot find libao - will not build vgmstream123])]) AM_CONDITIONAL(HAVE_LIBAO, test "$have_libao" = yes) +have_jansson=no +PKG_CHECK_MODULES(JANSSON, [jansson >= 2.3], have_jansson=yes, + [AC_MSG_WARN([Cannot find jansson - will disable JSON dumping in CLI])]) +AM_CONDITIONAL(HAVE_JANSSON, test "$have_jansson" = yes) + if test "_$GCC" = _yes then CFLAGS="$CFLAGS -Wall -Wextra -Wno-sign-compare -Wno-unused-parameter -Wno-unused-but-set-variable"