mirror of
https://github.com/vgmstream/vgmstream.git
synced 2025-02-17 19:19:16 +01:00
commit
7fb4a05b36
51
README.md
51
README.md
@ -46,25 +46,26 @@ or in a system directory, or any other directory in the PATH variable.
|
||||
```
|
||||
Usage: test.exe [-o outfile.wav] [options] infile
|
||||
Options:
|
||||
-o outfile.wav: name of output .wav file, default is infile.wav
|
||||
-o outfile.wav: name of output .wav file, default infile.wav
|
||||
-l loop count: loop count, default 2.0
|
||||
-f fade time: fade time (seconds), default 10.0
|
||||
-d fade delay: fade delay (seconds, default 0.0
|
||||
-f fade time: fade time in seconds after N loops, default 10.0
|
||||
-d fade delay: fade delay in seconds, default 0.0
|
||||
-F: don't fade after N loops and play the rest of the stream
|
||||
-i: ignore looping information and play the whole stream once
|
||||
-e: force end-to-end looping
|
||||
-E: force end-to-end looping even if file has real loop points
|
||||
-s N: select subsong N, if the format supports multiple subsongs
|
||||
-m: print metadata only, don't decode
|
||||
-L: append a smpl chunk and create a looping wav
|
||||
-2 N: only output the Nth (first is 0) set of stereo channels
|
||||
-p: output to stdout (for piping into another program)
|
||||
-P: output to stdout even if stdout is a terminal
|
||||
-c: loop forever (continuously)
|
||||
-m: print metadata only, don't decode
|
||||
-c: loop forever (continuously) to stdout
|
||||
-x: decode and print adxencd command line to encode as ADX
|
||||
-g: decode and print oggenc command line to encode as OGG
|
||||
-b: decode and print batch variable commands
|
||||
-L: append a smpl chunk and create a looping wav
|
||||
-e: force end-to-end looping
|
||||
-E: force end-to-end looping even if file has real loop points
|
||||
-r outfile2.wav: output a second time after resetting
|
||||
-2 N: only output the Nth (first is 0) set of stereo channels
|
||||
-F: don't fade after N loops and play the rest of the stream
|
||||
-s N: select subsong N, if the format supports multiple subsongs
|
||||
-r: output a second file after resetting (for testing)
|
||||
-t file: print if tags are found in file
|
||||
```
|
||||
Typical usage would be: ```test -o happy.wav happy.adx``` to decode ```happy.adx``` to ```happy.wav```.
|
||||
|
||||
@ -232,6 +233,32 @@ Creation of those files is meant for advanced users, docs can be found in
|
||||
vgmstream source.
|
||||
|
||||
|
||||
## Tagging
|
||||
Some of vgmstream's plugins support simple read-only tagging via external files.
|
||||
|
||||
Tags are loaded from a text/M3U-like file named _!tags.m3u_ in the song folder.
|
||||
You don't have to load your songs with that M3U though (but you can, for pre-made
|
||||
ordering), the file itself just 'looks' like an M3U.
|
||||
|
||||
Format is:
|
||||
```
|
||||
# ignored comment
|
||||
# @GLOBAL_TAG value (applies all following tracks)
|
||||
|
||||
# %LOCAL_TAG value (applies to next track only)
|
||||
filename1
|
||||
# %LOCAL_TAG value (applies to next track only)
|
||||
filename2
|
||||
```
|
||||
Accepted tags depend on the player (foobar: any; winamp: see ATF config),
|
||||
typically ALBUM/ARTIST/TITLE/DISC/TRACK/COMPOSER/etc, lower or uppercase,
|
||||
separated by one or multiple spaces. Repeated tags overwrite previous
|
||||
(ex.- may define @COMPOSER for multiple tracks). It only reads up to current
|
||||
_filename_ though, so any @TAG below would be ignored.
|
||||
|
||||
Playlist formatting should follow player's config. ASCII or UTF-8 tags work.
|
||||
|
||||
|
||||
## Supported codec types
|
||||
Quick list of codecs vgmstream supports, including many obscure ones that
|
||||
are used in few games.
|
||||
|
@ -1,6 +1,7 @@
|
||||
#define POSIXLY_CORRECT
|
||||
#include <getopt.h>
|
||||
#include "../src/vgmstream.h"
|
||||
#include "../src/plugins.h"
|
||||
#include "../src/util.h"
|
||||
#ifdef WIN32
|
||||
#include <io.h>
|
||||
@ -52,6 +53,7 @@ static void usage(const char * name) {
|
||||
" -g: decode and print oggenc command line to encode as OGG\n"
|
||||
" -b: decode and print batch variable commands\n"
|
||||
" -r: output a second file after resetting (for testing)\n"
|
||||
" -t file: print if tags are found in file\n"
|
||||
, name);
|
||||
}
|
||||
|
||||
@ -59,6 +61,7 @@ static void usage(const char * name) {
|
||||
typedef struct {
|
||||
char * infilename;
|
||||
char * outfilename;
|
||||
char * tag_filename;
|
||||
int ignore_loop;
|
||||
int force_loop;
|
||||
int really_force_loop;
|
||||
@ -96,7 +99,7 @@ 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:")) != -1) {
|
||||
while ((opt = getopt(argc, argv, "o:l:f:d:ipPcmxeLEFrgb2:s:t:")) != -1) {
|
||||
switch (opt) {
|
||||
case 'o':
|
||||
cfg->outfilename = optarg;
|
||||
@ -156,6 +159,9 @@ static int parse_config(cli_config *cfg, int argc, char ** argv) {
|
||||
case 's':
|
||||
cfg->stream_index = atoi(optarg);
|
||||
break;
|
||||
case 't':
|
||||
cfg->tag_filename= optarg;
|
||||
break;
|
||||
case '?':
|
||||
fprintf(stderr, "Unknown option -%c found\n", optopt);
|
||||
goto fail;
|
||||
@ -323,6 +329,8 @@ void apply_fade(sample * buf, VGMSTREAM * vgmstream, int to_get, int i, int len_
|
||||
}
|
||||
}
|
||||
|
||||
/* ************************************************************ */
|
||||
|
||||
int main(int argc, char ** argv) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
FILE * outfile = NULL;
|
||||
@ -403,6 +411,27 @@ int main(int argc, char ** argv) {
|
||||
|
||||
/* print file info (or batch commands, depending on config) */
|
||||
print_info(vgmstream, &cfg);
|
||||
|
||||
/* print tags info */
|
||||
if (cfg.tag_filename) {
|
||||
VGMSTREAM_TAGS tag;
|
||||
|
||||
STREAMFILE *tagFile = open_stdio_streamfile(cfg.tag_filename);
|
||||
if (!tagFile) {
|
||||
fprintf(stderr,"tag file %s not found\n",cfg.tag_filename);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
printf("tags:\n");
|
||||
vgmstream_tags_reset(&tag, cfg.infilename);
|
||||
while ( vgmstream_tags_next_tag(&tag, tagFile)) {
|
||||
printf("- '%s'='%s'\n", tag.key, tag.val);
|
||||
}
|
||||
|
||||
close_streamfile(tagFile);
|
||||
}
|
||||
|
||||
/* prints done */
|
||||
if (cfg.print_metaonly) {
|
||||
if (!cfg.play_sdtout)
|
||||
fclose(outfile);
|
||||
|
@ -102,7 +102,7 @@ file2.ext#m2-3,4-5,4-6 # ogg "FL CN FR BL BR SB" to wav "FL FR CN SB BL BR"
|
||||
Those setting should override player's defaults if set (except "loop forever"). They are equivalent to some test.exe options.
|
||||
|
||||
- __God Hand (PS2)__: _boss2_3ningumi_ver6.txtp_ (each line is a separate TXTP)
|
||||
<EFBFBD><EFBFBD><EFBFBD>
|
||||
```
|
||||
# set number of loops
|
||||
boss2_3ningumi_ver6.adx#l3
|
||||
|
||||
@ -128,7 +128,7 @@ boss2_3ningumi_ver6.adx#l2#F # 2 loops + ending
|
||||
boss2_3ningumi_ver6.adx#l1.5#d1#f5
|
||||
|
||||
# boss2_3ningumi_ver6.adx#l1.0#F # this is equivalent to #i
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
```
|
||||
|
||||
For segments and layers the first file defines looping options.
|
||||
|
||||
|
@ -3,13 +3,13 @@
|
||||
* BSD License:
|
||||
****************************************************************************
|
||||
*
|
||||
* Copyright (c) 2005-2007 Paul Hsieh
|
||||
* Copyright (c) 2005-2016 Paul Hsieh
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
@ -17,7 +17,7 @@
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
@ -31,30 +31,28 @@
|
||||
*
|
||||
****************************************************************************
|
||||
*
|
||||
* Version 0.1.10
|
||||
* Version 0.1.16.0
|
||||
*
|
||||
* The ANSI C standard committee, for the C99 standard, specified the
|
||||
* inclusion of a new standard include file called stdint.h. This is
|
||||
* a very useful and long desired include file which contains several
|
||||
* very precise definitions for integer scalar types that is
|
||||
* critically important for making portable several classes of
|
||||
* applications including cryptography, hashing, variable length
|
||||
* integer libraries and so on. But for most developers its likely
|
||||
* useful just for programming sanity.
|
||||
* very precise definitions for integer scalar types that is critically
|
||||
* important for making several classes of applications portable
|
||||
* including cryptography, hashing, variable length integer libraries
|
||||
* and so on. But for most developers its likely useful just for
|
||||
* programming sanity.
|
||||
*
|
||||
* The problem is that most compiler vendors have decided not to
|
||||
* implement the C99 standard, and the next C++ language standard
|
||||
* (which has a lot more mindshare these days) will be a long time in
|
||||
* coming and its unknown whether or not it will include stdint.h or
|
||||
* how much adoption it will have. Either way, it will be a long time
|
||||
* before all compilers come with a stdint.h and it also does nothing
|
||||
* for the extremely large number of compilers available today which
|
||||
* do not include this file, or anything comparable to it.
|
||||
* The problem is that some compiler vendors chose to ignore the C99
|
||||
* standard and some older compilers have no opportunity to be updated.
|
||||
* Because of this situation, simply including stdint.h in your code
|
||||
* makes it unportable.
|
||||
*
|
||||
* So that's what this file is all about. Its an attempt to build a
|
||||
* So that's what this file is all about. It's an attempt to build a
|
||||
* single universal include file that works on as many platforms as
|
||||
* possible to deliver what stdint.h is supposed to. A few things
|
||||
* that should be noted about this file:
|
||||
* possible to deliver what stdint.h is supposed to. Even compilers
|
||||
* that already come with stdint.h can use this file instead without
|
||||
* any loss of functionality. A few things that should be noted about
|
||||
* this file:
|
||||
*
|
||||
* 1) It is not guaranteed to be portable and/or present an identical
|
||||
* interface on all platforms. The extreme variability of the
|
||||
@ -73,7 +71,7 @@
|
||||
* include stdint.h. The hope is that one or the other can be
|
||||
* used with no real difference.
|
||||
*
|
||||
* 5) In the current verison, if your platform can't represent
|
||||
* 5) In the current version, if your platform can't represent
|
||||
* int32_t, int16_t and int8_t, it just dumps out with a compiler
|
||||
* error.
|
||||
*
|
||||
@ -154,7 +152,12 @@
|
||||
* PRINTF_INT64_DEC_WIDTH
|
||||
* PRINTF_INT32_DEC_WIDTH
|
||||
* PRINTF_INT16_DEC_WIDTH
|
||||
* PRINTF_INT8_DEC_WIDTH
|
||||
* PRINTF_UINT8_DEC_WIDTH
|
||||
* PRINTF_UINTMAX_DEC_WIDTH
|
||||
* PRINTF_UINT64_DEC_WIDTH
|
||||
* PRINTF_UINT32_DEC_WIDTH
|
||||
* PRINTF_UINT16_DEC_WIDTH
|
||||
* PRINTF_UINT8_DEC_WIDTH
|
||||
*
|
||||
* Which specifies the maximum number of characters required to
|
||||
* print the number of that type in either hexadecimal or decimal.
|
||||
@ -178,6 +181,10 @@
|
||||
* Chris Howie
|
||||
* John Steele Scott
|
||||
* Dave Thorup
|
||||
* John Dill
|
||||
* Florian Wobbe
|
||||
* Christopher Sean Morrison
|
||||
* Mikkel Fahnoe Jorgensen
|
||||
*
|
||||
*/
|
||||
|
||||
@ -190,14 +197,27 @@
|
||||
* do nothing else. On the Mac OS X version of gcc this is _STDINT_H_.
|
||||
*/
|
||||
|
||||
#if ((defined(__STDC__) && __STDC__ && __STDC_VERSION__ >= 199901L) || (defined (__WATCOMC__) && (defined (_STDINT_H_INCLUDED) || __WATCOMC__ >= 1250)) || (defined(__GNUC__) && (defined(_STDINT_H) || defined(_STDINT_H_)) )) && !defined (_PSTDINT_H_INCLUDED)
|
||||
#if ((defined(__SUNPRO_C) && __SUNPRO_C >= 0x570) || (defined(_MSC_VER) && _MSC_VER >= 1600) || (defined(__STDC__) && __STDC__ && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (defined (__WATCOMC__) && (defined (_STDINT_H_INCLUDED) || __WATCOMC__ >= 1250)) || (defined(__GNUC__) && (__GNUC__ > 3 || defined(_STDINT_H) || defined(_STDINT_H_) || defined (__UINT_FAST64_TYPE__)) )) && !defined (_PSTDINT_H_INCLUDED)
|
||||
#include <stdint.h>
|
||||
#define _PSTDINT_H_INCLUDED
|
||||
# ifndef PRINTF_INT64_MODIFIER
|
||||
# define PRINTF_INT64_MODIFIER "ll"
|
||||
# endif
|
||||
# ifndef PRINTF_INT32_MODIFIER
|
||||
# define PRINTF_INT32_MODIFIER "l"
|
||||
# if defined(__GNUC__) && (defined(__x86_64__) || defined(__ppc64__)) && !(defined(__APPLE__) && defined(__MACH__))
|
||||
# ifndef PRINTF_INT64_MODIFIER
|
||||
# define PRINTF_INT64_MODIFIER "l"
|
||||
# endif
|
||||
# ifndef PRINTF_INT32_MODIFIER
|
||||
# define PRINTF_INT32_MODIFIER ""
|
||||
# endif
|
||||
# else
|
||||
# ifndef PRINTF_INT64_MODIFIER
|
||||
# define PRINTF_INT64_MODIFIER "ll"
|
||||
# endif
|
||||
# ifndef PRINTF_INT32_MODIFIER
|
||||
# if (UINT_MAX == UINT32_MAX)
|
||||
# define PRINTF_INT32_MODIFIER ""
|
||||
# else
|
||||
# define PRINTF_INT32_MODIFIER "l"
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
# ifndef PRINTF_INT16_MODIFIER
|
||||
# define PRINTF_INT16_MODIFIER "h"
|
||||
@ -208,32 +228,62 @@
|
||||
# ifndef PRINTF_INT64_HEX_WIDTH
|
||||
# define PRINTF_INT64_HEX_WIDTH "16"
|
||||
# endif
|
||||
# ifndef PRINTF_UINT64_HEX_WIDTH
|
||||
# define PRINTF_UINT64_HEX_WIDTH "16"
|
||||
# endif
|
||||
# ifndef PRINTF_INT32_HEX_WIDTH
|
||||
# define PRINTF_INT32_HEX_WIDTH "8"
|
||||
# endif
|
||||
# ifndef PRINTF_UINT32_HEX_WIDTH
|
||||
# define PRINTF_UINT32_HEX_WIDTH "8"
|
||||
# endif
|
||||
# ifndef PRINTF_INT16_HEX_WIDTH
|
||||
# define PRINTF_INT16_HEX_WIDTH "4"
|
||||
# endif
|
||||
# ifndef PRINTF_UINT16_HEX_WIDTH
|
||||
# define PRINTF_UINT16_HEX_WIDTH "4"
|
||||
# endif
|
||||
# ifndef PRINTF_INT8_HEX_WIDTH
|
||||
# define PRINTF_INT8_HEX_WIDTH "2"
|
||||
# endif
|
||||
# ifndef PRINTF_UINT8_HEX_WIDTH
|
||||
# define PRINTF_UINT8_HEX_WIDTH "2"
|
||||
# endif
|
||||
# ifndef PRINTF_INT64_DEC_WIDTH
|
||||
# define PRINTF_INT64_DEC_WIDTH "20"
|
||||
# define PRINTF_INT64_DEC_WIDTH "19"
|
||||
# endif
|
||||
# ifndef PRINTF_UINT64_DEC_WIDTH
|
||||
# define PRINTF_UINT64_DEC_WIDTH "20"
|
||||
# endif
|
||||
# ifndef PRINTF_INT32_DEC_WIDTH
|
||||
# define PRINTF_INT32_DEC_WIDTH "10"
|
||||
# endif
|
||||
# ifndef PRINTF_UINT32_DEC_WIDTH
|
||||
# define PRINTF_UINT32_DEC_WIDTH "10"
|
||||
# endif
|
||||
# ifndef PRINTF_INT16_DEC_WIDTH
|
||||
# define PRINTF_INT16_DEC_WIDTH "5"
|
||||
# endif
|
||||
# ifndef PRINTF_UINT16_DEC_WIDTH
|
||||
# define PRINTF_UINT16_DEC_WIDTH "5"
|
||||
# endif
|
||||
# ifndef PRINTF_INT8_DEC_WIDTH
|
||||
# define PRINTF_INT8_DEC_WIDTH "3"
|
||||
# endif
|
||||
# ifndef PRINTF_UINT8_DEC_WIDTH
|
||||
# define PRINTF_UINT8_DEC_WIDTH "3"
|
||||
# endif
|
||||
# ifndef PRINTF_INTMAX_HEX_WIDTH
|
||||
# define PRINTF_INTMAX_HEX_WIDTH PRINTF_INT64_HEX_WIDTH
|
||||
# define PRINTF_INTMAX_HEX_WIDTH PRINTF_UINT64_HEX_WIDTH
|
||||
# endif
|
||||
# ifndef PRINTF_UINTMAX_HEX_WIDTH
|
||||
# define PRINTF_UINTMAX_HEX_WIDTH PRINTF_UINT64_HEX_WIDTH
|
||||
# endif
|
||||
# ifndef PRINTF_INTMAX_DEC_WIDTH
|
||||
# define PRINTF_INTMAX_DEC_WIDTH PRINTF_INT64_DEC_WIDTH
|
||||
# define PRINTF_INTMAX_DEC_WIDTH PRINTF_UINT64_DEC_WIDTH
|
||||
# endif
|
||||
# ifndef PRINTF_UINTMAX_DEC_WIDTH
|
||||
# define PRINTF_UINTMAX_DEC_WIDTH PRINTF_UINT64_DEC_WIDTH
|
||||
# endif
|
||||
|
||||
/*
|
||||
@ -287,11 +337,25 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* I have no idea what is the truly correct thing to do on older Solaris.
|
||||
* From some online discussions, this seems to be what is being
|
||||
* recommended. For people who actually are developing on older Solaris,
|
||||
* what I would like to know is, does this define all of the relevant
|
||||
* macros of a complete stdint.h? Remember, in pstdint.h 64 bit is
|
||||
* considered optional.
|
||||
*/
|
||||
|
||||
#if (defined(__SUNPRO_C) && __SUNPRO_C >= 0x420) && !defined(_PSTDINT_H_INCLUDED)
|
||||
#include <sys/inttypes.h>
|
||||
#define _PSTDINT_H_INCLUDED
|
||||
#endif
|
||||
|
||||
#ifndef _PSTDINT_H_INCLUDED
|
||||
#define _PSTDINT_H_INCLUDED
|
||||
|
||||
#ifndef SIZE_MAX
|
||||
# define SIZE_MAX (~(size_t)0)
|
||||
# define SIZE_MAX ((size_t)-1)
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -303,7 +367,7 @@
|
||||
#ifndef UINT8_MAX
|
||||
# define UINT8_MAX 0xff
|
||||
#endif
|
||||
#ifndef uint8_t
|
||||
#if !defined(uint8_t) && !defined(_UINT8_T) && !defined(vxWorks)
|
||||
# if (UCHAR_MAX == UINT8_MAX) || defined (S_SPLINT_S)
|
||||
typedef unsigned char uint8_t;
|
||||
# define UINT8_C(v) ((uint8_t) v)
|
||||
@ -318,7 +382,7 @@
|
||||
#ifndef INT8_MIN
|
||||
# define INT8_MIN INT8_C(0x80)
|
||||
#endif
|
||||
#ifndef int8_t
|
||||
#if !defined(int8_t) && !defined(_INT8_T) && !defined(vxWorks)
|
||||
# if (SCHAR_MAX == INT8_MAX) || defined (S_SPLINT_S)
|
||||
typedef signed char int8_t;
|
||||
# define INT8_C(v) ((int8_t) v)
|
||||
@ -330,7 +394,7 @@
|
||||
#ifndef UINT16_MAX
|
||||
# define UINT16_MAX 0xffff
|
||||
#endif
|
||||
#ifndef uint16_t
|
||||
#if !defined(uint16_t) && !defined(_UINT16_T) && !defined(vxWorks)
|
||||
#if (UINT_MAX == UINT16_MAX) || defined (S_SPLINT_S)
|
||||
typedef unsigned int uint16_t;
|
||||
# ifndef PRINTF_INT16_MODIFIER
|
||||
@ -354,7 +418,7 @@
|
||||
#ifndef INT16_MIN
|
||||
# define INT16_MIN INT16_C(0x8000)
|
||||
#endif
|
||||
#ifndef int16_t
|
||||
#if !defined(int16_t) && !defined(_INT16_T) && !defined(vxWorks)
|
||||
#if (INT_MAX == INT16_MAX) || defined (S_SPLINT_S)
|
||||
typedef signed int int16_t;
|
||||
# define INT16_C(v) ((int16_t) (v))
|
||||
@ -375,7 +439,7 @@
|
||||
#ifndef UINT32_MAX
|
||||
# define UINT32_MAX (0xffffffffUL)
|
||||
#endif
|
||||
#ifndef uint32_t
|
||||
#if !defined(uint32_t) && !defined(_UINT32_T) && !defined(vxWorks)
|
||||
#if (ULONG_MAX == UINT32_MAX) || defined (S_SPLINT_S)
|
||||
typedef unsigned long uint32_t;
|
||||
# define UINT32_C(v) v ## UL
|
||||
@ -405,7 +469,7 @@
|
||||
#ifndef INT32_MIN
|
||||
# define INT32_MIN INT32_C(0x80000000)
|
||||
#endif
|
||||
#ifndef int32_t
|
||||
#if !defined(int32_t) && !defined(_INT32_T) && !defined(vxWorks)
|
||||
#if (LONG_MAX == INT32_MAX) || defined (S_SPLINT_S)
|
||||
typedef signed long int32_t;
|
||||
# define INT32_C(v) v ## L
|
||||
@ -438,7 +502,7 @@
|
||||
|
||||
#undef stdint_int64_defined
|
||||
#if (defined(__STDC__) && defined(__STDC_VERSION__)) || defined (S_SPLINT_S)
|
||||
# if (__STDC__ && __STDC_VERSION >= 199901L) || defined (S_SPLINT_S)
|
||||
# if (__STDC__ && __STDC_VERSION__ >= 199901L) || defined (S_SPLINT_S)
|
||||
# define stdint_int64_defined
|
||||
typedef long long int64_t;
|
||||
typedef unsigned long long uint64_t;
|
||||
@ -451,7 +515,7 @@
|
||||
#endif
|
||||
|
||||
#if !defined (stdint_int64_defined)
|
||||
# if defined(__GNUC__)
|
||||
# if defined(__GNUC__) && !defined(vxWorks)
|
||||
# define stdint_int64_defined
|
||||
__extension__ typedef long long int64_t;
|
||||
__extension__ typedef unsigned long long uint64_t;
|
||||
@ -514,9 +578,8 @@
|
||||
#ifndef PRINTF_INT8_HEX_WIDTH
|
||||
# define PRINTF_INT8_HEX_WIDTH "2"
|
||||
#endif
|
||||
|
||||
#ifndef PRINTF_INT64_DEC_WIDTH
|
||||
# define PRINTF_INT64_DEC_WIDTH "20"
|
||||
# define PRINTF_INT64_DEC_WIDTH "19"
|
||||
#endif
|
||||
#ifndef PRINTF_INT32_DEC_WIDTH
|
||||
# define PRINTF_INT32_DEC_WIDTH "10"
|
||||
@ -527,6 +590,18 @@
|
||||
#ifndef PRINTF_INT8_DEC_WIDTH
|
||||
# define PRINTF_INT8_DEC_WIDTH "3"
|
||||
#endif
|
||||
#ifndef PRINTF_UINT64_DEC_WIDTH
|
||||
# define PRINTF_UINT64_DEC_WIDTH "20"
|
||||
#endif
|
||||
#ifndef PRINTF_UINT32_DEC_WIDTH
|
||||
# define PRINTF_UINT32_DEC_WIDTH "10"
|
||||
#endif
|
||||
#ifndef PRINTF_UINT16_DEC_WIDTH
|
||||
# define PRINTF_UINT16_DEC_WIDTH "5"
|
||||
#endif
|
||||
#ifndef PRINTF_UINT8_DEC_WIDTH
|
||||
# define PRINTF_UINT8_DEC_WIDTH "3"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Ok, lets not worry about 128 bit integers for now. Moore's law says
|
||||
@ -606,14 +681,12 @@
|
||||
#undef stdint_least_defined
|
||||
|
||||
/*
|
||||
* The ANSI C committee pretending to know or specify anything about
|
||||
* performance is the epitome of misguided arrogance. The mandate of
|
||||
* this file is to *ONLY* ever support that absolute minimum
|
||||
* definition of the fast integer types, for compatibility purposes.
|
||||
* No extensions, and no attempt to suggest what may or may not be a
|
||||
* faster integer type will ever be made in this file. Developers are
|
||||
* warned to stay away from these types when using this or any other
|
||||
* stdint.h.
|
||||
* The ANSI C committee has defined *int*_fast*_t types as well. This,
|
||||
* of course, defies rationality -- you can't know what will be fast
|
||||
* just from the type itself. Even for a given architecture, compatible
|
||||
* implementations might have different performance characteristics.
|
||||
* Developers are warned to stay away from these types when using this
|
||||
* or any other stdint.h.
|
||||
*/
|
||||
|
||||
typedef int_least8_t int_fast8_t;
|
||||
@ -646,7 +719,7 @@ typedef uint_least32_t uint_fast32_t;
|
||||
* type limits.
|
||||
*/
|
||||
|
||||
#if defined(__WATCOMC__) || defined(_MSC_VER) || defined (__GNUC__)
|
||||
#if defined(__WATCOMC__) || defined(_MSC_VER) || defined (__GNUC__) && !defined(vxWorks)
|
||||
# include <wchar.h>
|
||||
# ifndef WCHAR_MIN
|
||||
# define WCHAR_MIN 0
|
||||
@ -661,12 +734,12 @@ typedef uint_least32_t uint_fast32_t;
|
||||
* (u)intptr_t types and limits.
|
||||
*/
|
||||
|
||||
#if defined (_MSC_VER) && defined (_UINTPTR_T_DEFINED)
|
||||
#if (defined (_MSC_VER) && defined (_UINTPTR_T_DEFINED)) || defined (_UINTPTR_T)
|
||||
# define STDINT_H_UINTPTR_T_DEFINED
|
||||
#endif
|
||||
|
||||
#ifndef STDINT_H_UINTPTR_T_DEFINED
|
||||
# if defined (__alpha__) || defined (__ia64__) || defined (__x86_64__) || defined (_WIN64)
|
||||
# if defined (__alpha__) || defined (__ia64__) || defined (__x86_64__) || defined (_WIN64) || defined (__ppc64__)
|
||||
# define stdint_intptr_bits 64
|
||||
# elif defined (__WATCOMC__) || defined (__TURBOC__)
|
||||
# if defined(__TINY__) || defined(__SMALL__) || defined(__MEDIUM__)
|
||||
@ -674,10 +747,12 @@ typedef uint_least32_t uint_fast32_t;
|
||||
# else
|
||||
# define stdint_intptr_bits 32
|
||||
# endif
|
||||
# elif defined (__i386__) || defined (_WIN32) || defined (WIN32)
|
||||
# elif defined (__i386__) || defined (_WIN32) || defined (WIN32) || defined (__ppc64__)
|
||||
# define stdint_intptr_bits 32
|
||||
# elif defined (__INTEL_COMPILER)
|
||||
/* TODO -- what will Intel do about x86-64? */
|
||||
/* TODO -- what did Intel do about x86-64? */
|
||||
# else
|
||||
/* #error "This platform might not be supported yet" */
|
||||
# endif
|
||||
|
||||
# ifdef stdint_intptr_bits
|
||||
@ -726,3 +801,119 @@ typedef uint_least32_t uint_fast32_t;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if defined (__TEST_PSTDINT_FOR_CORRECTNESS)
|
||||
|
||||
/*
|
||||
* Please compile with the maximum warning settings to make sure macros are
|
||||
* not defined more than once.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#define glue3_aux(x,y,z) x ## y ## z
|
||||
#define glue3(x,y,z) glue3_aux(x,y,z)
|
||||
|
||||
#define DECLU(bits) glue3(uint,bits,_t) glue3(u,bits,) = glue3(UINT,bits,_C) (0);
|
||||
#define DECLI(bits) glue3(int,bits,_t) glue3(i,bits,) = glue3(INT,bits,_C) (0);
|
||||
|
||||
#define DECL(us,bits) glue3(DECL,us,) (bits)
|
||||
|
||||
#define TESTUMAX(bits) glue3(u,bits,) = ~glue3(u,bits,); if (glue3(UINT,bits,_MAX) != glue3(u,bits,)) printf ("Something wrong with UINT%d_MAX\n", bits)
|
||||
|
||||
#define REPORTERROR(msg) { err_n++; if (err_first <= 0) err_first = __LINE__; printf msg; }
|
||||
|
||||
#define X_SIZE_MAX ((size_t)-1)
|
||||
|
||||
int main () {
|
||||
int err_n = 0;
|
||||
int err_first = 0;
|
||||
DECL(I,8)
|
||||
DECL(U,8)
|
||||
DECL(I,16)
|
||||
DECL(U,16)
|
||||
DECL(I,32)
|
||||
DECL(U,32)
|
||||
#ifdef INT64_MAX
|
||||
DECL(I,64)
|
||||
DECL(U,64)
|
||||
#endif
|
||||
intmax_t imax = INTMAX_C(0);
|
||||
uintmax_t umax = UINTMAX_C(0);
|
||||
char str0[256], str1[256];
|
||||
|
||||
sprintf (str0, "%" PRINTF_INT32_MODIFIER "d", INT32_C(2147483647));
|
||||
if (0 != strcmp (str0, "2147483647")) REPORTERROR (("Something wrong with PRINTF_INT32_MODIFIER : %s\n", str0));
|
||||
if (atoi(PRINTF_INT32_DEC_WIDTH) != (int) strlen(str0)) REPORTERROR (("Something wrong with PRINTF_INT32_DEC_WIDTH : %s\n", PRINTF_INT32_DEC_WIDTH));
|
||||
sprintf (str0, "%" PRINTF_INT32_MODIFIER "u", UINT32_C(4294967295));
|
||||
if (0 != strcmp (str0, "4294967295")) REPORTERROR (("Something wrong with PRINTF_INT32_MODIFIER : %s\n", str0));
|
||||
if (atoi(PRINTF_UINT32_DEC_WIDTH) != (int) strlen(str0)) REPORTERROR (("Something wrong with PRINTF_UINT32_DEC_WIDTH : %s\n", PRINTF_UINT32_DEC_WIDTH));
|
||||
#ifdef INT64_MAX
|
||||
sprintf (str1, "%" PRINTF_INT64_MODIFIER "d", INT64_C(9223372036854775807));
|
||||
if (0 != strcmp (str1, "9223372036854775807")) REPORTERROR (("Something wrong with PRINTF_INT32_MODIFIER : %s\n", str1));
|
||||
if (atoi(PRINTF_INT64_DEC_WIDTH) != (int) strlen(str1)) REPORTERROR (("Something wrong with PRINTF_INT64_DEC_WIDTH : %s, %d\n", PRINTF_INT64_DEC_WIDTH, (int) strlen(str1)));
|
||||
sprintf (str1, "%" PRINTF_INT64_MODIFIER "u", UINT64_C(18446744073709550591));
|
||||
if (0 != strcmp (str1, "18446744073709550591")) REPORTERROR (("Something wrong with PRINTF_INT32_MODIFIER : %s\n", str1));
|
||||
if (atoi(PRINTF_UINT64_DEC_WIDTH) != (int) strlen(str1)) REPORTERROR (("Something wrong with PRINTF_UINT64_DEC_WIDTH : %s, %d\n", PRINTF_UINT64_DEC_WIDTH, (int) strlen(str1)));
|
||||
#endif
|
||||
|
||||
sprintf (str0, "%d %x\n", 0, ~0);
|
||||
|
||||
sprintf (str1, "%d %x\n", i8, ~0);
|
||||
if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with i8 : %s\n", str1));
|
||||
sprintf (str1, "%u %x\n", u8, ~0);
|
||||
if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with u8 : %s\n", str1));
|
||||
sprintf (str1, "%d %x\n", i16, ~0);
|
||||
if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with i16 : %s\n", str1));
|
||||
sprintf (str1, "%u %x\n", u16, ~0);
|
||||
if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with u16 : %s\n", str1));
|
||||
sprintf (str1, "%" PRINTF_INT32_MODIFIER "d %x\n", i32, ~0);
|
||||
if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with i32 : %s\n", str1));
|
||||
sprintf (str1, "%" PRINTF_INT32_MODIFIER "u %x\n", u32, ~0);
|
||||
if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with u32 : %s\n", str1));
|
||||
#ifdef INT64_MAX
|
||||
sprintf (str1, "%" PRINTF_INT64_MODIFIER "d %x\n", i64, ~0);
|
||||
if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with i64 : %s\n", str1));
|
||||
#endif
|
||||
sprintf (str1, "%" PRINTF_INTMAX_MODIFIER "d %x\n", imax, ~0);
|
||||
if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with imax : %s\n", str1));
|
||||
sprintf (str1, "%" PRINTF_INTMAX_MODIFIER "u %x\n", umax, ~0);
|
||||
if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with umax : %s\n", str1));
|
||||
|
||||
TESTUMAX(8);
|
||||
TESTUMAX(16);
|
||||
TESTUMAX(32);
|
||||
#ifdef INT64_MAX
|
||||
TESTUMAX(64);
|
||||
#endif
|
||||
|
||||
#define STR(v) #v
|
||||
#define Q(v) printf ("sizeof " STR(v) " = %u\n", (unsigned) sizeof (v));
|
||||
if (err_n) {
|
||||
printf ("pstdint.h is not correct. Please use sizes below to correct it:\n");
|
||||
}
|
||||
|
||||
Q(int)
|
||||
Q(unsigned)
|
||||
Q(long int)
|
||||
Q(short int)
|
||||
Q(int8_t)
|
||||
Q(int16_t)
|
||||
Q(int32_t)
|
||||
#ifdef INT64_MAX
|
||||
Q(int64_t)
|
||||
#endif
|
||||
|
||||
#if UINT_MAX < X_SIZE_MAX
|
||||
printf ("UINT_MAX < X_SIZE_MAX\n");
|
||||
#else
|
||||
printf ("UINT_MAX >= X_SIZE_MAX\n");
|
||||
#endif
|
||||
printf ("%" PRINTF_INT64_MODIFIER "u vs %" PRINTF_INT64_MODIFIER "u\n", UINT_MAX, X_SIZE_MAX);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
Binary file not shown.
@ -31,18 +31,27 @@ FONT 8, "MS Shell Dlg", 400, 0, 0x0
|
||||
BEGIN
|
||||
LTEXT "Loop Count",IDC_STATIC,7,10,44,12
|
||||
EDITTEXT IDC_LOOP_COUNT,52,7,39,14,ES_AUTOHSCROLL
|
||||
|
||||
LTEXT "Fade Length",IDC_STATIC,7,25,41,8
|
||||
EDITTEXT IDC_FADE_SECONDS,52,23,39,14,ES_AUTOHSCROLL
|
||||
LTEXT "seconds",IDC_STATIC,93,25,29,11
|
||||
|
||||
LTEXT "Fade Delay",IDC_STATIC,7,40,41,8
|
||||
EDITTEXT IDC_FADE_DELAY_SECONDS,52,38,39,14,ES_AUTOHSCROLL
|
||||
LTEXT "seconds",IDC_STATIC,93,40,29,11
|
||||
|
||||
CONTROL "Loop normally",IDC_LOOP_NORMALLY,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,7,57,77,10
|
||||
CONTROL "Loop forever",IDC_LOOP_FOREVER,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,7,70,77,10
|
||||
CONTROL "Ignore looping",IDC_IGNORE_LOOP,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,7,83,77,10
|
||||
|
||||
CONTROL "Disable subsongs",IDC_DISABLE_SUBSONGS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,99,87,10
|
||||
|
||||
LTEXT "Downmix",IDC_STATIC,7,115,48,12
|
||||
EDITTEXT IDC_DOWNMIX_CHANNELS,52,112,37,14,ES_AUTOHSCROLL
|
||||
|
||||
CONTROL "Disable tagfile",IDC_TAGFILE_DISABLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,131,87,10
|
||||
|
||||
CONTROL "Override title",IDC_OVERRIDE_TITLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,147,97,10
|
||||
END
|
||||
|
||||
|
||||
|
@ -21,6 +21,8 @@ static const GUID guid_cfg_FadeLength = { 0x61da7ef1, 0x56a5, 0x4368, { 0xae, 0x
|
||||
static const GUID guid_cfg_FadeDelay = { 0x73907787, 0xaf49, 0x4659, { 0x96, 0x8e, 0x9f, 0x70, 0xa1, 0x62, 0x49, 0xc4 } };
|
||||
static const GUID guid_cfg_DisableSubsongs = { 0xa8cdd664, 0xb32b, 0x4a36, { 0x83, 0x07, 0xa0, 0x4c, 0xcd, 0x52, 0xa3, 0x7c } };
|
||||
static const GUID guid_cfg_DownmixChannels = { 0x5a0e65dd, 0xeb37, 0x4c67, { 0x9a, 0xb1, 0x3f, 0xb0, 0xc9, 0x7e, 0xb0, 0xe0 } };
|
||||
static const GUID guid_cfg_TagfileDisable = { 0xc1971eb7, 0xa930, 0x4bae, { 0x9e, 0x7f, 0xa9, 0x50, 0x36, 0x32, 0x41, 0xb3 } };
|
||||
static const GUID guid_cfg_OverrideTitle = { 0xe794831f, 0xd067, 0x4337, { 0x97, 0x85, 0x10, 0x57, 0x39, 0x4b, 0x1b, 0x97 } };
|
||||
|
||||
static cfg_bool cfg_LoopForever(guid_cfg_LoopForever, DEFAULT_LOOP_FOREVER);
|
||||
static cfg_bool cfg_IgnoreLoop(guid_cfg_IgnoreLoop, DEFAULT_IGNORE_LOOP);
|
||||
@ -29,6 +31,8 @@ static cfg_string cfg_FadeLength(guid_cfg_FadeLength, DEFAULT_FADE_SECONDS);
|
||||
static cfg_string cfg_FadeDelay(guid_cfg_FadeDelay, DEFAULT_FADE_DELAY_SECONDS);
|
||||
static cfg_bool cfg_DisableSubsongs(guid_cfg_DisableSubsongs, DEFAULT_DISABLE_SUBSONGS);
|
||||
static cfg_string cfg_DownmixChannels(guid_cfg_DownmixChannels, DEFAULT_DOWNMIX_CHANNELS);
|
||||
static cfg_bool cfg_TagfileDisable(guid_cfg_TagfileDisable, DEFAULT_TAGFILE_DISABLE);
|
||||
static cfg_bool cfg_OverrideTitle(guid_cfg_OverrideTitle, DEFAULT_OVERRIDE_TITLE);
|
||||
|
||||
// Needs to be here in rder to access the static config
|
||||
void input_vgmstream::load_settings()
|
||||
@ -41,6 +45,8 @@ void input_vgmstream::load_settings()
|
||||
ignore_loop = cfg_IgnoreLoop;
|
||||
disable_subsongs = cfg_DisableSubsongs;
|
||||
sscanf(cfg_DownmixChannels.get_ptr(),"%d",&downmix_channels);
|
||||
tagfile_disable = cfg_TagfileDisable;
|
||||
override_title = cfg_OverrideTitle;
|
||||
}
|
||||
|
||||
const char * vgmstream_prefs::get_name()
|
||||
@ -75,6 +81,9 @@ BOOL vgmstreamPreferences::OnInitDialog(CWindow, LPARAM)
|
||||
|
||||
uSetDlgItemText(m_hWnd, IDC_DOWNMIX_CHANNELS, cfg_DownmixChannels);
|
||||
|
||||
CheckDlgButton(IDC_TAGFILE_DISABLE, cfg_TagfileDisable?BST_CHECKED:BST_UNCHECKED);
|
||||
CheckDlgButton(IDC_OVERRIDE_TITLE, cfg_OverrideTitle?BST_CHECKED:BST_UNCHECKED);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -100,6 +109,9 @@ void vgmstreamPreferences::reset()
|
||||
CheckDlgButton(IDC_DISABLE_SUBSONGS, DEFAULT_DISABLE_SUBSONGS?BST_CHECKED:BST_UNCHECKED);
|
||||
|
||||
uSetDlgItemText(m_hWnd, IDC_DOWNMIX_CHANNELS, DEFAULT_DOWNMIX_CHANNELS);
|
||||
|
||||
CheckDlgButton(IDC_TAGFILE_DISABLE, DEFAULT_TAGFILE_DISABLE?BST_CHECKED:BST_UNCHECKED);
|
||||
CheckDlgButton(IDC_OVERRIDE_TITLE, DEFAULT_OVERRIDE_TITLE?BST_CHECKED:BST_UNCHECKED);
|
||||
}
|
||||
|
||||
|
||||
@ -109,6 +121,8 @@ void vgmstreamPreferences::apply()
|
||||
cfg_LoopForever = IsDlgButtonChecked(IDC_LOOP_FOREVER)?true:false;
|
||||
cfg_IgnoreLoop = IsDlgButtonChecked(IDC_IGNORE_LOOP)?true:false;
|
||||
cfg_DisableSubsongs = IsDlgButtonChecked(IDC_DISABLE_SUBSONGS)?true:false;
|
||||
cfg_TagfileDisable = IsDlgButtonChecked(IDC_TAGFILE_DISABLE)?true:false;
|
||||
cfg_OverrideTitle = IsDlgButtonChecked(IDC_OVERRIDE_TITLE)?true:false;
|
||||
|
||||
double temp_fade_seconds;
|
||||
double temp_fade_delay_seconds;
|
||||
@ -178,6 +192,12 @@ bool vgmstreamPreferences::HasChanged()
|
||||
bool current_cfg_DisableSubsongs = IsDlgButtonChecked(IDC_DISABLE_SUBSONGS)?true:false;
|
||||
if(cfg_DisableSubsongs != current_cfg_DisableSubsongs) return true;
|
||||
|
||||
bool current_cfg_TagfileDisable = IsDlgButtonChecked(IDC_TAGFILE_DISABLE)?true:false;
|
||||
if(cfg_TagfileDisable != current_cfg_TagfileDisable) return true;
|
||||
|
||||
bool current_cfg_OverrideTitle = IsDlgButtonChecked(IDC_OVERRIDE_TITLE)?true:false;
|
||||
if(cfg_OverrideTitle != current_cfg_OverrideTitle) return true;
|
||||
|
||||
pfc::string FadeLength(cfg_FadeLength);
|
||||
pfc::string FadeDelay(cfg_FadeDelay);
|
||||
pfc::string LoopCount(cfg_LoopCount);
|
||||
|
@ -16,6 +16,8 @@
|
||||
#define DEFAULT_IGNORE_LOOP false
|
||||
#define DEFAULT_DISABLE_SUBSONGS false
|
||||
#define DEFAULT_DOWNMIX_CHANNELS "8"
|
||||
#define DEFAULT_TAGFILE_DISABLE false
|
||||
#define DEFAULT_OVERRIDE_TITLE false
|
||||
|
||||
class vgmstreamPreferences : public CDialogImpl<vgmstreamPreferences>, public preferences_page_instance {
|
||||
public:
|
||||
@ -44,6 +46,8 @@ public:
|
||||
COMMAND_HANDLER_EX(IDC_LOOP_COUNT, EN_CHANGE, OnEditChange)
|
||||
COMMAND_HANDLER_EX(IDC_DISABLE_SUBSONGS, BN_CLICKED, OnEditChange)
|
||||
COMMAND_HANDLER_EX(IDC_DOWNMIX_CHANNELS, EN_CHANGE, OnEditChange)
|
||||
COMMAND_HANDLER_EX(IDC_TAGFILE_DISABLE, BN_CLICKED, OnEditChange)
|
||||
COMMAND_HANDLER_EX(IDC_OVERRIDE_TITLE, BN_CLICKED, OnEditChange)
|
||||
END_MSG_MAP()
|
||||
private:
|
||||
BOOL OnInitDialog(CWindow, LPARAM);
|
||||
|
@ -14,6 +14,7 @@
|
||||
|
||||
extern "C" {
|
||||
#include "../src/vgmstream.h"
|
||||
#include "../src/plugins.h"
|
||||
}
|
||||
#include "foo_vgmstream.h"
|
||||
#include "foo_filetypes.h"
|
||||
@ -58,6 +59,9 @@ input_vgmstream::input_vgmstream() {
|
||||
ignore_loop = 0;
|
||||
disable_subsongs = false;
|
||||
downmix_channels = 0;
|
||||
tagfile_disable = false;
|
||||
tagfile_name = "!tags.m3u"; //todo make configurable
|
||||
override_title = false;
|
||||
|
||||
load_settings();
|
||||
}
|
||||
@ -77,15 +81,6 @@ void input_vgmstream::open(service_ptr_t<file> p_filehint,const char * p_path,t_
|
||||
|
||||
filename = p_path;
|
||||
|
||||
/* KLUDGE */
|
||||
if ( !pfc::stricmp_ascii( pfc::string_extension(filename), "MUS" ) )
|
||||
{
|
||||
unsigned char buffer[ 4 ];
|
||||
if ( p_filehint.is_empty() ) input_open_file_helper( p_filehint, filename, p_reason, p_abort );
|
||||
p_filehint->read_object_t( buffer, p_abort );
|
||||
if ( !memcmp( buffer, "MUS\x1A", 4 ) ) throw exception_io_unsupported_format();
|
||||
}
|
||||
|
||||
|
||||
// keep file stats around (timestamp, filesize)
|
||||
if ( p_filehint.is_empty() )
|
||||
@ -142,18 +137,59 @@ void input_vgmstream::get_info(t_uint32 p_subsong, file_info & p_info, abort_cal
|
||||
|
||||
get_subsong_info(p_subsong, temp, &length_in_ms, &total_samples, &loop_start, &loop_end, &samplerate, &channels, &bitrate, description, p_abort);
|
||||
|
||||
if (get_subsong_count() > 1) {
|
||||
|
||||
/* set tag info (metadata tab in file properties) */
|
||||
|
||||
/* Shows a custom subsong title by default with subsong name, to simplify for average users.
|
||||
* This can be overriden and extended and using the exported STREAM_x below and foobar's formatting.
|
||||
* foobar defaults to filename minus extension if there is no meta "title" value. */
|
||||
if (!override_title && get_subsong_count() > 1) {
|
||||
p_info.meta_set("TITLE",temp);
|
||||
}
|
||||
if (get_description_tag(temp,description,"stream count: ")) p_info.meta_set("stream_count",temp);
|
||||
if (get_description_tag(temp,description,"stream index: ")) p_info.meta_set("stream_index",temp);
|
||||
if (get_description_tag(temp,description,"stream name: ")) p_info.meta_set("stream_name",temp);
|
||||
|
||||
p_info.info_set("vgmstream version",PLUGIN_VERSION);
|
||||
/* get external file tags */
|
||||
//todo optimize and don't parse tags again for this session (not sure how), seems foobar
|
||||
// calls get_info on every play even if the file hasn't changes, and won't refresh "meta"
|
||||
// unless forced or closing playlist+exe
|
||||
if (!tagfile_disable) {
|
||||
//todo use foobar's fancy-but-arcane string functions
|
||||
char tagfile_path[PATH_LIMIT];
|
||||
strcpy(tagfile_path, filename);
|
||||
|
||||
char *path = strrchr(tagfile_path,'\\');
|
||||
if (path!=NULL) {
|
||||
path[1] = '\0'; /* includes "\", remove after that from tagfile_path */
|
||||
strcat(tagfile_path,tagfile_name);
|
||||
}
|
||||
else { /* ??? */
|
||||
strcpy(tagfile_path,tagfile_name);
|
||||
}
|
||||
|
||||
STREAMFILE *tagFile = open_foo_streamfile(tagfile_path, &p_abort, &stats);
|
||||
if (tagFile != NULL) {
|
||||
VGMSTREAM_TAGS tag;
|
||||
vgmstream_tags_reset(&tag, filename);
|
||||
while (vgmstream_tags_next_tag(&tag, tagFile)) {
|
||||
p_info.meta_set(tag.key,tag.val);
|
||||
}
|
||||
|
||||
close_streamfile(tagFile);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* set technical info (details tab in file properties) */
|
||||
|
||||
p_info.info_set("vgmstream_version",PLUGIN_VERSION);
|
||||
p_info.info_set_int("samplerate", samplerate);
|
||||
p_info.info_set_int("channels", channels);
|
||||
p_info.info_set_int("bitspersample",16);
|
||||
/* not quite accurate but some people are confused by this
|
||||
/* not quite accurate but some people are confused by "lossless"
|
||||
* (could set lossless if PCM, but then again PCMFloat or PCM8 are converted/"lossy" in vgmstream) */
|
||||
p_info.info_set("encoding","lossy");
|
||||
p_info.info_set("encoding","lossy/lossless");
|
||||
p_info.info_set_bitrate(bitrate / 1000);
|
||||
if (total_samples > 0)
|
||||
p_info.info_set_int("stream_total_samples", total_samples);
|
||||
@ -344,8 +380,8 @@ bool input_vgmstream::g_is_our_path(const char * p_path,const char * p_extension
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* some extensionless files can be handled by vgmstream, try to play */
|
||||
if (strlen(p_extension) <= 0) {
|
||||
// Last Of Us speech files have no file extension
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -65,7 +65,7 @@ class input_vgmstream : public input_stubs {
|
||||
int seek_pos_samples;
|
||||
short sample_buffer[SAMPLE_BUFFER_SIZE];
|
||||
|
||||
/* config */
|
||||
/* settings */
|
||||
double fade_seconds;
|
||||
double fade_delay_seconds;
|
||||
double loop_count;
|
||||
@ -74,7 +74,11 @@ class input_vgmstream : public input_stubs {
|
||||
int ignore_loop;
|
||||
bool disable_subsongs;
|
||||
int downmix_channels;
|
||||
bool tagfile_disable;
|
||||
pfc::string8 tagfile_name;
|
||||
bool override_title;
|
||||
|
||||
/* song config */
|
||||
foobar_song_config config;
|
||||
|
||||
/* helpers */
|
||||
|
@ -15,6 +15,8 @@
|
||||
#define IDC_DEFAULT_BUTTON 1008
|
||||
#define IDC_DISABLE_SUBSONGS 1009
|
||||
#define IDC_DOWNMIX_CHANNELS 1010
|
||||
#define IDC_TAGFILE_DISABLE 1011
|
||||
#define IDC_OVERRIDE_TITLE 1012
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
|
@ -147,10 +147,14 @@
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\streamfile.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\plugins.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\streamfile.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\streamtypes.h"
|
||||
>
|
||||
@ -172,6 +176,10 @@
|
||||
<File
|
||||
RelativePath=".\formats.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\plugins.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\streamfile.c"
|
||||
|
@ -89,6 +89,7 @@
|
||||
<ClInclude Include="coding\vorbis_custom_data_fsb.h" />
|
||||
<ClInclude Include="coding\vorbis_custom_data_wwise.h" />
|
||||
<ClInclude Include="coding\vorbis_custom_decoder.h" />
|
||||
<ClInclude Include="plugins.h" />
|
||||
<ClInclude Include="streamfile.h" />
|
||||
<ClInclude Include="streamtypes.h" />
|
||||
<ClInclude Include="util.h" />
|
||||
@ -189,6 +190,7 @@
|
||||
<ClCompile Include="meta\x360_cxs.c" />
|
||||
<ClCompile Include="meta\x360_tra.c" />
|
||||
<ClCompile Include="formats.c" />
|
||||
<ClCompile Include="plugins.c" />
|
||||
<ClCompile Include="meta\ps2_va3.c" />
|
||||
<ClCompile Include="streamfile.c" />
|
||||
<ClCompile Include="util.c" />
|
||||
|
@ -47,6 +47,9 @@
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="plugins.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="streamfile.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
@ -160,6 +163,9 @@
|
||||
<ClCompile Include="formats.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="plugins.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="streamfile.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
|
@ -185,6 +185,9 @@ static const adxkey_info adxkey8_list[] = {
|
||||
/* Tensei Hakkenshi - Fuumaroku (PS2) */
|
||||
{0x5761,0x6283,0x4531, "HAKKEN",0},
|
||||
|
||||
/* Lucky Star - Ryouou Gakuen Outousai (PS2) */
|
||||
{0x481D,0x44F9,0x4E35, "LSTARPS2",0},
|
||||
|
||||
};
|
||||
|
||||
static const adxkey_info adxkey9_list[] = {
|
||||
|
@ -32,7 +32,7 @@ VGMSTREAM * init_vgmstream_svs(STREAMFILE *streamFile) {
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
vgmstream->meta_type = meta_SVS;
|
||||
vgmstream->sample_rate = (48000 * pitch) / 4096; /* music = ~44100, ambience = 48000 */
|
||||
vgmstream->sample_rate = round10((48000 * pitch) / 4096); /* music = ~44100, ambience = 48000 (rounding makes more sense but not sure) */
|
||||
vgmstream->num_samples = ps_bytes_to_samples(get_streamfile_size(streamFile) - start_offset, channel_count);
|
||||
if (loop_flag) {
|
||||
vgmstream->loop_start_sample = read_32bitLE(0x08,streamFile) * 28; /* frame count (0x10*ch) */
|
||||
|
@ -35,7 +35,7 @@ VGMSTREAM * init_vgmstream_vs_ffx(STREAMFILE *streamFile) {
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
vgmstream->meta_type = meta_VS_FFX;
|
||||
vgmstream->sample_rate = (48000 * pitch) / 4096; /* verified, needed for rare files */
|
||||
vgmstream->sample_rate = round10((48000 * pitch) / 4096); /* needed for rare files */
|
||||
vgmstream->coding_type = coding_PSX;
|
||||
vgmstream->layout_type = layout_blocked_vs_ffx;
|
||||
|
||||
|
129
src/plugins.c
Normal file
129
src/plugins.c
Normal file
@ -0,0 +1,129 @@
|
||||
#include "vgmstream.h"
|
||||
#include "plugins.h"
|
||||
|
||||
|
||||
static void tags_clean(VGMSTREAM_TAGS* tag) {
|
||||
int i;
|
||||
int val_len = strlen(tag->val);
|
||||
|
||||
/* remove trailing spaces */
|
||||
for (i = val_len - 1; i > 0; i--) {
|
||||
if (tag->val[i] != ' ')
|
||||
break;
|
||||
tag->val[i] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
/* Tags are divided in two: "global" @TAGS and "file" %TAGS for target filename. To extract both
|
||||
* we find the filename's tag "section": (other_filename) ..(#tag section).. (target_filename).
|
||||
* When a new "other_filename" is found that offset is marked as section_start, and when target_filename
|
||||
* is found it's marked as section_end. Then we can begin extracting tags within that section, until
|
||||
* all tags are exhausted. Global tags are extracted while searching, so they always go first, and
|
||||
* also meaning any tags after the section is found are ignored. */
|
||||
int vgmstream_tags_next_tag(VGMSTREAM_TAGS* tag, STREAMFILE* tagfile) {
|
||||
off_t file_size = get_streamfile_size(tagfile);
|
||||
char currentname[TAG_LINE_MAX] = {0};
|
||||
char line[TAG_LINE_MAX] = {0};
|
||||
int ok, bytes_read, line_done;
|
||||
|
||||
|
||||
/* prepare file start and skip BOM if needed */
|
||||
if (tag->offset == 0) {
|
||||
if ((uint16_t)read_16bitLE(0x00, tagfile) == 0xFFFE ||
|
||||
(uint16_t)read_16bitLE(0x00, tagfile) == 0xFEFF) {
|
||||
tag->offset = 0x02;
|
||||
if (tag->section_start == 0)
|
||||
tag->section_start = 0x02;
|
||||
}
|
||||
else if (((uint32_t)read_32bitBE(0x00, tagfile) & 0xFFFFFF00) == 0xEFBBBF00) {
|
||||
tag->offset = 0x03;
|
||||
if (tag->section_start == 0)
|
||||
tag->section_start = 0x03;
|
||||
}
|
||||
}
|
||||
|
||||
/* read lines */
|
||||
while (tag->offset < file_size) {
|
||||
/* no more tags to extract */
|
||||
if (tag->section_found && tag->offset >= tag->section_end) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
bytes_read = get_streamfile_text_line(TAG_LINE_MAX,line, tag->offset,tagfile, &line_done);
|
||||
if (!line_done) goto fail;
|
||||
|
||||
tag->offset += bytes_read;
|
||||
|
||||
|
||||
if (tag->section_found) {
|
||||
/* find possible file tag */
|
||||
ok = sscanf(line, "# %%%[^ \t] %[^\r\n] ", tag->key,tag->val);
|
||||
if (ok == 2) {
|
||||
tags_clean(tag);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* find possible global tag */
|
||||
if (line[0] == '#') {
|
||||
ok = sscanf(line, "# @%[^ \t] %[^\r\n]", tag->key,tag->val);
|
||||
if (ok == 2) {
|
||||
tags_clean(tag);
|
||||
return 1;
|
||||
}
|
||||
|
||||
continue; /* next line */
|
||||
}
|
||||
|
||||
/* find possible filename and section start/end */
|
||||
ok = sscanf(line, " %[^\r\n] ", currentname);
|
||||
if (ok == 1) {
|
||||
if (strcasecmp(tag->targetname,currentname) == 0) { /* looks ok even for UTF-8 */
|
||||
/* section ok, start would be set before this (or be 0) */
|
||||
tag->section_end = tag->offset;
|
||||
tag->section_found = 1;
|
||||
tag->offset = tag->section_start;
|
||||
}
|
||||
else {
|
||||
/* mark new possible section */
|
||||
tag->section_start = tag->offset;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
/* empty/bad line, probably */
|
||||
}
|
||||
}
|
||||
|
||||
/* may reach here if read up to file_size but no section was found */
|
||||
|
||||
fail:
|
||||
tag->key[0] = '\0';
|
||||
tag->val[0] = '\0';
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void vgmstream_tags_reset(VGMSTREAM_TAGS* tag, const char* target_filename) {
|
||||
const char *path;
|
||||
|
||||
memset(tag, 0, sizeof(VGMSTREAM_TAGS));
|
||||
|
||||
|
||||
/* get base name */
|
||||
|
||||
//todo Windows CMD accepts both \\ and /, better way to handle this?
|
||||
path = strrchr(target_filename,'\\');
|
||||
if (!path)
|
||||
path = strrchr(target_filename,'/');
|
||||
if (path != NULL)
|
||||
path = path+1;
|
||||
|
||||
//todo validate sizes and copy sensible max
|
||||
if (path) {
|
||||
strcpy(tag->targetname, path);
|
||||
} else {
|
||||
strcpy(tag->targetname, target_filename);
|
||||
}
|
||||
}
|
36
src/plugins.h
Normal file
36
src/plugins.h
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* plugins.h - helper for plugins
|
||||
*/
|
||||
#ifndef _PLUGINS_H_
|
||||
#define _PLUGINS_H_
|
||||
|
||||
#include "streamfile.h"
|
||||
#define TAG_LINE_MAX 2048
|
||||
|
||||
//todo improve API and make opaque
|
||||
//typedef struct VGMSTREAM_TAGS VGMSTREAM_TAGS;
|
||||
typedef struct {
|
||||
/* extracted output */
|
||||
char key[TAG_LINE_MAX];
|
||||
char val[TAG_LINE_MAX];
|
||||
|
||||
/* file to find tags for */
|
||||
char targetname[TAG_LINE_MAX];
|
||||
|
||||
/* tag section for filename (see comments below) */
|
||||
int section_found;
|
||||
off_t section_start;
|
||||
off_t section_end;
|
||||
off_t offset;
|
||||
} VGMSTREAM_TAGS;
|
||||
|
||||
|
||||
|
||||
/* Extracts next valid tag in tagfile to *tag. Returns 0 if no more tags are found (meant to be
|
||||
* called repeatedly until 0). Key are lowercase and values can be treated as UTF-8. */
|
||||
int vgmstream_tags_next_tag(VGMSTREAM_TAGS* tag, STREAMFILE* tagfile);
|
||||
|
||||
/* resets tagfile to restart reading from the beginning for a new filename */
|
||||
void vgmstream_tags_reset(VGMSTREAM_TAGS* tag, const char* target_filename);
|
||||
|
||||
#endif /* _PLUGINS_H_ */
|
@ -14,7 +14,10 @@
|
||||
#include <pstdint.h>
|
||||
#endif /* (_MSC_VER >= 1600) */
|
||||
|
||||
#ifndef inline /* (_MSC_VER < 1900)? */
|
||||
#define inline _inline
|
||||
#endif
|
||||
|
||||
#define strcasecmp _stricmp
|
||||
#define strncasecmp _strnicmp
|
||||
|
||||
|
@ -67,6 +67,14 @@ static inline int clamp16(int32_t val) {
|
||||
return val;
|
||||
}
|
||||
|
||||
static inline int round10(int val) {
|
||||
int round_val = val % 10;
|
||||
if (round_val < 5) /* half-down rounding */
|
||||
return val - round_val;
|
||||
else
|
||||
return val + (10 - round_val);
|
||||
}
|
||||
|
||||
/* return a file's extension (a pointer to the first character of the
|
||||
* extension in the original filename or the ending null byte if no extension */
|
||||
const char * filename_extension(const char * filename);
|
||||
|
@ -2322,12 +2322,13 @@ void describe_vgmstream(VGMSTREAM * vgmstream, char * desc, int length) {
|
||||
concatn(length,desc,temp);
|
||||
}
|
||||
|
||||
if (vgmstream->num_streams > 1 && vgmstream->stream_index > 0) {
|
||||
if (vgmstream->num_streams > 1) {
|
||||
snprintf(temp,TEMPSIZE,
|
||||
"\nstream index: %d",
|
||||
vgmstream->stream_index);
|
||||
vgmstream->stream_index == 0 ? 1 : vgmstream->stream_index);
|
||||
concatn(length,desc,temp);
|
||||
}
|
||||
|
||||
if (vgmstream->stream_name[0] != '\0') {
|
||||
snprintf(temp,TEMPSIZE,
|
||||
"\nstream name: %s",
|
||||
|
@ -12,6 +12,7 @@
|
||||
#ifdef _MSC_VER
|
||||
#define _CRT_SECURE_NO_DEPRECATE
|
||||
#endif
|
||||
|
||||
#include <windows.h>
|
||||
#include <windowsx.h>
|
||||
#include <commctrl.h>
|
||||
@ -21,9 +22,10 @@
|
||||
#include <ctype.h>
|
||||
|
||||
#include "../src/vgmstream.h"
|
||||
#include "in2.h"
|
||||
#include "wa_ipc.h"
|
||||
#include "ipc_pe.h"
|
||||
#include "../src/plugins.h"
|
||||
#include "sdk/in2.h"
|
||||
#include "sdk/wa_ipc.h"
|
||||
#include "sdk/ipc_pe.h"
|
||||
#include "resource.h"
|
||||
|
||||
|
||||
@ -39,13 +41,14 @@
|
||||
|
||||
/* ************************************* */
|
||||
|
||||
/* plugin main (declared at the bottom of this file) */
|
||||
/* plugin module (declared at the bottom of this file) */
|
||||
In_Module input_module;
|
||||
DWORD WINAPI __stdcall decode(void *arg);
|
||||
|
||||
/* Winamp Play extension list, to accept and associate extensions in Windows */
|
||||
#define EXTENSION_LIST_SIZE (0x2000 * 6)
|
||||
#define EXT_BUFFER_SIZE 200
|
||||
/* fixed list to simplify but could also malloc/free on init/close */
|
||||
char working_extension_list[EXTENSION_LIST_SIZE] = {0};
|
||||
|
||||
/* defaults */
|
||||
@ -58,6 +61,7 @@ typedef struct {
|
||||
int thread_priority;
|
||||
int disable_subsongs;
|
||||
int downmix_channels;
|
||||
int tagfile_disable;
|
||||
} winamp_settings;
|
||||
|
||||
/* current song settings */
|
||||
@ -89,13 +93,18 @@ int stream_length_samples = 0;
|
||||
int fade_samples = 0;
|
||||
int output_channels = 0;
|
||||
|
||||
const char* tagfile_name = "!tags.m3u"; //todo make configurable
|
||||
|
||||
in_char lastfn[PATH_LIMIT] = {0}; /* name of the currently playing file */
|
||||
|
||||
|
||||
/* ************************************* */
|
||||
/* IN_UNICODE */
|
||||
/* ************************************* */
|
||||
//todo safe ops
|
||||
//todo there must be a better way to handle unicode...
|
||||
#ifdef UNICODE_INPUT_PLUGIN
|
||||
#define wa_strcmp wcscmp
|
||||
#define wa_strcpy wcscpy
|
||||
#define wa_strncpy wcsncpy
|
||||
#define wa_strcat wcscat
|
||||
@ -108,6 +117,7 @@ in_char lastfn[PATH_LIMIT] = {0}; /* name of the currently playing file */
|
||||
#define wa_IPC_PE_INSERTFILENAME IPC_PE_INSERTFILENAMEW
|
||||
#define wa_L(x) L ##x
|
||||
#else
|
||||
#define wa_strcmp strcmp
|
||||
#define wa_strcpy strcpy
|
||||
#define wa_strncpy strncpy
|
||||
#define wa_strcat strcat
|
||||
@ -121,8 +131,8 @@ in_char lastfn[PATH_LIMIT] = {0}; /* name of the currently playing file */
|
||||
#define wa_L(x) x
|
||||
#endif
|
||||
|
||||
/* converts from utf16 to utf8 (if unicode is active) */
|
||||
static void wa_wchar_to_char(char *dst, size_t dstsize, const in_char *wsrc) {
|
||||
/* converts from utf16 to utf8 (if unicode is on) */
|
||||
static void wa_ichar_to_char(char *dst, size_t dstsize, const in_char *wsrc) {
|
||||
#ifdef UNICODE_INPUT_PLUGIN
|
||||
/* converto to UTF8 codepage, default separate bytes, source wstr, wstr lenght, */
|
||||
//int size_needed = WideCharToMultiByte(CP_UTF8,0, src,-1, NULL,0, NULL, NULL);
|
||||
@ -132,8 +142,8 @@ static void wa_wchar_to_char(char *dst, size_t dstsize, const in_char *wsrc) {
|
||||
#endif
|
||||
}
|
||||
|
||||
/* converts from utf8 to utf16 (if unicode is active) */
|
||||
static void wa_char_to_wchar(in_char *wdst, size_t wdstsize, const char *src) {
|
||||
/* converts from utf8 to utf16 (if unicode is on) */
|
||||
static void wa_char_to_ichar(in_char *wdst, size_t wdstsize, const char *src) {
|
||||
#ifdef UNICODE_INPUT_PLUGIN
|
||||
//int size_needed = MultiByteToWideChar(CP_UTF8,0, src,-1, NULL,0);
|
||||
MultiByteToWideChar(CP_UTF8,0, src,-1, wdst,wdstsize);
|
||||
@ -142,6 +152,24 @@ static void wa_char_to_wchar(in_char *wdst, size_t wdstsize, const char *src) {
|
||||
#endif
|
||||
}
|
||||
|
||||
/* copies from utf16 to utf16 (if unicode is active) */
|
||||
static void wa_wchar_to_ichar(in_char *wdst, size_t wdstsize, const wchar_t *src) {
|
||||
#ifdef UNICODE_INPUT_PLUGIN
|
||||
wcscpy(wdst,src);
|
||||
#else
|
||||
strcpy(wdst,src); //todo ???
|
||||
#endif
|
||||
}
|
||||
|
||||
/* copies from utf16 to utf16 */
|
||||
static void wa_char_to_wchar(wchar_t *wdst, size_t wdstsize, const char *src) {
|
||||
#ifdef UNICODE_INPUT_PLUGIN
|
||||
MultiByteToWideChar(CP_UTF8,0, src,-1, wdst,wdstsize);
|
||||
#else
|
||||
strcpy(wdst,src); //todo ???
|
||||
#endif
|
||||
}
|
||||
|
||||
/* opens a utf16 (unicode) path */
|
||||
static FILE* wa_fopen(const in_char *wpath) {
|
||||
#ifdef UNICODE_INPUT_PLUGIN
|
||||
@ -172,7 +200,7 @@ typedef struct {
|
||||
} WINAMP_STREAMFILE;
|
||||
|
||||
static STREAMFILE *open_winamp_streamfile_by_file(FILE *infile, const char * path);
|
||||
static STREAMFILE *open_winamp_streamfile_by_wpath(const in_char *wpath);
|
||||
static STREAMFILE *open_winamp_streamfile_by_ipath(const in_char *wpath);
|
||||
|
||||
static size_t wasf_read(WINAMP_STREAMFILE *streamfile, uint8_t *dest, off_t offset, size_t length) {
|
||||
return streamfile->stdiosf->read(streamfile->stdiosf,dest,offset,length);
|
||||
@ -216,8 +244,8 @@ static STREAMFILE *wasf_open(WINAMP_STREAMFILE *streamFile, const char *const fi
|
||||
}
|
||||
|
||||
/* STREAMFILEs carry char/UTF8 names, convert to wchar for Winamp */
|
||||
wa_char_to_wchar(wpath,PATH_LIMIT, filename);
|
||||
return open_winamp_streamfile_by_wpath(wpath);
|
||||
wa_char_to_ichar(wpath,PATH_LIMIT, filename);
|
||||
return open_winamp_streamfile_by_ipath(wpath);
|
||||
}
|
||||
|
||||
static void wasf_close(WINAMP_STREAMFILE *streamfile) {
|
||||
@ -255,7 +283,7 @@ fail:
|
||||
}
|
||||
|
||||
|
||||
static STREAMFILE *open_winamp_streamfile_by_wpath(const in_char *wpath) {
|
||||
static STREAMFILE *open_winamp_streamfile_by_ipath(const in_char *wpath) {
|
||||
FILE *infile = NULL;
|
||||
STREAMFILE *streamFile;
|
||||
char path[PATH_LIMIT];
|
||||
@ -265,7 +293,7 @@ static STREAMFILE *open_winamp_streamfile_by_wpath(const in_char *wpath) {
|
||||
if (!infile) return NULL;
|
||||
|
||||
/* convert to UTF-8 if needed for internal use */
|
||||
wa_wchar_to_char(path,PATH_LIMIT, wpath);
|
||||
wa_ichar_to_char(path,PATH_LIMIT, wpath);
|
||||
|
||||
streamFile = open_winamp_streamfile_by_file(infile,path);
|
||||
if (!streamFile) {
|
||||
@ -282,7 +310,7 @@ static VGMSTREAM* init_vgmstream_winamp(const in_char *fn, int stream_index) {
|
||||
//return init_vgmstream(fn);
|
||||
|
||||
/* manually init streamfile to pass the stream index */
|
||||
STREAMFILE *streamFile = open_winamp_streamfile_by_wpath(fn); //open_stdio_streamfile(fn);
|
||||
STREAMFILE *streamFile = open_winamp_streamfile_by_ipath(fn); //open_stdio_streamfile(fn);
|
||||
if (streamFile) {
|
||||
streamFile->stream_index = stream_index;
|
||||
vgmstream = init_vgmstream_from_STREAMFILE(streamFile);
|
||||
@ -336,6 +364,7 @@ static void cfg_char_to_wchar(TCHAR *wdst, size_t wdstsize, const char *src) {
|
||||
#define DEFAULT_IGNORE_LOOP 0
|
||||
#define DEFAULT_DISABLE_SUBSONGS 0
|
||||
#define DEFAULT_DOWNMIX_CHANNELS 0
|
||||
#define DEFAULT_TAGFILE_DISABLE 0
|
||||
|
||||
#define INI_ENTRY_FADE_SECONDS TEXT("fade_seconds")
|
||||
#define INI_ENTRY_FADE_DELAY_SECONDS TEXT("fade_delay")
|
||||
@ -345,6 +374,7 @@ static void cfg_char_to_wchar(TCHAR *wdst, size_t wdstsize, const char *src) {
|
||||
#define INI_ENTRY_IGNORE_LOOP TEXT("ignore_loop")
|
||||
#define INI_ENTRY_DISABLE_SUBSONGS TEXT("disable_subsongs")
|
||||
#define INI_ENTRY_DOWNMIX_CHANNELS TEXT("downmix_channels")
|
||||
#define INI_ENTRY_TAGFILE_DISABLE TEXT("tagfile_disable")
|
||||
|
||||
TCHAR *priority_strings[] = {
|
||||
TEXT("Idle"),
|
||||
@ -458,6 +488,7 @@ static void load_config() {
|
||||
settings.downmix_channels = DEFAULT_DOWNMIX_CHANNELS;
|
||||
}
|
||||
|
||||
settings.tagfile_disable = GetPrivateProfileInt(CONFIG_APP_NAME,INI_ENTRY_TAGFILE_DISABLE,DEFAULT_TAGFILE_DISABLE,iniFile);
|
||||
}
|
||||
|
||||
/* config dialog handler */
|
||||
@ -508,6 +539,9 @@ INT_PTR CALLBACK configDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lPara
|
||||
cfg_sprintf(buf, TEXT("%d"),settings.downmix_channels);
|
||||
SetDlgItemText(hDlg,IDC_DOWNMIX_CHANNELS,buf);
|
||||
|
||||
if (settings.tagfile_disable)
|
||||
CheckDlgButton(hDlg,IDC_TAGFILE_DISABLE,BST_CHECKED);
|
||||
|
||||
break;
|
||||
|
||||
case WM_COMMAND: /* button presses */
|
||||
@ -598,6 +632,10 @@ INT_PTR CALLBACK configDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lPara
|
||||
settings.downmix_channels = temp_downmix_channels;
|
||||
cfg_sprintf(buf, TEXT("%d"),settings.downmix_channels);
|
||||
WritePrivateProfileString(CONFIG_APP_NAME,INI_ENTRY_DOWNMIX_CHANNELS,buf,iniFile);
|
||||
|
||||
settings.tagfile_disable = (IsDlgButtonChecked(hDlg,IDC_TAGFILE_DISABLE) == BST_CHECKED);
|
||||
cfg_sprintf(buf, TEXT("%d"),settings.tagfile_disable);
|
||||
WritePrivateProfileString(CONFIG_APP_NAME,INI_ENTRY_TAGFILE_DISABLE,buf,iniFile);
|
||||
}
|
||||
|
||||
EndDialog(hDlg,TRUE);
|
||||
@ -628,6 +666,7 @@ INT_PTR CALLBACK configDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lPara
|
||||
|
||||
CheckDlgButton(hDlg,IDC_DISABLE_SUBSONGS,BST_UNCHECKED);
|
||||
SetDlgItemText(hDlg,IDC_DOWNMIX_CHANNELS,DEFAULT_DOWNMIX_CHANNELS);
|
||||
CheckDlgButton(hDlg,IDC_TAGFILE_DISABLE,BST_UNCHECKED);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -706,19 +745,17 @@ static int split_subsongs(const in_char * filename, int stream_index, VGMSTREAM
|
||||
/* remove current file from the playlist */
|
||||
SendMessage(hPlaylistWindow, WM_WA_IPC, IPC_PE_DELETEINDEX, playlist_index);
|
||||
|
||||
/* autoplay doesn't always advance to the first unpacked track, manually fails too */
|
||||
/* autoplay doesn't always advance to the first unpacked track, but manually fails somehow */
|
||||
//SendMessage(input_module.hMainWindow,WM_WA_IPC,playlist_index,IPC_SETPLAYLISTPOS);
|
||||
//SendMessage(input_module.hMainWindow,WM_WA_IPC,0,IPC_STARTPLAY);
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* parses a modified filename ('fakename') extracting tags parameters (NULL tag for first = filename) */
|
||||
static int parse_fn_string(const in_char * fn, const in_char * tag, in_char * dst, int dst_size) {
|
||||
in_char *end;
|
||||
const in_char *end = wa_strchr(fn,'|');
|
||||
|
||||
end = wa_strchr(fn,'|');
|
||||
if (tag==NULL) {
|
||||
wa_strcpy(dst,fn);
|
||||
if (end)
|
||||
@ -726,14 +763,12 @@ static int parse_fn_string(const in_char * fn, const in_char * tag, in_char * ds
|
||||
return 1;
|
||||
}
|
||||
|
||||
//todo actually find + read tags
|
||||
dst[0] = '\0';
|
||||
return 0;
|
||||
}
|
||||
static int parse_fn_int(const in_char * fn, const in_char * tag, int * num) {
|
||||
in_char * start = wa_strchr(fn,'|');
|
||||
const in_char * start = wa_strchr(fn,'|');
|
||||
|
||||
//todo actually find + read tags
|
||||
if (start > 0) {
|
||||
wa_sscanf(start+1, wa_L("$s=%i "), num);
|
||||
return 1;
|
||||
@ -767,13 +802,13 @@ static void add_extension(int length, char * dst, const char * ext) {
|
||||
ext_len = strlen(ext);
|
||||
|
||||
/* find end of dst (double \0), saved in i */
|
||||
for (i=0; i<length-2 && (dst[i] || dst[i+1]); i++)
|
||||
for (i = 0; i < length-2 && (dst[i] || dst[i+1]); i++)
|
||||
;
|
||||
|
||||
/* check if end reached or not enough room to add */
|
||||
if (i == length-2 || i + EXT_BUFFER_SIZE+2 > length-2 || ext_len * 3 + 20+2 > EXT_BUFFER_SIZE) {
|
||||
dst[i]='\0';
|
||||
dst[i+1]='\0';
|
||||
dst[i] = '\0';
|
||||
dst[i+1] = '\0';
|
||||
return;
|
||||
}
|
||||
|
||||
@ -781,16 +816,17 @@ static void add_extension(int length, char * dst, const char * ext) {
|
||||
i++;
|
||||
|
||||
/* uppercase ext */
|
||||
for (j=0; j < ext_len; j++)
|
||||
for (j = 0; j < ext_len; j++)
|
||||
ext_upp[j] = toupper(ext[j]);
|
||||
ext_upp[j] = '\0';
|
||||
|
||||
/* copy new extension + double null terminate */
|
||||
written = sprintf(buf, "%s%c%s Audio File (*.%s)%c", ext,'\0',ext_upp,ext_upp,'\0'); /*ex: "vgmstream\0vgmstream Audio File (*.VGMSTREAM)\0" */
|
||||
for (j=0; j < written; i++,j++)
|
||||
/* ex: "vgmstream\0vgmstream Audio File (*.VGMSTREAM)\0" */
|
||||
written = sprintf(buf, "%s%c%s Audio File (*.%s)%c", ext,'\0',ext_upp,ext_upp,'\0');
|
||||
for (j = 0; j < written; i++,j++)
|
||||
dst[i] = buf[j];
|
||||
dst[i]='\0';
|
||||
dst[i+1]='\0';
|
||||
dst[i] = '\0';
|
||||
dst[i+1] = '\0';
|
||||
}
|
||||
|
||||
/* Creates Winamp's extension list, a single string that ends with \0\0.
|
||||
@ -837,7 +873,7 @@ static void get_title(in_char * dst, int dst_size, const in_char * fn, VGMSTREAM
|
||||
/* show name, but not for the base stream */
|
||||
if (infostream && infostream->stream_name[0] != '\0' && stream_index > 0) {
|
||||
in_char stream_name[PATH_LIMIT];
|
||||
wa_char_to_wchar(stream_name, PATH_LIMIT, infostream->stream_name);
|
||||
wa_char_to_ichar(stream_name, PATH_LIMIT, infostream->stream_name);
|
||||
wa_snprintf(buffer,PATH_LIMIT, wa_L(" (%s)"), stream_name);
|
||||
wa_strcat(dst,buffer);
|
||||
}
|
||||
@ -1198,7 +1234,8 @@ void winamp_GetFileInfo(const in_char *fn, in_char *title, int *length_in_ms) {
|
||||
if (length_in_ms) {
|
||||
*length_in_ms = -1000;
|
||||
if (infostream) {
|
||||
int num_samples = get_vgmstream_play_samples(infoconfig.song_loop_count,infoconfig.song_fade_time,infoconfig.song_fade_delay,infostream);
|
||||
const int num_samples = get_vgmstream_play_samples(
|
||||
infoconfig.song_loop_count,infoconfig.song_fade_time,infoconfig.song_fade_delay,infostream);
|
||||
*length_in_ms = num_samples * 1000LL /infostream->sample_rate;
|
||||
}
|
||||
}
|
||||
@ -1214,8 +1251,8 @@ void winamp_EQSet(int on, char data[10], int preamp) {
|
||||
|
||||
/* the decode thread */
|
||||
DWORD WINAPI __stdcall decode(void *arg) {
|
||||
int max_buffer_samples = sizeof(sample_buffer) / sizeof(sample_buffer[0]) / 2 / vgmstream->channels;
|
||||
int max_samples = stream_length_samples;
|
||||
const int max_buffer_samples = sizeof(sample_buffer) / sizeof(sample_buffer[0]) / 2 / vgmstream->channels;
|
||||
const int max_samples = stream_length_samples;
|
||||
|
||||
while (!decode_abort) {
|
||||
int samples_to_do;
|
||||
@ -1284,11 +1321,11 @@ DWORD WINAPI __stdcall decode(void *arg) {
|
||||
if (vgmstream->loop_flag && fade_samples > 0 && !settings.loop_forever) {
|
||||
int samples_into_fade = decode_pos_samples - (stream_length_samples - fade_samples);
|
||||
if (samples_into_fade + samples_to_do > 0) {
|
||||
int j,k;
|
||||
for (j=0; j < samples_to_do; j++, samples_into_fade++) {
|
||||
int j, k;
|
||||
for (j = 0; j < samples_to_do; j++, samples_into_fade++) {
|
||||
if (samples_into_fade > 0) {
|
||||
double fadedness = (double)(fade_samples-samples_into_fade)/fade_samples;
|
||||
for (k=0; k < vgmstream->channels; k++) {
|
||||
const double fadedness = (double)(fade_samples-samples_into_fade)/fade_samples;
|
||||
for (k = 0; k < vgmstream->channels; k++) {
|
||||
sample_buffer[j*vgmstream->channels+k] =
|
||||
(short)(sample_buffer[j*vgmstream->channels+k]*fadedness);
|
||||
}
|
||||
@ -1385,6 +1422,210 @@ In_Module input_module = {
|
||||
0 /* outMod */
|
||||
};
|
||||
|
||||
__declspec( dllexport ) In_Module * winampGetInModule2() {
|
||||
__declspec(dllexport) In_Module * winampGetInModule2() {
|
||||
return &input_module;
|
||||
}
|
||||
|
||||
|
||||
/* ************************************* */
|
||||
/* IN_TAGS */
|
||||
/* ************************************* */
|
||||
|
||||
/* could malloc and stuff but totals aren't much bigger than PATH_LIMITs anyway */
|
||||
#define WINAMP_TAGS_ENTRY_MAX 30
|
||||
#define WINAMP_TAGS_ENTRY_SIZE 2048
|
||||
|
||||
typedef struct {
|
||||
in_char filename[PATH_LIMIT]; /* tags are loaded for this file */
|
||||
int tag_count;
|
||||
|
||||
char keys[WINAMP_TAGS_ENTRY_MAX][WINAMP_TAGS_ENTRY_SIZE+1];
|
||||
char vals[WINAMP_TAGS_ENTRY_MAX][WINAMP_TAGS_ENTRY_SIZE+1];
|
||||
} winamp_tags;
|
||||
|
||||
winamp_tags last_tags;
|
||||
|
||||
|
||||
/* Loads all tags for a filename in a temp struct to improve performance, as
|
||||
* Winamp requests one tag at a time and may reask for the same tag several times */
|
||||
static void load_tagfile_info(in_char* filename) {
|
||||
STREAMFILE *tagFile = NULL;
|
||||
char filename_utf8[PATH_LIMIT];
|
||||
char tagfile_path_utf8[PATH_LIMIT];
|
||||
in_char tagfile_path_i[PATH_LIMIT];
|
||||
char *path;
|
||||
|
||||
|
||||
if (settings.tagfile_disable) {
|
||||
last_tags.tag_count = 0; /* maybe helps if setting changes during play */
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (wa_strcmp(last_tags.filename, filename) == 0) {
|
||||
return; /* not changed, tags still apply */
|
||||
}
|
||||
|
||||
/* tags are now for this filename, find tagfile path */
|
||||
wa_ichar_to_char(filename_utf8, PATH_LIMIT, filename);
|
||||
strcpy(tagfile_path_utf8,filename_utf8);
|
||||
|
||||
path = strrchr(tagfile_path_utf8,'\\');
|
||||
if (path != NULL) {
|
||||
path[1] = '\0'; /* includes "\", remove after that from tagfile_path */
|
||||
strcat(tagfile_path_utf8,tagfile_name);
|
||||
}
|
||||
else { /* ??? */
|
||||
strcpy(tagfile_path_utf8,tagfile_name);
|
||||
}
|
||||
wa_char_to_ichar(tagfile_path_i, PATH_LIMIT, tagfile_path_utf8);
|
||||
|
||||
wa_strcpy(last_tags.filename, filename);
|
||||
last_tags.tag_count = 0;
|
||||
|
||||
/* load all tags from tagfile */
|
||||
tagFile = open_winamp_streamfile_by_ipath(tagfile_path_i);
|
||||
if (tagFile != NULL) {
|
||||
VGMSTREAM_TAGS tag;
|
||||
int i;
|
||||
|
||||
vgmstream_tags_reset(&tag, filename_utf8);
|
||||
while (vgmstream_tags_next_tag(&tag, tagFile)) {
|
||||
int repeated_tag = 0;
|
||||
int current_tag = last_tags.tag_count;
|
||||
if (current_tag >= WINAMP_TAGS_ENTRY_MAX)
|
||||
continue;
|
||||
|
||||
/* should overwrite repeated tags as global tags may appear multiple times */
|
||||
for (i = 0; i < current_tag; i++) {
|
||||
if (strcmp(last_tags.keys[i], tag.key) == 0) {
|
||||
current_tag = i;
|
||||
repeated_tag = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
last_tags.keys[current_tag][0] = '\0';
|
||||
strncat(last_tags.keys[current_tag], tag.key, WINAMP_TAGS_ENTRY_SIZE);
|
||||
last_tags.vals[current_tag][0] = '\0';
|
||||
strncat(last_tags.vals[current_tag], tag.val, WINAMP_TAGS_ENTRY_SIZE);
|
||||
if (!repeated_tag)
|
||||
last_tags.tag_count++;
|
||||
}
|
||||
|
||||
close_streamfile(tagFile);
|
||||
}
|
||||
}
|
||||
|
||||
/* Winamp repeatedly calls this for every known tag currently used in the Advanced Title Formatting (ATF)
|
||||
* config, 'metadata' being the requested tag. Returns 0 on failure/tag not found.
|
||||
* May be called again after certain actions (adding file to playlist, Play, GetFileInfo, etc), and
|
||||
* doesn't seem the plugin can tell Winamp all tags it supports at once or use custom tags. */
|
||||
//todo unicode stuff could be improved... probably
|
||||
static int winampGetExtendedFileInfo_common(in_char* filename, char *metadata, char* ret, int retlen) {
|
||||
int i, tag_found;
|
||||
int max_len;
|
||||
|
||||
/* always called (value in ms), must return ok so other tags get called */
|
||||
if (strcasecmp(metadata, "length") == 0) {
|
||||
strcpy(ret, "0");//todo should export but shows GetFileInfo's ms if not provided
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* load list current tags, if necessary */
|
||||
load_tagfile_info(filename);
|
||||
|
||||
|
||||
#if 0
|
||||
/* special case to fill WA5's unified dialog */
|
||||
if (strcasecmp(metadata, "formatinformation") == 0) {
|
||||
generate_format_string(...);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* find requested tag */
|
||||
tag_found = 0;
|
||||
max_len = (retlen > 0) ? retlen-1 : retlen;
|
||||
for (i = 0; i < last_tags.tag_count; i++) {
|
||||
if (strcasecmp(metadata,last_tags.keys[i]) == 0) {
|
||||
ret[0] = '\0';
|
||||
strncat(ret, last_tags.vals[i], max_len);
|
||||
tag_found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!tag_found)
|
||||
goto fail;
|
||||
|
||||
return 1;
|
||||
|
||||
fail:
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* for Winamp 5.24 */
|
||||
__declspec (dllexport) int winampGetExtendedFileInfo(char *filename, char *metadata, char *ret, int retlen) {
|
||||
in_char filename_wchar[PATH_LIMIT];
|
||||
int ok;
|
||||
|
||||
if (settings.tagfile_disable)
|
||||
return 0;
|
||||
|
||||
wa_char_to_ichar(filename_wchar,PATH_LIMIT, filename);
|
||||
|
||||
ok = winampGetExtendedFileInfo_common(filename_wchar, metadata, ret, retlen);
|
||||
if (ok == 0)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* for Winamp 5.3+ */
|
||||
__declspec (dllexport) int winampGetExtendedFileInfoW(wchar_t *filename, char *metadata, wchar_t *ret, int retlen) {
|
||||
in_char filename_ichar[PATH_LIMIT];
|
||||
char ret_utf8[2048];
|
||||
int ok;
|
||||
|
||||
if (settings.tagfile_disable)
|
||||
return 0;
|
||||
|
||||
wa_wchar_to_ichar(filename_ichar,PATH_LIMIT, filename);
|
||||
|
||||
ok = winampGetExtendedFileInfo_common(filename_ichar, metadata, ret_utf8,2048);
|
||||
if (ok == 0)
|
||||
return 0;
|
||||
|
||||
wa_char_to_wchar(ret,retlen, ret_utf8);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* return 1 if you want winamp to show it's own file info dialogue, 0 if you want to show your own (via In_Module.InfoBox)
|
||||
* if returning 1, remember to implement winampGetExtendedFileInfo("formatinformation")! */
|
||||
__declspec(dllexport) int winampUseUnifiedFileInfoDlg(const wchar_t * fn) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
__declspec(dllexport) int winampUninstallPlugin(HINSTANCE hDllInst, HWND hwndDlg, int param) {
|
||||
/* may uninstall without restart as we aren't subclassing */
|
||||
return IN_PLUGIN_UNINSTALL_NOW;
|
||||
}
|
||||
|
||||
/* winamp sekrit exports: */
|
||||
/*
|
||||
EXPORTS
|
||||
winampGetInModule2 @1
|
||||
winampGetExtendedFileInfo @2
|
||||
winampGetExtendedFileInfoW @3
|
||||
winampAddUnifiedFileInfoPane @4
|
||||
winampUseUnifiedFileInfoDlg @5
|
||||
winampGetExtendedRead_close @6
|
||||
winampGetExtendedRead_getData @7
|
||||
winampGetExtendedRead_open @8
|
||||
winampGetExtendedRead_openW @9
|
||||
winampGetExtendedRead_setTime @10
|
||||
winampUninstallPlugin @11
|
||||
*/
|
||||
|
@ -71,7 +71,7 @@
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>../ext_includes;$(DependenciesDir)/qaac/mp4v2/include;$(DependenciesDir)/fdk-aac/libSYS/include;$(DependenciesDir)/fdk-aac/libAACdec/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;VGM_USE_VORBIS;VGM_USE_MPEG;VGM_USE_FFMPEG;VGM_USE_G7221;VGM_USE_MP4V2;VGM_USE_FDKAAC;VGM_USE_ATRAC9;VGM_USE_CELT;_DEBUG;_WINDOWS;_USRDLL;IN_VGMSTREAM_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>WIN32;VGM_USE_VORBIS;VGM_USE_MPEG;VGM_USE_FFMPEG;VGM_USE_G7221;VGM_USE_MP4V2;VGM_USE_FDKAAC;VGM_USE_ATRAC9;VGM_USE_CELT;_DEBUG;_WINDOWS;_USRDLL;IN_VGMSTREAM_EXPORTS;VGM_WINAMP_UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>true</MinimalRebuild>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
@ -99,7 +99,7 @@
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>../ext_includes;$(DependenciesDir)/qaac/mp4v2/include;$(DependenciesDir)/fdk-aac/libSYS/include;$(DependenciesDir)/fdk-aac/libAACdec/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;VGM_USE_VORBIS;VGM_USE_MPEG;VGM_USE_FFMPEG;VGM_USE_G7221;VGM_USE_MP4V2;VGM_USE_FDKAAC;NDEBUG;_WINDOWS;_USRDLL;IN_VGMSTREAM_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>WIN32;VGM_USE_VORBIS;VGM_USE_MPEG;VGM_USE_FFMPEG;VGM_USE_G7221;VGM_USE_MP4V2;VGM_USE_FDKAAC;VGM_USE_ATRAC9;VGM_USE_CELT;NDEBUG;_WINDOWS;_USRDLL;IN_VGMSTREAM_EXPORTS;VGM_WINAMP_UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
|
@ -10,3 +10,4 @@
|
||||
#define IDC_DEFAULT_BUTTON 1008
|
||||
#define IDC_DISABLE_SUBSONGS 1009
|
||||
#define IDC_DOWNMIX_CHANNELS 1011
|
||||
#define IDC_TAGFILE_DISABLE 1012
|
||||
|
@ -9,25 +9,35 @@ STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "in_vgmstream configuration"
|
||||
FONT 8, "MS Sans Serif", 0, 0, 0x0
|
||||
BEGIN
|
||||
// right column
|
||||
DEFPUSHBUTTON "OK",IDOK,129,7,50,14
|
||||
PUSHBUTTON "Cancel",IDCANCEL,129,24,50,14
|
||||
PUSHBUTTON "Default",IDC_DEFAULT_BUTTON,129,41,50,14
|
||||
|
||||
LTEXT "Thread Priority",IDC_STATIC,110,60,46,8
|
||||
CONTROL "Slider1",IDC_THREAD_PRIORITY_SLIDER,"msctls_trackbar32",TBS_AUTOTICKS | WS_TABSTOP,96,76,77,10
|
||||
CTEXT "DATARIFIC",IDC_THREAD_PRIORITY_TEXT,96,92,77,18
|
||||
|
||||
// left column
|
||||
LTEXT "Loop Count",IDC_STATIC,7,10,44,12
|
||||
EDITTEXT IDC_LOOP_COUNT,52,7,39,14,ES_AUTOHSCROLL
|
||||
|
||||
LTEXT "Fade Length",IDC_STATIC,7,25,41,8
|
||||
EDITTEXT IDC_FADE_SECONDS,52,23,39,14,ES_AUTOHSCROLL
|
||||
LTEXT "seconds",IDC_STATIC,93,25,29,11
|
||||
|
||||
LTEXT "Fade Delay",IDC_STATIC,7,40,41,8
|
||||
EDITTEXT IDC_FADE_DELAY_SECONDS,52,38,39,14,ES_AUTOHSCROLL
|
||||
LTEXT "seconds",IDC_STATIC,93,40,29,11
|
||||
|
||||
CONTROL "Loop normally",IDC_LOOP_NORMALLY,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,7,57,77,10
|
||||
CONTROL "Loop forever",IDC_LOOP_FOREVER,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,7,70,77,10
|
||||
CONTROL "Ignore looping",IDC_IGNORE_LOOP,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,7,83,77,10
|
||||
|
||||
CONTROL "Disable subsongs",IDC_DISABLE_SUBSONGS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,99,87,10
|
||||
|
||||
LTEXT "Downmix",IDC_STATIC,7,115,48,12
|
||||
EDITTEXT IDC_DOWNMIX_CHANNELS,52,112,37,14,ES_AUTOHSCROLL
|
||||
LTEXT "Thread Priority",IDC_STATIC,21,132,46,8
|
||||
CONTROL "Slider1",IDC_THREAD_PRIORITY_SLIDER,"msctls_trackbar32",TBS_AUTOTICKS | WS_TABSTOP,7,140,77,10
|
||||
CTEXT "DATARIFIC",IDC_THREAD_PRIORITY_TEXT,7,153,77,18
|
||||
|
||||
CONTROL "Disable tagfile",IDC_TAGFILE_DISABLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,131,87,10
|
||||
END
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user