Skip to content

Commit

Permalink
Merge pull request vgmstream#1410 from bnnm/adx-bnk
Browse files Browse the repository at this point in the history
- Adjust ADX decoding for v04 files
- Add .xai XA [Quake II (PS1)]
- Fix some .bnk versions [The Last of Us (PC)]
- Add .gmd extension [High Voltage games]
  • Loading branch information
bnnm authored Aug 26, 2023
2 parents a3a4990 + 3784307 commit 8e488cf
Show file tree
Hide file tree
Showing 11 changed files with 935 additions and 686 deletions.
2 changes: 1 addition & 1 deletion doc/BUILD-LIB.md
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ Some `libatrac9.vcxproj` x64 config may be outdated. In MSBuild +15 (VS +2017) y
```


### libvorbis
### libvorbis/libogg
Should be buildable with *autotools* (Git releases need to use `autogen.sh` first) or MSVC (projects in `./win32/`, may not be up to date). *CMake* may work as well.

Methods below create 3 DLL: `libogg.dll`, `libvorbis.dll` and `libvorbisfile.dll` (also `libvorbisenc.dll`, unneeded), plus static libs (`.a`). However Vorbis/Ogg DLL support in vgmstream was originally added using a combined DLL from *RareWares* (https://www.rarewares.org/ogg-libraries.php) simply called `libvorbis.dll`, so separate DLLs can't be used at the moment and we'll need to fix that.
Expand Down
4 changes: 2 additions & 2 deletions doc/BUILD.md
Original file line number Diff line number Diff line change
Expand Up @@ -487,15 +487,15 @@ They are compiled in their own sources, and the resulting binary is linked by vg

Currently vgmstream's repository contains pre-compiled external DLL libraries for **Windows**, while other systems link to system libraries or include static copies using CMake.

### libvorbis
### libvorbis/libogg
Adds support for Vorbis, inside Ogg as `.ogg` (plain or encrypted) or custom variations like `.wem`, `.fsb`, `.ogl`, etc.
- Sources:
- http://downloads.xiph.org/releases/vorbis/libvorbis-1.3.7.zip (for base vorbis decoding)
- http://downloads.xiph.org/releases/ogg/libogg-1.3.5.zip (for ogg support)
- Official Windows binaries: none
- Commonly used compilations: https://www.rarewares.org/ogg-libraries.php (32-bit only, fusing libogg+libvorbis+libvorbisfile)
- Version: 1.3.7
- DLL: `libvorbis.dll`
- DLL: `libvorbis.dll` (includes `libogg` + `libvorbis` + `libvorbisfile` for historical reasons)
- lib: `-lvorbis -lvorbisfile`
- licensed under the 3-clause BSD license

Expand Down
3 changes: 2 additions & 1 deletion doc/FORMATS.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ different internally (encrypted, different versions, etc) and not always can be
- Codecs: PSX
- **xa.c**
- Sony XA header [*XA*]
- *xa*: `.xa .str .pxa .grn .an2 .(extensionless)`
- *xa*: `.xa .str .pxa .grn .an2 .(extensionless) .xai`
- Codecs: XA8 XA
- **rxws.c**
- Sony RXWS header [*RXWS*]
Expand Down Expand Up @@ -1301,6 +1301,7 @@ different internally (encrypted, different versions, etc) and not always can be
- **bnk_sony.c**
- Sony BNK header [*BNK_SONY*]
- *bnk_sony*: `.bnk`
- Subfiles: *riff*
- Codecs: ATRAC9 PCM16BE PCM16LE PSX HEVAG
- **nus3bank.c**
- (container)
Expand Down
2 changes: 1 addition & 1 deletion src/base/decode.c
Original file line number Diff line number Diff line change
Expand Up @@ -790,7 +790,7 @@ void decode_vgmstream(VGMSTREAM* vgmstream, int samples_written, int samples_to_
for (ch = 0; ch < vgmstream->channels; ch++) {
decode_adx(&vgmstream->ch[ch], buffer+ch,
vgmstream->channels, vgmstream->samples_into_block, samples_to_do,
vgmstream->interleave_block_size, vgmstream->coding_type);
vgmstream->interleave_block_size, vgmstream->coding_type, vgmstream->codec_config);
}
break;
case coding_NGC_DSP:
Expand Down
13 changes: 10 additions & 3 deletions src/coding/adx_decoder.c
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
#include "coding.h"
#include "../util.h"

void decode_adx(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int32_t frame_size, coding_t coding_type) {
void decode_adx(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int32_t frame_size, coding_t coding_type, uint32_t codec_config) {
uint8_t frame[0x12] = {0};
off_t frame_offset;
int i, frames_in, sample_count = 0;
size_t bytes_per_frame, samples_per_frame;
int scale, coef1, coef2;
int32_t hist1 = stream->adpcm_history1_32;
int32_t hist2 = stream->adpcm_history2_32;
int version = codec_config;


/* external interleave (fixed size), mono */
Expand Down Expand Up @@ -50,7 +51,7 @@ void decode_adx(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing,
break;
case coding_CRI_ADX_enc_8:
case coding_CRI_ADX_enc_9:
scale = ((scale ^ stream->adx_xor) & 0x1fff) + 1;
scale = ((scale ^ stream->adx_xor) & 0x1fff) + 1; /* this seems to be used even in unencrypted ADX (compatible) */
coef1 = stream->adpcm_coef[0];
coef2 = stream->adpcm_coef[1];
break;
Expand All @@ -69,7 +70,13 @@ void decode_adx(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing,
sample = i&1 ? /* high nibble first */
get_low_nibble_signed(nibbles):
get_high_nibble_signed(nibbles);
sample = sample * scale + (coef1 * hist1 >> 12) + (coef2 * hist2 >> 12);

/* Early (v3 ADX only) libs decode slightly differently (quieter?), while later libs (v4 ADX) tweaked it. V4 libs playing v3 files
* seem to behave like V4 though, so it's not detectable but not that common (ex. ports of old games reusing v3 ADX) */
if (version == 0x0300)
sample = sample * scale + ((coef1 * hist1) >> 12) + ((coef2 * hist2) >> 12); /* V3 lib */
else
sample = sample * scale + ((coef1 * hist1 + coef2 * hist2) >> 12); /* V4 lib */
sample = clamp16(sample);

outbuf[sample_count] = sample;
Expand Down
2 changes: 1 addition & 1 deletion src/coding/coding.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
#include "hca_decoder_clhca.h"

/* adx_decoder */
void decode_adx(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int32_t frame_bytes, coding_t coding_type);
void decode_adx(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int32_t frame_bytes, coding_t coding_type, uint32_t codec_config);
void adx_next_key(VGMSTREAMCHANNEL* stream);


Expand Down
2 changes: 2 additions & 0 deletions src/formats.c
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@ static const char* extension_list[] = {
"gcw",
"genh",
"gin",
"gmd", //txth/semi [High Voltage games: Charlie and the Chocolate Factory (GC), Zathura (GC)]
"gms",
"grn",
"gsf",
Expand Down Expand Up @@ -649,6 +650,7 @@ static const char* extension_list[] = {
"xa",
"xa2",
"xa30",
"xai",
"xag", //txth/reserved [Tamsoft's PS2 games]
"xau",
"xav",
Expand Down
1 change: 1 addition & 0 deletions src/meta/adx.c
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ VGMSTREAM* init_vgmstream_adx_subkey(STREAMFILE* sf, uint16_t subkey) {
vgmstream->loop_start_sample = loop_start_sample;
vgmstream->loop_end_sample = loop_end_sample;

vgmstream->codec_config = version;
vgmstream->coding_type = coding_type;
vgmstream->layout_type = layout_interleave;
vgmstream->interleave_block_size = frame_size;
Expand Down
Loading

0 comments on commit 8e488cf

Please sign in to comment.