mirror of
https://github.com/vgmstream/vgmstream.git
synced 2025-02-17 11:18:31 +01:00
Merge pull request #1561 from bnnm/api-misc3
- Fix some .agsc [Metroid Prime (GC)] - Remove fake .b1s format (use .txth) - Remove fake format .ffw (use .txth) - cleanup
This commit is contained in:
commit
ae16779577
@ -1,7 +1,7 @@
|
||||
# CLI
|
||||
|
||||
add_executable(vgmstream_cli
|
||||
vgmstream_cli.c)
|
||||
vgmstream_cli.c wav_utils.c)
|
||||
|
||||
set_target_properties(vgmstream_cli PROPERTIES
|
||||
PREFIX ""
|
||||
@ -67,7 +67,7 @@ if(NOT WIN32 AND BUILD_V123)
|
||||
# vgmstream123
|
||||
|
||||
add_executable(vgmstream123
|
||||
vgmstream123.c)
|
||||
vgmstream123.c wav_utils.c)
|
||||
|
||||
# Link to the vgmstream library as well as libao
|
||||
target_link_libraries(vgmstream123
|
||||
|
@ -41,11 +41,11 @@ export CFLAGS LDFLAGS
|
||||
### targets
|
||||
|
||||
vgmstream_cli: libvgmstream.a $(TARGET_EXT_LIBS)
|
||||
$(CC) $(CFLAGS) vgmstream_cli.c $(LDFLAGS) -o $(OUTPUT_CLI)
|
||||
$(CC) $(CFLAGS) vgmstream_cli.c wav_utils.c $(LDFLAGS) -o $(OUTPUT_CLI)
|
||||
$(STRIP) $(OUTPUT_CLI)
|
||||
|
||||
vgmstream123: libvgmstream.a $(TARGET_EXT_LIBS)
|
||||
$(CC) $(CFLAGS) $(LIBAO_INC) vgmstream123.c $(LDFLAGS) $(LIBAO_LIB) -o $(OUTPUT_123)
|
||||
$(CC) $(CFLAGS) $(LIBAO_INC) vgmstream123.c wav_utils.c $(LDFLAGS) $(LIBAO_LIB) -o $(OUTPUT_123)
|
||||
$(STRIP) $(OUTPUT_123)
|
||||
|
||||
api_example: libvgmstream.a $(TARGET_EXT_LIBS)
|
||||
|
@ -9,8 +9,8 @@ endif
|
||||
AM_CFLAGS = -DVGMSTREAM_VERSION_AUTO -DVGM_LOG_OUTPUT -I$(top_builddir) -I$(top_srcdir) -I$(top_srcdir)/ext_includes/ $(AO_CFLAGS)
|
||||
AM_MAKEFLAGS = -f Makefile.autotools
|
||||
|
||||
vgmstream_cli_SOURCES = vgmstream_cli.c
|
||||
vgmstream_cli_SOURCES = vgmstream_cli.c wav_utils.c
|
||||
vgmstream_cli_LDADD = ../src/libvgmstream.la
|
||||
|
||||
vgmstream123_SOURCES = vgmstream123.c
|
||||
vgmstream123_SOURCES = vgmstream123.c wav_utils.c
|
||||
vgmstream123_LDADD = ../src/libvgmstream.la $(AO_LIBS)
|
||||
|
@ -39,7 +39,6 @@
|
||||
|
||||
#include "../src/vgmstream.h"
|
||||
#include "../src/api.h"
|
||||
#include "../src/util/samples_ops.h"
|
||||
|
||||
#include "../version.h"
|
||||
#ifndef VGMSTREAM_VERSION
|
||||
@ -397,7 +396,7 @@ static int play_vgmstream(const char* filename, song_settings_t* cfg) {
|
||||
render_vgmstream(buffer, to_do, vgmstream);
|
||||
|
||||
#if LITTLE_ENDIAN_OUTPUT
|
||||
swap_samples_le(buffer, output_channels * to_do);
|
||||
swap_samples_le(buffer, output_channels * to_do, 0);
|
||||
#endif
|
||||
|
||||
if (verbose && !out_filename) {
|
||||
|
@ -4,10 +4,10 @@
|
||||
#define POSIXLY_CORRECT
|
||||
|
||||
#include <getopt.h>
|
||||
#include "wav_utils.h"
|
||||
#include "../src/vgmstream.h"
|
||||
#include "../src/api.h"
|
||||
#include "../src/util.h"
|
||||
#include "../src/util/samples_ops.h"
|
||||
//todo use <>?
|
||||
#ifdef HAVE_JSON
|
||||
#include "jansson/jansson.h"
|
||||
@ -48,8 +48,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);
|
||||
|
||||
static void usage(const char* progname, int is_help) {
|
||||
|
||||
fprintf(is_help ? stdout : stderr, APP_INFO "\n"
|
||||
@ -901,7 +899,7 @@ static int write_file(VGMSTREAM* vgmstream, cli_config* cfg) {
|
||||
|
||||
render_vgmstream(buf, to_get, vgmstream);
|
||||
|
||||
swap_samples_le(buf, channels * to_get); /* change to WAV (LE) endian if PC is Big Endian */
|
||||
swap_samples_le(buf, channels * to_get, 0);
|
||||
fwrite(buf, sizeof(sample_t), to_get * channels, outfile);
|
||||
/* should write infinitely until program kill */
|
||||
}
|
||||
@ -912,10 +910,16 @@ static int write_file(VGMSTREAM* vgmstream, cli_config* cfg) {
|
||||
uint8_t wav_buf[0x100];
|
||||
size_t bytes_done;
|
||||
|
||||
bytes_done = make_wav_header(wav_buf,0x100,
|
||||
len_samples, vgmstream->sample_rate, channels,
|
||||
cfg->write_lwav, cfg->lwav_loop_start, cfg->lwav_loop_end);
|
||||
wav_header_t wav = {
|
||||
.sample_count = len_samples,
|
||||
.sample_rate = vgmstream->sample_rate,
|
||||
.channels = channels,
|
||||
.write_smpl_chunk = cfg->write_lwav,
|
||||
.loop_start = cfg->lwav_loop_start,
|
||||
.loop_end = cfg->lwav_loop_end
|
||||
};
|
||||
|
||||
bytes_done = wav_make_header(wav_buf, 0x100, &wav);
|
||||
fwrite(wav_buf, sizeof(uint8_t), bytes_done, outfile);
|
||||
}
|
||||
|
||||
@ -929,7 +933,7 @@ static int write_file(VGMSTREAM* vgmstream, cli_config* cfg) {
|
||||
render_vgmstream(buf, to_get, vgmstream);
|
||||
|
||||
if (!cfg->decode_only) {
|
||||
swap_samples_le(buf, channels * to_get); /* change to WAV (LE) endian if PC is Big Endian */
|
||||
swap_samples_le(buf, channels * to_get, 0);
|
||||
fwrite(buf, sizeof(sample_t), to_get * channels, outfile);
|
||||
}
|
||||
}
|
||||
@ -1020,66 +1024,3 @@ static void print_json_info(VGMSTREAM* vgm, cli_config* cfg) {
|
||||
json_decref(final_object);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void make_smpl_chunk(uint8_t* buf, int32_t loop_start, int32_t loop_end) {
|
||||
int i;
|
||||
|
||||
memcpy(buf+0, "smpl", 0x04); /* header */
|
||||
put_s32le(buf+0x04, 0x3c); /* size */
|
||||
|
||||
for (i = 0; i < 7; i++)
|
||||
put_s32le(buf+0x08 + i * 0x04, 0);
|
||||
|
||||
put_s32le(buf+0x24, 1);
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
put_s32le(buf+0x28 + i * 0x04, 0);
|
||||
|
||||
put_s32le(buf+0x34, loop_start);
|
||||
put_s32le(buf+0x38, loop_end);
|
||||
put_s32le(buf+0x3C, 0);
|
||||
put_s32le(buf+0x40, 0);
|
||||
}
|
||||
|
||||
/* make a RIFF header for .wav */
|
||||
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) {
|
||||
size_t data_size, header_size;
|
||||
|
||||
data_size = sample_count * channels * sizeof(sample_t);
|
||||
header_size = 0x2c;
|
||||
if (smpl_chunk && loop_end)
|
||||
header_size += 0x3c+ 0x08;
|
||||
|
||||
if (header_size > buf_size)
|
||||
goto fail;
|
||||
|
||||
memcpy(buf+0x00, "RIFF", 0x04); /* RIFF header */
|
||||
put_u32le(buf+0x04, (int32_t)(header_size - 0x08 + data_size)); /* size of RIFF */
|
||||
|
||||
memcpy(buf+0x08, "WAVE", 4); /* WAVE header */
|
||||
|
||||
memcpy(buf+0x0c, "fmt ", 0x04); /* WAVE fmt chunk */
|
||||
put_s32le(buf+0x10, 0x10); /* size of WAVE fmt chunk */
|
||||
put_s16le(buf+0x14, 0x0001); /* codec PCM */
|
||||
put_s16le(buf+0x16, channels); /* channel count */
|
||||
put_s32le(buf+0x18, sample_rate); /* sample rate */
|
||||
put_s32le(buf+0x1c, sample_rate * channels * sizeof(sample_t)); /* bytes per second */
|
||||
put_s16le(buf+0x20, (int16_t)(channels * sizeof(sample_t))); /* block align */
|
||||
put_s16le(buf+0x22, sizeof(sample_t) * 8); /* significant bits per sample */
|
||||
|
||||
if (smpl_chunk && loop_end) {
|
||||
make_smpl_chunk(buf+0x24, loop_start, loop_end);
|
||||
memcpy(buf+0x24+0x3c+0x08, "data", 0x04); /* WAVE data chunk */
|
||||
put_u32le(buf+0x28+0x3c+0x08, (int32_t)data_size); /* size of WAVE data chunk */
|
||||
}
|
||||
else {
|
||||
memcpy(buf+0x24, "data", 0x04); /* WAVE data chunk */
|
||||
put_s32le(buf+0x28, (int32_t)data_size); /* size of WAVE data chunk */
|
||||
}
|
||||
|
||||
/* could try to add channel_layout, but would need to write WAVEFORMATEXTENSIBLE (maybe only if arg flag?) */
|
||||
|
||||
return header_size;
|
||||
fail:
|
||||
return 0;
|
||||
}
|
||||
|
@ -103,8 +103,12 @@
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="wav_utils.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="vgmstream_cli.c" />
|
||||
<ClCompile Include="wav_utils.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\ext_libs\ext_libs.vcxproj">
|
||||
|
@ -1,6 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
@ -14,9 +18,17 @@
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="wav_utils.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="vgmstream_cli.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="wav_utils.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
152
cli/wav_utils.c
Normal file
152
cli/wav_utils.c
Normal file
@ -0,0 +1,152 @@
|
||||
#include "wav_utils.h"
|
||||
#include "../src/util/reader_put.h"
|
||||
|
||||
static int make_riff_chunk(uint8_t* buf, wav_header_t* wav, uint32_t header_size, uint32_t data_size) {
|
||||
|
||||
put_data (buf+0x00, "RIFF", 0x04);
|
||||
put_u32le(buf+0x04, header_size - 0x08 + data_size);
|
||||
|
||||
put_data (buf+0x08, "WAVE", 0x04);
|
||||
|
||||
return 0x08 + 0x04;
|
||||
}
|
||||
|
||||
static int make_fmt_chunk(uint8_t* buf, wav_header_t* wav) {
|
||||
|
||||
int codec = wav->is_float ? 0x0003 : 0x0001; /* PCM */
|
||||
int bytes_per_second = wav->sample_rate * wav->channels * wav->sample_size;
|
||||
int16_t block_align = wav->channels * wav->sample_size;
|
||||
int bits_per_sample = wav->sample_size * 8;
|
||||
|
||||
put_data (buf + 0x00, "fmt ", 0x04);
|
||||
put_u32le(buf + 0x04, 0x10);
|
||||
|
||||
put_s16le(buf + 0x08, codec);
|
||||
put_s16le(buf + 0x0a, wav->channels);
|
||||
put_s32le(buf + 0x0c, wav->sample_rate);
|
||||
put_s32le(buf + 0x10, bytes_per_second);
|
||||
put_s16le(buf + 0x14, block_align);
|
||||
put_s16le(buf + 0x16, bits_per_sample);
|
||||
|
||||
return 0x08 + 0x10;
|
||||
}
|
||||
|
||||
/* see riff.c */
|
||||
static int make_smpl_chunk(uint8_t* buf, wav_header_t* wav) {
|
||||
|
||||
put_data (buf + 0x00, "smpl", 0x04);
|
||||
put_s32le(buf + 0x04, 0x3c);
|
||||
|
||||
for (int i = 0; i < 7; i++) {
|
||||
put_s32le(buf + 0x08 + i * 0x04, 0);
|
||||
}
|
||||
|
||||
put_s32le(buf + 0x24, 1);
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
put_s32le(buf + 0x28 + i * 0x04, 0);
|
||||
}
|
||||
|
||||
put_s32le(buf + 0x34, wav->loop_start);
|
||||
put_s32le(buf + 0x38, wav->loop_end);
|
||||
put_s32le(buf + 0x3C, 0);
|
||||
put_s32le(buf + 0x40, 0);
|
||||
|
||||
return 0x08 + 0x3c;
|
||||
}
|
||||
|
||||
static int make_data_chunk(uint8_t* buf, wav_header_t* wav, uint32_t data_size) {
|
||||
|
||||
put_data (buf + 0x00, "data", 0x04);
|
||||
put_u32le(buf + 0x04, data_size);
|
||||
|
||||
return 0x08;
|
||||
}
|
||||
|
||||
/* make a RIFF header for .wav */
|
||||
size_t wav_make_header(uint8_t* buf, size_t buf_size, wav_header_t* wav) {
|
||||
size_t header_size;
|
||||
|
||||
/* RIFF + fmt + smpl + data */
|
||||
header_size = 0x08 + 0x04;
|
||||
header_size += 0x08 + 0x10;
|
||||
if (wav->write_smpl_chunk && wav->loop_end)
|
||||
header_size += 0x08 + 0x3c;
|
||||
header_size += 0x08;
|
||||
|
||||
if (header_size > buf_size)
|
||||
return 0;
|
||||
|
||||
if (!wav->sample_size)
|
||||
wav->sample_size = sizeof(short);
|
||||
if (wav->sample_size <= 0 || wav->sample_size >= 4)
|
||||
return 0;
|
||||
|
||||
size_t data_size = wav->sample_count * wav->channels * wav->sample_size;
|
||||
int size;
|
||||
|
||||
size = make_riff_chunk(buf, wav, header_size, data_size);
|
||||
buf += size;
|
||||
|
||||
size = make_fmt_chunk(buf, wav);
|
||||
buf += size;
|
||||
|
||||
if (wav->write_smpl_chunk && wav->loop_end) {
|
||||
size = make_smpl_chunk(buf, wav);
|
||||
buf += size;
|
||||
}
|
||||
|
||||
size = make_data_chunk(buf, wav, data_size);
|
||||
buf += size;
|
||||
|
||||
/* could try to add channel_layout but would need WAVEFORMATEXTENSIBLE */
|
||||
|
||||
return header_size;
|
||||
}
|
||||
|
||||
#if 0
|
||||
void swap_samples_le(sample_t *buf, int count) {
|
||||
/* Windows can't be BE... I think */
|
||||
#if !defined(_WIN32)
|
||||
#if !defined(__BYTE_ORDER__) || __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__
|
||||
for (int i = 0; i < count; i++) {
|
||||
/* 16b sample in memory: aabb where aa=MSB, bb=LSB */
|
||||
uint8_t b0 = buf[i] & 0xff;
|
||||
uint8_t b1 = buf[i] >> 8;
|
||||
uint8_t *p = (uint8_t*)&(buf[i]);
|
||||
/* 16b sample in buffer: bbaa where bb=LSB, aa=MSB */
|
||||
p[0] = b0;
|
||||
p[1] = b1;
|
||||
/* when endianness is LE, buffer has bbaa already so this function can be skipped */
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static inline void swap_value(uint8_t* buf, int sample_size) {
|
||||
for (int i = 0; i < sample_size / 2; i++) {
|
||||
char temp = buf[i];
|
||||
buf[i] = buf[sample_size - i - 1];
|
||||
buf[sample_size - i - 1] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
/* when endianness is LE buffer is correct already and this function can be skipped */
|
||||
void swap_samples_le(void* samples, int samples_len, int sample_size) {
|
||||
/* Windows can't be BE... I think */
|
||||
#if !defined(_WIN32)
|
||||
#if !defined(__BYTE_ORDER__) || __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__
|
||||
if (!sample_size)
|
||||
sample_size = sizeof(short);
|
||||
|
||||
/* 16b sample in memory is AABB where AA=MSB, BB=LSB, swap to BBAA */
|
||||
|
||||
uint8_t* buf = samples;
|
||||
for (int i = 0; i < samples_len; i += sample_size) {
|
||||
swap_value(buf + i, sample_size);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
29
cli/wav_utils.h
Normal file
29
cli/wav_utils.h
Normal file
@ -0,0 +1,29 @@
|
||||
#ifndef _WAV_UTILS_H_
|
||||
#define _WAV_UTILS_H_
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef struct {
|
||||
bool is_float;
|
||||
int sample_size;
|
||||
|
||||
int32_t sample_count;
|
||||
int32_t sample_rate;
|
||||
int channels;
|
||||
|
||||
bool write_smpl_chunk;
|
||||
int32_t loop_start;
|
||||
int32_t loop_end;
|
||||
} wav_header_t;
|
||||
|
||||
/* make a RIFF header for .wav; returns final RIFF size or 0 if buffer is too small */
|
||||
size_t wav_make_header(uint8_t* buf, size_t buf_size, wav_header_t* wav);
|
||||
|
||||
/* swap big endian samples to little endian. Does nothing if machine is already LE.
|
||||
* Used when writting .WAV files, where samples in memory/buf may be BE while RIFF
|
||||
* is expected to have LE samples. */
|
||||
void swap_samples_le(void* samples, int samples_len, int sample_size);
|
||||
|
||||
#endif
|
@ -785,10 +785,6 @@ different internally (encrypted, different versions, etc) and not always can be
|
||||
- Electronic Arts SWVR header [*EA_SWVR*]
|
||||
- *ea_swvr*: `.stream .str`
|
||||
- Codecs: PSX NGC_DSP PCM8_U_int
|
||||
- **ps2_b1s.c**
|
||||
- B1S header [*PS2_B1S*]
|
||||
- *ps2_b1s*: `.b1s`
|
||||
- Codecs: PSX
|
||||
- **lpcm_shade.c**
|
||||
- Shade LPCM header [*LPCM_SHADE*]
|
||||
- *lpcm_shade*: `.w .lpcm`
|
||||
@ -805,10 +801,6 @@ different internally (encrypted, different versions, etc) and not always can be
|
||||
- Guitar Hero III Mobile .bar [*GH3_BAR*]
|
||||
- *bar*: `.bar`
|
||||
- Codecs: IMA
|
||||
- **ffw.c**
|
||||
- Freedom Fighters BGM header [*FFW*]
|
||||
- *ffw*: `.ffw`
|
||||
- Codecs: PCM16BE
|
||||
- **jstm.c**
|
||||
- JSTM Header [*PS2_JSTM*]
|
||||
- *jstm*: `.stm .jstm`
|
||||
@ -1206,9 +1198,9 @@ different internally (encrypted, different versions, etc) and not always can be
|
||||
- Subfiles: *vag riff*
|
||||
- *sps_n1_segmented*: `.at9 .nlsd`
|
||||
- Subfiles: *ogg_vorbis opus_std*
|
||||
- **atx.c**
|
||||
- **apa3.c**
|
||||
- (container)
|
||||
- *atx*: `.atx + .(external)`
|
||||
- *apa3*: `.atx`
|
||||
- Subfiles: *riff*
|
||||
- **sqex_sead.c**
|
||||
- Square Enix SAB header [*SQEX_SAB*]
|
||||
|
23
src/api.h
23
src/api.h
@ -8,8 +8,7 @@
|
||||
/* vgmstream's public API
|
||||
*
|
||||
* By default vgmstream behaves like a simple decoder (extract samples until stream end), but you can configure it
|
||||
* to loop N times or even downmix (since complex formats need those features). In other words, it also behaves
|
||||
* a bit like a player.
|
||||
* to loop N times or even downmix. In other words, it also behaves a bit like a player.
|
||||
*
|
||||
* It exposes multiple options and convenience functions beyond simple decoding mainly for various plugins,
|
||||
* since it was faster moving shared behavior to core rather than reimplementing every time.
|
||||
@ -19,14 +18,13 @@
|
||||
* Notes:
|
||||
* - vgmstream may dynamically allocate stuff as needed (not too much beyond some setup buffers, but varies per format)
|
||||
* - previously the only way to use vgmstream was accesing its internals. Now there is an API internals may change in the future
|
||||
* - some details described in the API may not happen at the moment (they are defined to consider internal changes)
|
||||
* - some details described in the API may not happen at the moment (they are defined for future internal changes)
|
||||
* - main reason it uses the slighly long-winded libvgmstream_* names is that internals use the vgmstream_* 'namespace'
|
||||
* - c-strings should be in UTF-8
|
||||
* - the API is still WIP and may be slightly buggy overall due to lack of time, to be improved later
|
||||
* - vgmstream's features are mostly stable, but this API may be tweaked from time to time (check API_VERSION)
|
||||
*
|
||||
* Basic usage (also see api_example.c):
|
||||
* - libvgmstream_get_version() // just in case
|
||||
* - libvgmstream_init(...) // base context
|
||||
* - libvgmstream_setup(...) // config if needed
|
||||
* - libvgmstream_open(...) // setup format
|
||||
@ -42,7 +40,6 @@
|
||||
//#define LIBVGMSTREAM_CALL __cdecl //needed?
|
||||
//LIBVGMSTREAM_API (type) LIBVGMSTREAM_CALL libvgmstream_function(...);
|
||||
|
||||
|
||||
/* define external function behavior (during compilation) */
|
||||
#if defined(LIBVGMSTREAM_EXPORT)
|
||||
#define LIBVGMSTREAM_API __declspec(dllexport) /* when exporting/creating vgmstream DLL */
|
||||
@ -52,21 +49,7 @@
|
||||
#define LIBVGMSTREAM_API /* nothing, internal/default */
|
||||
#endif
|
||||
|
||||
|
||||
/* Current API version.
|
||||
* - only refers to the API itself, as changes related to formats/etc don't alter this (since they are usually additive)
|
||||
* - vgmstream's features are mostly stable, but this API may be tweaked from time to time
|
||||
*/
|
||||
#define LIBVGMSTREAM_API_VERSION_MAJOR 1 // breaking API/ABI changes
|
||||
#define LIBVGMSTREAM_API_VERSION_MINOR 0 // compatible API/ABI changes
|
||||
#define LIBVGMSTREAM_API_VERSION_PATCH 0 // fixes
|
||||
|
||||
/* returns API version in hex format: 0xMMmmpppp = MM-major, mm-minor, pppp-patch
|
||||
* - use when loading vgmstream as a dynamic library to ensure API/ABI compatibility
|
||||
*/
|
||||
LIBVGMSTREAM_API uint32_t libvgmstream_get_version(void);
|
||||
|
||||
|
||||
#include "api_version.h"
|
||||
#include "api_decode.h"
|
||||
#include "api_helpers.h"
|
||||
#include "api_streamfile.h"
|
||||
|
25
src/api_version.h
Normal file
25
src/api_version.h
Normal file
@ -0,0 +1,25 @@
|
||||
#ifndef _API_VERSION_H_
|
||||
#define _API_VERSION_H_
|
||||
#include "api.h"
|
||||
#if LIBVGMSTREAM_ENABLE
|
||||
|
||||
/* Current API version.
|
||||
* - only refers to the API itself, as changes related to formats/etc don't alter this (since they are usually additive)
|
||||
* - vgmstream's features are mostly stable, but this API may be tweaked from time to time
|
||||
*/
|
||||
#define LIBVGMSTREAM_API_VERSION_MAJOR 1 // breaking API/ABI changes
|
||||
#define LIBVGMSTREAM_API_VERSION_MINOR 0 // compatible API/ABI changes
|
||||
#define LIBVGMSTREAM_API_VERSION_PATCH 0 // fixes
|
||||
|
||||
/* returns API version in hex format: 0xMMmmpppp = MM-major, mm-minor, pppp-patch
|
||||
* - use when loading vgmstream as a dynamic library to ensure API/ABI compatibility
|
||||
*/
|
||||
LIBVGMSTREAM_API uint32_t libvgmstream_get_version(void);
|
||||
|
||||
/* CHANGELOG:
|
||||
*
|
||||
* - 1.0.0: initial version
|
||||
*/
|
||||
|
||||
#endif
|
||||
#endif
|
@ -92,7 +92,7 @@ static const char* extension_list[] = {
|
||||
"awc",
|
||||
"awd",
|
||||
|
||||
"b1s",
|
||||
"b1s", //txth/reserved [7 Wonders of the Ancient World (PS2)]
|
||||
"baf",
|
||||
"baka",
|
||||
"bank",
|
||||
@ -190,7 +190,6 @@ static const char* extension_list[] = {
|
||||
"fag",
|
||||
"fcb", //FFmpeg/not parsed (BINK AUDIO)
|
||||
"fda",
|
||||
"ffw",
|
||||
"filp",
|
||||
"fish",
|
||||
//"flac", //common
|
||||
@ -1204,7 +1203,6 @@ static const meta_info meta_info_list[] = {
|
||||
{meta_NGC_DSP_MPDS, "MPDS DSP header"},
|
||||
{meta_DSP_STR_IG, "Infogrames .DSP header"},
|
||||
{meta_EA_SWVR, "Electronic Arts SWVR header"},
|
||||
{meta_PS2_B1S, "B1S header"},
|
||||
{meta_DSP_XIII, "XIII dsp header"},
|
||||
{meta_DSP_CABELAS, "Cabelas games .DSP header"},
|
||||
{meta_PS2_ADM, "Dragon Quest V .ADM raw header"},
|
||||
@ -1212,7 +1210,6 @@ static const meta_info meta_info_list[] = {
|
||||
{meta_PS2_VMS, "VMS Header"},
|
||||
{meta_XAU, "XPEC XAU header"},
|
||||
{meta_GH3_BAR, "Guitar Hero III Mobile .bar"},
|
||||
{meta_FFW, "Freedom Fighters BGM header"},
|
||||
{meta_DSP_DSPW, "Capcom DSPW header"},
|
||||
{meta_PS2_JSTM, "JSTM Header"},
|
||||
{meta_XVAG, "Sony XVAG header"},
|
||||
|
@ -85,6 +85,7 @@
|
||||
<ClInclude Include="api_helpers.h" />
|
||||
<ClInclude Include="api_streamfile.h" />
|
||||
<ClInclude Include="api_tags.h" />
|
||||
<ClInclude Include="api_version.h" />
|
||||
<ClInclude Include="streamfile.h" />
|
||||
<ClInclude Include="streamtypes.h" />
|
||||
<ClInclude Include="util.h" />
|
||||
@ -126,6 +127,7 @@
|
||||
<ClInclude Include="meta\adx_keys.h" />
|
||||
<ClInclude Include="meta\ahx_keys.h" />
|
||||
<ClInclude Include="meta\aix_streamfile.h" />
|
||||
<ClInclude Include="meta\apa3_streamfile.h" />
|
||||
<ClInclude Include="meta\awc_decryption_streamfile.h" />
|
||||
<ClInclude Include="meta\awc_streamfile.h" />
|
||||
<ClInclude Include="meta\bar_streamfile.h" />
|
||||
@ -200,7 +202,6 @@
|
||||
<ClInclude Include="util\reader_put.h" />
|
||||
<ClInclude Include="util\reader_sf.h" />
|
||||
<ClInclude Include="util\reader_text.h" />
|
||||
<ClInclude Include="util\samples_ops.h" />
|
||||
<ClInclude Include="util\sf_utils.h" />
|
||||
<ClInclude Include="util\text_reader.h" />
|
||||
<ClInclude Include="util\vgmstream_limits.h" />
|
||||
@ -395,6 +396,7 @@
|
||||
<ClCompile Include="meta\akb.c" />
|
||||
<ClCompile Include="meta\alp.c" />
|
||||
<ClCompile Include="meta\ao.c" />
|
||||
<ClCompile Include="meta\apa3.c" />
|
||||
<ClCompile Include="meta\apc.c" />
|
||||
<ClCompile Include="meta\apple_caff.c" />
|
||||
<ClCompile Include="meta\asd_naxat.c" />
|
||||
@ -404,7 +406,6 @@
|
||||
<ClCompile Include="meta\ast_mmv.c" />
|
||||
<ClCompile Include="meta\ast_mv.c" />
|
||||
<ClCompile Include="meta\atsl.c" />
|
||||
<ClCompile Include="meta\atx.c" />
|
||||
<ClCompile Include="meta\aus.c" />
|
||||
<ClCompile Include="meta\awb.c" />
|
||||
<ClCompile Include="meta\awc.c" />
|
||||
@ -479,7 +480,6 @@
|
||||
<ClCompile Include="meta\fda.c" />
|
||||
<ClCompile Include="meta\ffdl.c" />
|
||||
<ClCompile Include="meta\ffmpeg.c" />
|
||||
<ClCompile Include="meta\ffw.c" />
|
||||
<ClCompile Include="meta\filp.c" />
|
||||
<ClCompile Include="meta\flx.c" />
|
||||
<ClCompile Include="meta\fsb.c" />
|
||||
@ -610,7 +610,6 @@
|
||||
<ClCompile Include="meta\ppst.c" />
|
||||
<ClCompile Include="meta\ps2_adm.c" />
|
||||
<ClCompile Include="meta\ps2_ass.c" />
|
||||
<ClCompile Include="meta\ps2_b1s.c" />
|
||||
<ClCompile Include="meta\ps2_bmdx.c" />
|
||||
<ClCompile Include="meta\ps2_gcm.c" />
|
||||
<ClCompile Include="meta\ps2_hsf.c" />
|
||||
@ -804,7 +803,6 @@
|
||||
<ClCompile Include="util\miniz.c" />
|
||||
<ClCompile Include="util\paths.c" />
|
||||
<ClCompile Include="util\reader.c" />
|
||||
<ClCompile Include="util\samples_ops.c" />
|
||||
<ClCompile Include="util\sf_utils.c" />
|
||||
<ClCompile Include="util\text_reader.c" />
|
||||
</ItemGroup>
|
||||
|
@ -89,6 +89,9 @@
|
||||
<ClInclude Include="api_tags.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="api_version.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="streamfile.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
@ -212,6 +215,9 @@
|
||||
<ClInclude Include="meta\aix_streamfile.h">
|
||||
<Filter>meta\Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="meta\apa3_streamfile.h">
|
||||
<Filter>meta\Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="meta\awc_decryption_streamfile.h">
|
||||
<Filter>meta\Header Files</Filter>
|
||||
</ClInclude>
|
||||
@ -434,9 +440,6 @@
|
||||
<ClInclude Include="util\reader_text.h">
|
||||
<Filter>util\Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="util\samples_ops.h">
|
||||
<Filter>util\Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="util\sf_utils.h">
|
||||
<Filter>util\Header Files</Filter>
|
||||
</ClInclude>
|
||||
@ -1015,6 +1018,9 @@
|
||||
<ClCompile Include="meta\ao.c">
|
||||
<Filter>meta\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="meta\apa3.c">
|
||||
<Filter>meta\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="meta\apc.c">
|
||||
<Filter>meta\Source Files</Filter>
|
||||
</ClCompile>
|
||||
@ -1042,9 +1048,6 @@
|
||||
<ClCompile Include="meta\atsl.c">
|
||||
<Filter>meta\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="meta\atx.c">
|
||||
<Filter>meta\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="meta\aus.c">
|
||||
<Filter>meta\Source Files</Filter>
|
||||
</ClCompile>
|
||||
@ -1267,9 +1270,6 @@
|
||||
<ClCompile Include="meta\ffmpeg.c">
|
||||
<Filter>meta\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="meta\ffw.c">
|
||||
<Filter>meta\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="meta\filp.c">
|
||||
<Filter>meta\Source Files</Filter>
|
||||
</ClCompile>
|
||||
@ -1660,9 +1660,6 @@
|
||||
<ClCompile Include="meta\ps2_ass.c">
|
||||
<Filter>meta\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="meta\ps2_b1s.c">
|
||||
<Filter>meta\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="meta\ps2_bmdx.c">
|
||||
<Filter>meta\Source Files</Filter>
|
||||
</ClCompile>
|
||||
@ -2242,9 +2239,6 @@
|
||||
<ClCompile Include="util\reader.c">
|
||||
<Filter>util\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="util\samples_ops.c">
|
||||
<Filter>util\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="util\sf_utils.c">
|
||||
<Filter>util\Source Files</Filter>
|
||||
</ClCompile>
|
||||
|
195
src/meta/agsc.c
195
src/meta/agsc.c
@ -1,74 +1,145 @@
|
||||
#include "meta.h"
|
||||
#include "../util.h"
|
||||
#include "../coding/coding.h"
|
||||
#include "../util/reader_text.h"
|
||||
#include "../util/meta_utils.h"
|
||||
|
||||
/* .agsc - from Metroid Prime 2 */
|
||||
static bool parse_agsc(meta_header_t* hdr, STREAMFILE* sf, int version);
|
||||
|
||||
VGMSTREAM * init_vgmstream_agsc(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
char filename[PATH_LIMIT];
|
||||
|
||||
off_t header_offset;
|
||||
off_t start_offset;
|
||||
int channel_count;
|
||||
int i;
|
||||
/* .agsc - from Retro Studios games [Metroid Prime (GC), Metroid Prime 2 (GC)] */
|
||||
VGMSTREAM* init_vgmstream_agsc(STREAMFILE* sf) {
|
||||
|
||||
/* check extension, case insensitive */
|
||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||
if (strcasecmp("agsc",filename_extension(filename))) goto fail;
|
||||
/* checks */
|
||||
int version;
|
||||
if (is_id32be(0x00, sf, "Audi"))
|
||||
version = 1;
|
||||
else if (read_u32be(0x00, sf) == 0x00000001)
|
||||
version = 2;
|
||||
else
|
||||
return NULL;
|
||||
|
||||
/* check header */
|
||||
if ((uint32_t)read_32bitBE(0,streamFile)!=0x00000001)
|
||||
goto fail;
|
||||
/* .agsc: 'class' type in .pak */
|
||||
if (!check_extensions(sf, "agsc"))
|
||||
return NULL;
|
||||
|
||||
/* count length of name, including terminating 0 */
|
||||
for (header_offset=4;header_offset < get_streamfile_size(streamFile) && read_8bit(header_offset,streamFile)!='\0';header_offset++);
|
||||
|
||||
header_offset ++;
|
||||
meta_header_t hdr = {0};
|
||||
if (!parse_agsc(&hdr, sf, version))
|
||||
return NULL;
|
||||
|
||||
channel_count = 1;
|
||||
hdr.meta = meta_AGSC;
|
||||
hdr.coding = coding_NGC_DSP;
|
||||
hdr.layout = layout_none;
|
||||
hdr.big_endian = true;
|
||||
hdr.allow_dual_stereo = true;
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
hdr.sf = sf;
|
||||
hdr.open_stream = true;
|
||||
|
||||
vgmstream = allocate_vgmstream(1,1);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
/* fill in the vital statistics */
|
||||
vgmstream->num_samples = read_32bitBE(header_offset+0xda,streamFile);
|
||||
vgmstream->sample_rate = (uint16_t)read_16bitBE(header_offset+0xd8,streamFile);
|
||||
|
||||
vgmstream->loop_start_sample = read_32bitBE(header_offset+0xde,streamFile);
|
||||
/* this is cute, we actually have a "loop length" */
|
||||
vgmstream->loop_end_sample = (vgmstream->loop_start_sample + read_32bitBE(header_offset+0xe2,streamFile))-1;
|
||||
|
||||
vgmstream->coding_type = coding_NGC_DSP;
|
||||
vgmstream->layout_type = layout_none;
|
||||
vgmstream->meta_type = meta_AGSC;
|
||||
vgmstream->allow_dual_stereo = 1;
|
||||
|
||||
for (i=0;i<16;i++) {
|
||||
vgmstream->ch[0].adpcm_coef[i]=read_16bitBE(header_offset+0xf6+i*2,streamFile);
|
||||
}
|
||||
|
||||
start_offset = header_offset+0x116;
|
||||
|
||||
/* open the file for reading by each channel */
|
||||
{
|
||||
int i;
|
||||
for (i=0;i<channel_count;i++) {
|
||||
vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
|
||||
|
||||
if (!vgmstream->ch[i].streamfile) goto fail;
|
||||
|
||||
vgmstream->ch[i].channel_start_offset=
|
||||
vgmstream->ch[i].offset=
|
||||
start_offset;
|
||||
}
|
||||
}
|
||||
|
||||
return vgmstream;
|
||||
|
||||
/* clean up anything we may have opened */
|
||||
fail:
|
||||
if (vgmstream) close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
return alloc_metastream(&hdr);
|
||||
}
|
||||
|
||||
|
||||
static bool parse_agsc(meta_header_t* hdr, STREAMFILE* sf, int version) {
|
||||
uint32_t offset;
|
||||
int name_size;
|
||||
|
||||
switch(version) {
|
||||
case 1:
|
||||
// usually "Audio/" but rarely "Audio//"
|
||||
name_size = read_string(NULL, 0x20, 0x00, sf);
|
||||
if (name_size == 0) // not a string
|
||||
return false;
|
||||
offset = name_size + 1;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
/* after fixed ID */
|
||||
offset = 0x04;
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
/* after id starts with name + null */
|
||||
hdr->name_offset = offset;
|
||||
name_size = read_string(NULL, 0x20, offset, sf);
|
||||
if (name_size == 0) // not a string
|
||||
return false;
|
||||
offset += name_size + 1;
|
||||
|
||||
uint32_t head_offset, data_offset;
|
||||
uint32_t unk1_size, unk2_size, head_size, data_size;
|
||||
switch(version) {
|
||||
case 1:
|
||||
/* per chunk: chunk size + chunk data */
|
||||
unk1_size = read_u32be(offset, sf);
|
||||
offset += 0x04 + unk1_size;
|
||||
|
||||
unk2_size = read_u32be(offset, sf);
|
||||
offset += 0x04 + unk2_size;
|
||||
|
||||
data_offset = offset + 0x04; // data chunk goes before headers...
|
||||
data_size = read_u32be(offset, sf);
|
||||
offset += 0x04 + data_size;
|
||||
|
||||
head_offset = offset + 0x04;
|
||||
head_size = read_u32be(offset, sf);
|
||||
offset += 0x04 + head_size;
|
||||
|
||||
break;
|
||||
|
||||
case 2:
|
||||
/* chunk sizes per chunk + chunk data per chunk */
|
||||
offset += 0x02; // song id?
|
||||
unk1_size = read_u32be(offset + 0x00, sf);
|
||||
unk2_size = read_u32be(offset + 0x04, sf);
|
||||
head_size = read_u32be(offset + 0x08, sf);
|
||||
data_size = read_u32be(offset + 0x0c, sf);
|
||||
|
||||
head_offset = offset + 0x10 + unk1_size + unk2_size;
|
||||
data_offset = head_offset + head_size;
|
||||
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
// offsets/values/data aren't 32b aligned but file is (0xFF padding)
|
||||
|
||||
// possible in some test banks
|
||||
if (data_size == 0 || head_size < 0x20 + 0x28) {
|
||||
vgm_logi("AGSC: bank has no subsongs (ignore)\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* header chunk has 0x20 headers per subsong + 0xFFFFFFFF (end marker) + 0x28 coefs per subsongs,
|
||||
* no apparent count even in other chunks */
|
||||
hdr->total_subsongs = (head_size - 0x04) / (0x20 + 0x28);
|
||||
hdr->target_subsong = sf->stream_index;
|
||||
if (!check_subsongs(&hdr->target_subsong, hdr->total_subsongs))
|
||||
return false;
|
||||
|
||||
uint32_t entry_offset = head_offset + 0x20 * (hdr->target_subsong - 1);
|
||||
|
||||
// 00: id?
|
||||
hdr->stream_offset = read_u32be(entry_offset + 0x04,sf) + data_offset;
|
||||
// 08: null?
|
||||
// 0c: always 0x3c00?
|
||||
hdr->sample_rate = read_u16be(entry_offset + 0x0e,sf);
|
||||
hdr->num_samples = read_s32be(entry_offset + 0x10,sf);
|
||||
hdr->loop_start = read_s32be(entry_offset + 0x14,sf);
|
||||
hdr->loop_end = read_s32be(entry_offset + 0x18,sf); // loop length
|
||||
hdr->coefs_offset = read_s32be(entry_offset + 0x1c,sf);
|
||||
|
||||
if (hdr->loop_end)
|
||||
hdr->loop_end = hdr->loop_end + hdr->loop_start - 1;
|
||||
hdr->loop_flag = hdr->loop_end != 0;
|
||||
|
||||
hdr->coefs_offset += head_offset + 0x08; // skip unknown hist/loop ps-like values
|
||||
|
||||
hdr->channels = 1; // MP2 uses dual stereo for title track
|
||||
hdr->stream_size = hdr->num_samples / 14 * 8 * hdr->channels; // meh
|
||||
|
||||
return true;
|
||||
}
|
||||
|
34
src/meta/apa3.c
Normal file
34
src/meta/apa3.c
Normal file
@ -0,0 +1,34 @@
|
||||
#include "meta.h"
|
||||
#include "../coding/coding.h"
|
||||
#include "apa3_streamfile.h"
|
||||
|
||||
|
||||
/* .ATX - Media.Vision's segmented RIFF AT3 wrapper [Senjo no Valkyria 3 (PSP), Shining Blade (PSP)] */
|
||||
VGMSTREAM* init_vgmstream_apa3(STREAMFILE* sf) {
|
||||
VGMSTREAM* vgmstream = NULL;
|
||||
STREAMFILE* temp_sf = NULL;
|
||||
|
||||
|
||||
/* checks */
|
||||
if (!is_id32be(0x00, sf, "APA3"))
|
||||
return NULL;
|
||||
if (!check_extensions(sf,"atx"))
|
||||
return NULL;
|
||||
|
||||
/* .ATX is made of subfile segments, handled by a custom SF.
|
||||
* Each segment has a header/footer, and part of the full AT3 data
|
||||
* (i.e. ATRAC3 data ends in a subfile and continues in the next) */
|
||||
temp_sf = setup_apa3_streamfile(sf);
|
||||
if (!temp_sf) goto fail;
|
||||
|
||||
vgmstream = init_vgmstream_riff(temp_sf);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
close_streamfile(temp_sf);
|
||||
return vgmstream;
|
||||
|
||||
fail:
|
||||
close_streamfile(temp_sf);
|
||||
close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
81
src/meta/apa3_streamfile.h
Normal file
81
src/meta/apa3_streamfile.h
Normal file
@ -0,0 +1,81 @@
|
||||
#ifndef _APA3_STREAMFILE_H_
|
||||
#define _APA3_STREAMFILE_H_
|
||||
#include "meta.h"
|
||||
|
||||
|
||||
#define ATX_MAX_SEGMENTS 2
|
||||
|
||||
|
||||
static STREAMFILE* setup_apa3_streamfile(STREAMFILE* sf) {
|
||||
STREAMFILE* new_sf = NULL;
|
||||
STREAMFILE* segments_sf[ATX_MAX_SEGMENTS] = {0};
|
||||
char filename[PATH_LIMIT];
|
||||
size_t riff_size;
|
||||
|
||||
|
||||
/* this must be first segment */
|
||||
if (read_u16le(0x1c,sf) != 0)
|
||||
return NULL;
|
||||
int total_segments = read_u16le(0x1e,sf);
|
||||
if (total_segments < 1 || total_segments > ATX_MAX_SEGMENTS)
|
||||
return NULL;
|
||||
|
||||
/* expected segment name: X_XXX_XXX_0n.ATX, starting from n=1 */
|
||||
get_streamfile_filename(sf, filename, PATH_LIMIT);
|
||||
size_t filename_len = strlen(filename);
|
||||
if (filename_len < 7 || filename[filename_len - 5] != '1')
|
||||
return NULL;
|
||||
|
||||
/* setup segments (could avoid reopening first segment but meh) */
|
||||
for (int i = 0; i < total_segments; i++) {
|
||||
off_t subfile_offset;
|
||||
size_t subfile_size;
|
||||
|
||||
filename[filename_len - 5] = ('0' + i + 1); /* digit conversion */
|
||||
|
||||
segments_sf[i] = open_streamfile_by_filename(sf, filename);
|
||||
if (!segments_sf[i]) goto fail;
|
||||
|
||||
if (!is_id32be(0x00, segments_sf[i], "APA3"))
|
||||
goto fail;
|
||||
|
||||
/* parse block/segment header (other Media.Vision's files use it too) */
|
||||
subfile_offset = read_32bitLE(0x08, segments_sf[i]); /* header size */
|
||||
subfile_size = read_32bitLE(0x14, segments_sf[i]); /* can be 0 in other containers */
|
||||
|
||||
if (read_u16le(0x1c,segments_sf[i]) != i)
|
||||
goto fail; /* segment sequence */
|
||||
// 0x04: block size (should match subfile_size in .ATX)
|
||||
// 0x0c: flags? also in other files
|
||||
// 0x10/18: null
|
||||
// 0x1e: total segments
|
||||
|
||||
/* clamp to ignore header/footer during next reads */
|
||||
segments_sf[i] = open_clamp_streamfile_f(segments_sf[i], subfile_offset, subfile_size);
|
||||
if (!segments_sf[i]) goto fail;
|
||||
}
|
||||
|
||||
/* setup with all segments and clamp further using riff_size (last segment has padding) */
|
||||
riff_size = read_32bitLE(read_32bitLE(0x08,sf) + 0x04,sf) + 0x08;
|
||||
|
||||
new_sf = open_multifile_streamfile_f(segments_sf, total_segments);
|
||||
new_sf = open_clamp_streamfile_f(new_sf, 0, riff_size);
|
||||
new_sf = open_fakename_streamfile_f(new_sf, NULL, "at3");
|
||||
|
||||
/* if all this worked we'll have this frankenstein streamfile:
|
||||
* fakename( clamp( multifile( segment0=clamp(standard(FILE)), segment1=clamp(standard(FILE)) ) ) ) */
|
||||
|
||||
return new_sf;
|
||||
fail:
|
||||
if (!new_sf) {
|
||||
for (int i = 0; i < total_segments; i++) {
|
||||
close_streamfile(segments_sf[i]);
|
||||
}
|
||||
} else {
|
||||
close_streamfile(new_sf); /* closes all segments */
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
113
src/meta/atx.c
113
src/meta/atx.c
@ -1,113 +0,0 @@
|
||||
#include "meta.h"
|
||||
#include "../coding/coding.h"
|
||||
|
||||
#define ATX_MAX_SEGMENTS 2
|
||||
|
||||
static STREAMFILE* setup_atx_streamfile(STREAMFILE *streamFile);
|
||||
|
||||
/* .ATX - Media.Vision's segmented RIFF AT3 wrapper [Senjo no Valkyria 3 (PSP), Shining Blade (PSP)] */
|
||||
VGMSTREAM * init_vgmstream_atx(STREAMFILE *streamFile) {
|
||||
VGMSTREAM *vgmstream = NULL;
|
||||
STREAMFILE *temp_streamFile = NULL;
|
||||
|
||||
|
||||
/* check extensions */
|
||||
if ( !check_extensions(streamFile,"atx"))
|
||||
goto fail;
|
||||
if (read_32bitBE(0x00,streamFile) != 0x41504133) /* "APA3" */
|
||||
goto fail;
|
||||
|
||||
/* .ATX is made of subfile segments, handled by the streamFile.
|
||||
* Each segment has a header/footer, and part of the whole data
|
||||
* (i.e. ATRAC3 data ends in a subfile and continues in the next) */
|
||||
temp_streamFile = setup_atx_streamfile(streamFile);
|
||||
if (!temp_streamFile) goto fail;
|
||||
|
||||
vgmstream = init_vgmstream_riff(temp_streamFile);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
close_streamfile(temp_streamFile);
|
||||
return vgmstream;
|
||||
|
||||
fail:
|
||||
close_streamfile(temp_streamFile);
|
||||
close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static STREAMFILE* setup_atx_streamfile(STREAMFILE *streamFile) {
|
||||
STREAMFILE *temp_streamFile = NULL, *new_streamFile = NULL;
|
||||
STREAMFILE *segment_streamFiles[ATX_MAX_SEGMENTS] = {0};
|
||||
char filename[PATH_LIMIT];
|
||||
size_t filename_len;
|
||||
int i, num_segments = 0;
|
||||
size_t riff_size;
|
||||
|
||||
|
||||
if (read_16bitLE(0x1c,streamFile) != 0) goto fail; /* this must be first segment */
|
||||
if (read_16bitLE(0x1e,streamFile) < 1 || read_16bitLE(0x1e,streamFile) > ATX_MAX_SEGMENTS) goto fail;
|
||||
num_segments = read_16bitLE(0x1e,streamFile);
|
||||
|
||||
/* expected segment name: X_XXX_XXX_0n.ATX, starting from n=1 */
|
||||
get_streamfile_filename(streamFile, filename,PATH_LIMIT);
|
||||
filename_len = strlen(filename);
|
||||
if (filename_len < 7 || filename[filename_len - 5] != '1') goto fail;
|
||||
|
||||
/* setup segments (could avoid reopening first segment but meh) */
|
||||
for (i = 0; i < num_segments; i++) {
|
||||
off_t subfile_offset;
|
||||
size_t subfile_size;
|
||||
|
||||
filename[filename_len - 5] = ('0'+i+1); /* ghetto digit conversion */
|
||||
new_streamFile = open_streamfile_by_filename(streamFile, filename);
|
||||
if (!new_streamFile) goto fail;
|
||||
segment_streamFiles[i] = new_streamFile;
|
||||
|
||||
if (read_32bitBE(0x00,segment_streamFiles[i]) != 0x41504133) /* "APA3" */
|
||||
goto fail;
|
||||
|
||||
/* parse block/segment header (other Media.Vision's files use it too) */
|
||||
subfile_offset = read_32bitLE(0x08,segment_streamFiles[i]); /* header size */
|
||||
subfile_size = read_32bitLE(0x14,segment_streamFiles[i]); /* can be 0 in other containers */
|
||||
|
||||
if (read_16bitLE(0x1c,segment_streamFiles[i]) != i)
|
||||
goto fail; /* segment sequence */
|
||||
/* 0x04: block size (should match subfile_size in .ATX) */
|
||||
/* 0x0c: flags? also in other files, 0x10/18: null, 0x1e: segments */
|
||||
|
||||
/* clamp to ignore header/footer during next reads */
|
||||
new_streamFile = open_clamp_streamfile(segment_streamFiles[i], subfile_offset,subfile_size);
|
||||
if (!new_streamFile) goto fail;
|
||||
segment_streamFiles[i] = new_streamFile;
|
||||
}
|
||||
|
||||
/* setup with all segments and clamp further using riff_size (last segment has padding) */
|
||||
riff_size = read_32bitLE(read_32bitLE(0x08,streamFile) + 0x04,streamFile) + 0x08;
|
||||
|
||||
new_streamFile = open_multifile_streamfile(segment_streamFiles, num_segments);
|
||||
if (!new_streamFile) goto fail;
|
||||
temp_streamFile = new_streamFile;
|
||||
|
||||
new_streamFile = open_clamp_streamfile(temp_streamFile, 0,riff_size);
|
||||
if (!new_streamFile) goto fail;
|
||||
temp_streamFile = new_streamFile;
|
||||
|
||||
new_streamFile = open_fakename_streamfile(temp_streamFile, NULL, "at3");
|
||||
if (!new_streamFile) goto fail;
|
||||
temp_streamFile = new_streamFile;
|
||||
|
||||
/* if all this worked we'll have this frankenstein streamfile:
|
||||
* fakename( clamp( multifile( segment0=clamp(standard(FILE)), segment1=clamp(standard(FILE)) ) ) ) */
|
||||
|
||||
return temp_streamFile;
|
||||
|
||||
fail:
|
||||
if (!temp_streamFile) {
|
||||
for (i = 0; i < num_segments; i++) {
|
||||
close_streamfile(segment_streamFiles[i]);
|
||||
}
|
||||
} else {
|
||||
close_streamfile(temp_streamFile); /* closes all segments */
|
||||
}
|
||||
return NULL;
|
||||
}
|
@ -1,64 +0,0 @@
|
||||
#include "meta.h"
|
||||
#include "../util.h"
|
||||
|
||||
/* FFW (from Freedom Fighters [NGC]) */
|
||||
VGMSTREAM * init_vgmstream_ffw(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
char filename[PATH_LIMIT];
|
||||
off_t start_offset;
|
||||
int loop_flag = 0;
|
||||
int channel_count;
|
||||
|
||||
/* check extension, case insensitive */
|
||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||
if (strcasecmp("ffw",filename_extension(filename))) goto fail;
|
||||
|
||||
loop_flag = 0;
|
||||
channel_count = read_32bitLE(0x11C,streamFile);
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
/* fill in the vital statistics */
|
||||
start_offset = 0x130;
|
||||
vgmstream->channels = channel_count;
|
||||
vgmstream->sample_rate = read_32bitLE(0x10C,streamFile);
|
||||
vgmstream->coding_type = coding_PCM16BE;
|
||||
vgmstream->num_samples = (get_streamfile_size(streamFile)-start_offset)/2/channel_count;
|
||||
|
||||
if (channel_count == 1)
|
||||
{
|
||||
vgmstream->layout_type = layout_none;
|
||||
}
|
||||
else
|
||||
{
|
||||
vgmstream->layout_type = layout_interleave;
|
||||
vgmstream->interleave_block_size = 0x10000;
|
||||
}
|
||||
|
||||
vgmstream->meta_type = meta_FFW;
|
||||
|
||||
/* open the file for reading */
|
||||
{
|
||||
int i;
|
||||
STREAMFILE * file;
|
||||
file = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
|
||||
if (!file) goto fail;
|
||||
for (i=0;i<channel_count;i++) {
|
||||
vgmstream->ch[i].streamfile = file;
|
||||
|
||||
vgmstream->ch[i].channel_start_offset=
|
||||
vgmstream->ch[i].offset=start_offset+
|
||||
vgmstream->interleave_block_size*i;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return vgmstream;
|
||||
|
||||
/* clean up anything we may have opened */
|
||||
fail:
|
||||
if (vgmstream) close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
@ -453,8 +453,6 @@ VGMSTREAM * init_vgmstream_ngc_dsp_mpds(STREAMFILE* streamFile);
|
||||
|
||||
VGMSTREAM * init_vgmstream_ea_swvr(STREAMFILE* streamFile);
|
||||
|
||||
VGMSTREAM * init_vgmstream_ps2_b1s(STREAMFILE* streamFile);
|
||||
|
||||
VGMSTREAM * init_vgmstream_ps2_adm(STREAMFILE* streamFile);
|
||||
|
||||
VGMSTREAM* init_vgmstream_lpcm_shade(STREAMFILE* sf);
|
||||
@ -465,8 +463,6 @@ VGMSTREAM * init_vgmstream_xau(STREAMFILE* streamFile);
|
||||
|
||||
VGMSTREAM * init_vgmstream_bar(STREAMFILE* streamFile);
|
||||
|
||||
VGMSTREAM * init_vgmstream_ffw(STREAMFILE* streamFile);
|
||||
|
||||
VGMSTREAM * init_vgmstream_jstm(STREAMFILE* streamFile);
|
||||
|
||||
VGMSTREAM * init_vgmstream_xvag(STREAMFILE* streamFile);
|
||||
@ -690,7 +686,7 @@ VGMSTREAM * init_vgmstream_atsl(STREAMFILE *streamFile);
|
||||
VGMSTREAM * init_vgmstream_sps_n1(STREAMFILE *streamFile);
|
||||
VGMSTREAM * init_vgmstream_sps_n1_segmented(STREAMFILE *streamFile);
|
||||
|
||||
VGMSTREAM * init_vgmstream_atx(STREAMFILE *streamFile);
|
||||
VGMSTREAM* init_vgmstream_apa3(STREAMFILE *streamFile);
|
||||
|
||||
VGMSTREAM * init_vgmstream_sqex_sead(STREAMFILE * streamFile);
|
||||
|
||||
|
@ -1,56 +0,0 @@
|
||||
#include "meta.h"
|
||||
#include "../util.h"
|
||||
|
||||
/* B1S (found in 7 Wonders of the Ancient World) */
|
||||
VGMSTREAM * init_vgmstream_ps2_b1s(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
char filename[PATH_LIMIT];
|
||||
int channel_count;
|
||||
off_t start_offset;
|
||||
|
||||
/* check extension, case insensitive */
|
||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||
if (strcasecmp("b1s",filename_extension(filename))) goto fail;
|
||||
|
||||
if ((read_32bitLE(0x04,streamFile)+0x18) != get_streamfile_size(streamFile))
|
||||
goto fail;
|
||||
|
||||
channel_count = read_32bitLE(0x14,streamFile);
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channel_count,0);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
/* fill in the vital statistics */
|
||||
start_offset = 0x18;
|
||||
vgmstream->channels = channel_count;
|
||||
vgmstream->sample_rate = read_32bitBE(0x10,streamFile);
|
||||
vgmstream->coding_type = coding_PSX;
|
||||
vgmstream->num_samples = read_32bitLE(0x04,streamFile)/16/channel_count*28;
|
||||
vgmstream->layout_type = layout_interleave;
|
||||
vgmstream->interleave_block_size = read_32bitLE(0x0C,streamFile);
|
||||
vgmstream->meta_type = meta_PS2_B1S;
|
||||
|
||||
/* open the file for reading */
|
||||
{
|
||||
int i;
|
||||
STREAMFILE * file;
|
||||
file = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
|
||||
if (!file) goto fail;
|
||||
for (i=0;i<channel_count;i++) {
|
||||
vgmstream->ch[i].streamfile = file;
|
||||
|
||||
vgmstream->ch[i].channel_start_offset=
|
||||
vgmstream->ch[i].offset=start_offset+
|
||||
vgmstream->interleave_block_size*i;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return vgmstream;
|
||||
|
||||
/* clean up anything we may have opened */
|
||||
fail:
|
||||
if (vgmstream) close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
#include "../vgmstream.h"
|
||||
#include "meta_utils.h"
|
||||
#include "reader_text.h"
|
||||
|
||||
|
||||
/* Allocate memory and setup a VGMSTREAM */
|
||||
@ -10,7 +11,7 @@ VGMSTREAM* alloc_metastream(meta_header_t* h) {
|
||||
return NULL;
|
||||
}
|
||||
if (h->num_samples <= 0 || h->num_samples > VGMSTREAM_MAX_NUM_SAMPLES) {
|
||||
VGM_LOG("meta: wrong samples %i\n", h->sample_rate);
|
||||
VGM_LOG("meta: wrong samples %i\n", h->num_samples);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -30,7 +31,10 @@ VGMSTREAM* alloc_metastream(meta_header_t* h) {
|
||||
vgmstream->num_streams = h->total_subsongs;
|
||||
vgmstream->stream_size = h->stream_size;
|
||||
vgmstream->interleave_block_size = h->interleave;
|
||||
vgmstream->allow_dual_stereo = h->allow_dual_stereo;
|
||||
|
||||
if (h->name_offset)
|
||||
read_string(vgmstream->stream_name, sizeof(vgmstream->stream_name), h->name_offset, h->sf ? h->sf : h->sf_head);
|
||||
|
||||
if (h->coding == coding_NGC_DSP && (h->sf || h->sf_head)) {
|
||||
if (h->coefs_offset || h->coefs_spacing)
|
||||
|
@ -39,7 +39,9 @@ typedef struct {
|
||||
uint32_t hists_offset;
|
||||
uint32_t hists_spacing;
|
||||
|
||||
/* optional but can be used for some actions */
|
||||
uint32_t name_offset;
|
||||
|
||||
/* optional but can be used for some actions (such as DSP coefs) */
|
||||
bool big_endian;
|
||||
coding_t coding;
|
||||
layout_t layout;
|
||||
@ -51,6 +53,8 @@ typedef struct {
|
||||
STREAMFILE* sf_body;
|
||||
|
||||
bool open_stream;
|
||||
|
||||
bool allow_dual_stereo;
|
||||
} meta_header_t;
|
||||
|
||||
VGMSTREAM* alloc_metastream(meta_header_t* h);
|
||||
|
@ -1,3 +1,4 @@
|
||||
#include <string.h> // memcpy
|
||||
#include "reader_put.h"
|
||||
#include "reader_text.h"
|
||||
#include "reader_sf.h"
|
||||
@ -31,6 +32,30 @@ void put_u32be(uint8_t* buf, uint32_t v) {
|
||||
buf[3] = (uint8_t)((v >> 0) & 0xFF);
|
||||
}
|
||||
|
||||
void put_s8(uint8_t* buf, int8_t v) {
|
||||
put_u8(buf, v);
|
||||
}
|
||||
|
||||
void put_s16le(uint8_t* buf, int16_t v) {
|
||||
put_u16le(buf, v);
|
||||
}
|
||||
|
||||
void put_s32le(uint8_t* buf, int32_t v) {
|
||||
put_u32le(buf, v);
|
||||
}
|
||||
|
||||
void put_s16be(uint8_t* buf, int16_t v) {
|
||||
put_u16be(buf, v);
|
||||
}
|
||||
|
||||
void put_s32be(uint8_t* buf, int32_t v) {
|
||||
put_u32be(buf, v);
|
||||
}
|
||||
|
||||
void put_data(uint8_t* buf, void* v, int v_size) {
|
||||
memcpy (buf, v, v_size);
|
||||
}
|
||||
|
||||
/* **************************************************** */
|
||||
|
||||
size_t read_line(char* buf, int buf_size, off_t offset, STREAMFILE* sf, int* p_line_ok) {
|
||||
|
@ -9,11 +9,12 @@ void put_u32le(uint8_t* buf, uint32_t v);
|
||||
void put_u16be(uint8_t* buf, uint16_t v);
|
||||
void put_u32be(uint8_t* buf, uint32_t v);
|
||||
|
||||
/* alias of the above */ //TODO: improve
|
||||
#define put_s8 put_u8
|
||||
#define put_s16le put_u16le
|
||||
#define put_s32le put_u32le
|
||||
#define put_s16be put_u16be
|
||||
#define put_s32be put_u32be
|
||||
void put_s8(uint8_t* buf, int8_t v);
|
||||
void put_s16le(uint8_t* buf, int16_t v);
|
||||
void put_s32le(uint8_t* buf, int32_t v);
|
||||
void put_s16be(uint8_t* buf, int16_t v);
|
||||
void put_s32be(uint8_t* buf, int32_t v);
|
||||
|
||||
void put_data(uint8_t* buf, void* v, int v_size);
|
||||
|
||||
#endif
|
||||
|
@ -1,63 +0,0 @@
|
||||
#include "samples_ops.h"
|
||||
|
||||
|
||||
void swap_samples_le(sample_t *buf, int count) {
|
||||
/* Windows can't be BE... I think */
|
||||
#if !defined(_WIN32)
|
||||
#if !defined(__BYTE_ORDER__) || __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__
|
||||
int i;
|
||||
for (i = 0; i < count; i++) {
|
||||
/* 16b sample in memory: aabb where aa=MSB, bb=LSB */
|
||||
uint8_t b0 = buf[i] & 0xff;
|
||||
uint8_t b1 = buf[i] >> 8;
|
||||
uint8_t *p = (uint8_t*)&(buf[i]);
|
||||
/* 16b sample in buffer: bbaa where bb=LSB, aa=MSB */
|
||||
p[0] = b0;
|
||||
p[1] = b1;
|
||||
/* when endianness is LE, buffer has bbaa already so this function can be skipped */
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* unused */
|
||||
/*
|
||||
void interleave_channel(sample_t * outbuffer, sample_t * inbuffer, int32_t sample_count, int channel_count, int channel_number) {
|
||||
int32_t insample,outsample;
|
||||
|
||||
if (channel_count==1) {
|
||||
memcpy(outbuffer,inbuffer,sizeof(sample)*sample_count);
|
||||
return;
|
||||
}
|
||||
|
||||
for (insample=0,outsample=channel_number;insample<sample_count;insample++,outsample+=channel_count) {
|
||||
outbuffer[outsample]=inbuffer[insample];
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/* failed attempt at interleave in place */
|
||||
/*
|
||||
void interleave_stereo(sample_t * buffer, int32_t sample_count) {
|
||||
int32_t tomove, belongs;
|
||||
sample_t moving,temp;
|
||||
|
||||
tomove = sample_count;
|
||||
moving = buffer[tomove];
|
||||
|
||||
do {
|
||||
if (tomove<sample_count)
|
||||
belongs = tomove*2;
|
||||
else
|
||||
belongs = (tomove-sample_count)*2+1;
|
||||
|
||||
temp = buffer[belongs];
|
||||
buffer[belongs] = moving;
|
||||
moving = temp;
|
||||
|
||||
tomove = belongs;
|
||||
} while (tomove != sample_count);
|
||||
}
|
||||
*/
|
||||
|
@ -1,9 +0,0 @@
|
||||
#ifndef _SAMPLES_OPS_H
|
||||
#define _SAMPLES_OPS_H
|
||||
|
||||
#include "../streamtypes.h"
|
||||
|
||||
/* swap samples in machine endianness to little endian (useful to write .wav) */
|
||||
void swap_samples_le(sample_t* buf, int count);
|
||||
|
||||
#endif
|
@ -206,14 +206,12 @@ init_vgmstream_t init_vgmstream_functions[] = {
|
||||
init_vgmstream_ngc_dsp_mpds,
|
||||
init_vgmstream_dsp_str_ig,
|
||||
init_vgmstream_ea_swvr,
|
||||
init_vgmstream_ps2_b1s,
|
||||
init_vgmstream_dsp_xiii,
|
||||
init_vgmstream_dsp_cabelas,
|
||||
init_vgmstream_lpcm_shade,
|
||||
init_vgmstream_ps2_vms,
|
||||
init_vgmstream_xau,
|
||||
init_vgmstream_bar,
|
||||
init_vgmstream_ffw,
|
||||
init_vgmstream_dsp_dspw,
|
||||
init_vgmstream_jstm,
|
||||
init_vgmstream_xvag,
|
||||
@ -335,7 +333,7 @@ init_vgmstream_t init_vgmstream_functions[] = {
|
||||
init_vgmstream_xwc,
|
||||
init_vgmstream_atsl,
|
||||
init_vgmstream_sps_n1,
|
||||
init_vgmstream_atx,
|
||||
init_vgmstream_apa3,
|
||||
init_vgmstream_sqex_sead,
|
||||
init_vgmstream_waf,
|
||||
init_vgmstream_wave,
|
||||
|
@ -471,7 +471,6 @@ typedef enum {
|
||||
meta_NGC_DSP_MPDS, /* Big Air Freestyle, Terminator 3 */
|
||||
meta_DSP_STR_IG, /* Micro Machines, Superman Superman: Shadow of Apokolis */
|
||||
meta_EA_SWVR, /* Future Cop L.A.P.D., Freekstyle */
|
||||
meta_PS2_B1S, /* 7 Wonders of the ancient world */
|
||||
meta_DSP_XIII, /* XIII, possibly more (Ubisoft header???) */
|
||||
meta_DSP_CABELAS, /* Cabelas games */
|
||||
meta_PS2_ADM, /* Dragon Quest V (PS2) */
|
||||
@ -479,7 +478,6 @@ typedef enum {
|
||||
meta_PS2_VMS, /* Autobahn Raser - Police Madness */
|
||||
meta_XAU, /* XPEC Entertainment (Beat Down (PS2 Xbox), Spectral Force Chronicle (PS2)) */
|
||||
meta_GH3_BAR, /* Guitar Hero III Mobile .bar */
|
||||
meta_FFW, /* Freedom Fighters [NGC] */
|
||||
meta_DSP_DSPW, /* Sengoku Basara 3 [WII] */
|
||||
meta_PS2_JSTM, /* Tantei Jinguji Saburo - Kind of Blue (PS2) */
|
||||
meta_SQEX_SCD, /* Square-Enix SCD */
|
||||
|
Loading…
x
Reference in New Issue
Block a user