Coder Social home page Coder Social logo

shinen-gax-python's Introduction

Shin'en GAX Sound Engine tools for Python

This repo houses conversion and (un)packing tools for music and FX files made with Shin'en Multimedia's GAX Sound Engine library.
This also works with .gax/.o files made with NAX Sound Engine, which uses the same data structure as GAX.
Since this is a complete rewrite, some things in the original repo (i.e XM to GAX) are nonexistent, but this doesn't mean I won't implement them in the future.

Tools:

  • Gaxripper (v2) - A command line tool to rip and reconstruct GAX Sound Engine music data from Game Boy Advance ROMs.
    This tool, like the GAX library script itself, is meant for GAX Sound Engine v3.05+, but I have seen it work with games using GAX v3.02 (albeit with a bit of internal fudging since the script was designed for v3.05 in mind)

  • Waveform dumper - Allows one to dump sample data (internally referred to as waveforms) from .nax/.o files.
    For right now these are saved as .raw 8-bit unsigned files, not .wav or any typical audio format.

  • Furnace clipboard converter - This converts the GAX pattern data in a .nax/.o file into the clipboard format used by tildearrow's Furnace.

  • Header reconstructor - This decompiles/reconstructs a C/C++ header file (music.h) from the GAX music data in a Game Boy Advance ROM. This isn't really useful right now since there's no ELF object recompiler for either the music or FX data (yet).

  • GAX library detection - Detects the GAX Sound Engine library (+ functions from libgax.a) in a Game Boy Advance ROM.

To do:

  • Implement the export of GAX sound effects
  • Proper support for earlier revisions of GAX v3. v3.02 technically works but it is not explicitly supported.
  • Implement GAX 1 and 2 support. There are some major differences, like the lack of an FX mixing rate and different instrument formatting.
  • Implement .ELF file reconstruction for GBA decompilation projects.

Credits:

Bernhard Wodok, Shin'en Multimedia - original sound engine

loveemu - Documentation of GAX's format and gax_scanner.py

nikku4211 - Additional documentation of GAX's sequence data format (used as a jump-off point for my own research)

shinen-gax-python's People

Contributors

beanieaxolotl avatar

Stargazers

Dr. RNG avatar  avatar

Watchers

 avatar

shinen-gax-python's Issues

RLE compression of pattern data doesn't work

Due to a few refactors in the packing script, the RLE compression does not work.
This results in the song data being larger than it should be.

I have compared the music data stream of "song_12" from Madagascar between both the original ROM file and the script's output, and I think I know why this happened. The empty patterns are likely not being caught by the pattern compressor as it should, resulting in the hilariously-bloated output I get.

image

Note off command types and their unpacking conditions are inaccurate

I first assumed that 0x80 is an empty step, and 0x81 to be a note off command. This worked most of the time, but when a note off is paired with a effect command, this gets interpreted as a note with a semitone of 1 instead. I have noticed this in a few tracks, one being the main menu BGM from Drake & Josh:

image

Songs without a name can't be ripped

This specifically affects Harry Potter - Quidditch World Cup (U), since the only song in the ROM is internally referred to as:

"" © Manfred Linzner

I should probably code in a fail-safe handler for this: This code should ignore the song's name if it is empty, and only set the AUTH tag if possible.

NAX Support

Did this program support NAX sound driver which used only in Crash Nitro Kart and Payload for N-GAGE? I'm looking for HQ rip of Payload which sounds too compressed.

Repacked output is missing the last sample/waveform's pointer

I'm using my dumped copy of The Adventures of Jimmy Neutron Boy Genius: Attack of the Twonkies to generate a repacked file for this one, and I am certain this pops up in all of my test repacks as well.

All samples/waveforms are saved, and all but one of the waveforms has a corresponding pointer assigned.

image

This means that when the waveform bank is unpacked from the repacked output, one waveform is missing (that being the cymbal crash). Attempting to index this missing waveform in my WIP GAX instrument code throws an error.

SpongeBob SquarePants Movie, The (USA) (Beta) unpacking error

When trying to finish up unpacking the song data from the ROM, Gaxripper v2 attempts to obtain a 36-byte struct from ROM address 0x868d958 and promptly errors out with this:

struct.error: unpack_from requires a buffer of at least 6871420 bytes for unpacking 36 bytes at offset 6871384 (actual buffer size is 6871418)

The Powerpuff Girls : Him and Seek (USA) ~ Loads but can't be unpacked

The game uses GAX Sound Engine 3.0 (Jul 16 2002), so I'm not really surprised that this almost works, but fails.

When unpacking the GAX song data in order to create a .gax file, The program errors out due to it trying to get a perf list pointer from an empty instrument.

Traceback (most recent call last):
  File "C:\Users\User\....\Gaxripper v2.py", line 163, in <module>
    gax_object = gax.unpackGAXFromROM(song_settings, gba_rom)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\User\....\libs\shinen_gax.py", line 1039, in unpackGAXFromROM
    instrument_object = instrument(rom, pointer, is_gax_gba = True)
                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\User\....\libs\shinen_gax.py", line 584, in __init__
    perflist_struct = struct.unpack_from('<B?Bx4B', data, offset)
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
struct.error: unpack_from requires a buffer of at least 134217736 bytes for unpacking 8 bytes at offset 134217728 (actual buffer size is 8388608)

Reverb settings need to be implemented

So far I have seen uses for this in Iridion 2 myself, and heard uses of it in the compositions done by Manfred Linzner (Dexter's Laboratory, the GAX demos in Maya the Bee 1, The iconic Shin'en jingle at the start of Iridion 2, etc.)

Judging by the GHX2 editor screenshot, this is a boolean set for each channel, and each channel has its own parameters.

This type of reverb is defined in GAX internally as GAXReverb, and takes in 2 unsigned dwords: the reverb's delay, and the reverb's decay. I may have to double-check if this is indeed the same reverb used for the per-channel reverb settings, and if this is still implemented in GAX v3+ in mostly the same manner as GAX v2 and/or below.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.