Lovely 2SF Ripping Guide

This document explains how to rip a DS game to 2SF.

If you are going to rip a game that uses standard DS sound format (SDAT), you do not need to read this guide. You can use VGMToolbox to convert directly DS ROM to 2SF. I also recommend you to create NCSF instead of 2SF.

If it's not the case, it requires a manual ripping.

There is a 2SF ripping guide by unknownfile. However, since it is quite old, it is written for old 2SF format, and some tools in the guide cannot be downloaded today. As far as I know, it was the only guide for manual 2SF ripping, unfortunately. This is why I decided to write this guide, even though I am not very familiar with DS architectures.

I hope it helps you to create a new 2SF.


You need to have a knowledge of some technical things:

In this tutorial, I will use the following tools.

  • no$gba debugger version: High functionality emulator/debugger for GBA/NDS games.
  • DeSmuME: One of the best NDS emulator (I always use it for casual use). It is open-source and has some good debugger features, since it is a standard DS emulator for tool-assisted speedrun community. I sometimes use it for RAM search, memory viewer and Lua scripting.
  • IDA Pro: User-friendly disassembler. This is not a mandatory tool for 2SF ripping (no$gba will help you enough), but it's one of the best tools for every PSF ripping.
  • Tinke: Viewer and editor for files of NDS games. I use it to view ROM header and explore the NitroFS filesystem.
  • Hex editor: Everyone needs it for reverse-engineering work, right? I am using 010 Editor, but you can choose a different good free editor.

The whole strategy for 2SF ripping is quite similar to my generic PSF ripping strategy.

Loading NDS ROM

DS hardware has a two CPUs, ARM946E-S and ARM7TDMI. ARM9 is a main CPU, and ARM7TDMI is a sub CPU that is usually used for sound processing.

Therefore, a DS game has two entrypoints and code sections, and they correspond to ARM9 and ARM7TDMI. Usually, they will be loaded into a different address of the same main RAM (0x2xxxxxx). The entrypoint addresses are recorded in ROM header. You can view it by Tinke, or any other header tools.

To load a ROM into IDA Pro, there are several methods.

  • Use Nintendo DS loader module for IDA Pro.
  • Load the ROM in DeSmuME, and export whole main RAM data into a file (use View Memory), and load it into IDA Pro as ARM code.
    1. Choose ARM processor, and press OK
    2. Create 0x400000 bytes RAM segment at 0x2000000, and load the file into 0x2000000
    3. Move to ARM9 entrypoint (usually 0x2008000), set the processor mode to ARM (press Alt+G and set T = 0x0), and press C key

Music playback request is usually demanded by ARM9, so we will start exploring the ARM9 code, and we will not see the ARM7 code.

Also, you should view the filesystem and guess sound data is stored into what file.

Locating The Sound Select

Find a function to select a song and start playback. As I explained in my generic PSF ripping strategy guide, I often do it by backtracing the access to the score data pointer.

  1. Find a score data pointer address by DeSmuME's RAM search
  2. Back to no$gba, then set write breakpoint to the address (something like [2012345]!!)
  3. Repeat backtracing by "Run to Sub-Return" and find the target function

However, DS game has a build-in filesystem. So it often can be find by searching filenames. (See "Names" list if you are using IDA Pro) The following two methods are quoted from unknownfile's guide.

SOUND SELECT STYLE 1: sprintf (Doki Doki Majou Shinpan's CRI ADX driver)

This game uses an algorithm to use a sprintf call before playing the ADX files. The sprintf values are thus:

RAM:020BF780 aSBgm_DD_adx    DCB "%s/BGM_%d%d.adx",0 ; DATA XREF: RAM:off_207E568
RAM:020BF790 a_dataSoundBgm  DCB "_Data/Sound/Bgm",0 ; DATA XREF: RAM:off_207E56C

At this point, we trace back to the calling function and we get this:

RAM:0207E534                 SUB     LR, R4, R0
RAM:0207E538                 LDR     R1, =aSBgm_DD_adx
RAM:0207E53C                 LDR     R2, =a_dataSoundBgm
RAM:0207E540                 ADD     R0, SP, #0x50+var_4C
RAM:0207E544                 STR     LR, [SP,#0x50+var_50]
RAM:0207E548                 ADD     R3, R12, R3,ASR#2
RAM:0207E54C                 BL      sub_20118C4

The strings are loaded to R1 and R2, and the sound digit is loaded into R4. Therefore, we write the song value to R4.

SOUND SELECT STYLE 2: Register holds the sound value (Generic driver, Super Princess Peach)

Games using this sound select style are harder to rip as there is no obvious way to identify where the sound register is actually given to the engine. A good place to start is to place breakpoints in functions following an initialization function which is obvious to locate (generic driver games all use a call to load a file such as sound_data.sdat).

A typical generic driver sound select looks like this:

ROM:02060BB8                 STMFD   SP!, {R4,R5,LR}
ROM:02060BBC                 SUB     SP, SP, #0xC
ROM:02060BC0                 MOV     R4, R1
ROM:02060BC4                 MOV     R5, R0
ROM:02060BC8                 MOV     R0, R4
ROM:02060BCC                 BL      sub_205F8D8

r1 goes to r4, r0 goes to r5, and r4 goes to r0. In this case, we could use r1 on 0x02060BB8, or r0 on 0x02060BCC.

In other cases, the sound select value requires you to trace back and keep inserting values into a register until the music changes. Super Princess Peach and Yoshi's Island DS required me to go looking a bit before finding the register.

Locate Driver Code to main

You can test the function by the following steps:

  1. Set a breakpoint just before the function call
  2. Edit the arguments (register or RAM value)
  3. Listen whether it changes the song (try another function or parameter if it doesn't)

After finding the sound select function, you need to test it.

no$gba can change the ARM instructions during the emulation. Put a small driver code in the middle of main function (say, a noreturn function called by the startup function), and reset the game.

The driver code can be something like the following.

mov   r0, #1            ; song index
mov   r1, #0            ; do not forget to set other required arguments
mov   r2, #0x100
bl    #0x20034568       ; call the sound select

infinite_loop:          ; stop the main thread (music playback should be processed by interrupts)
swi   4
b     infinite_loop

Congratulations! It starts playing the music and stays in blank screen! If not, try to put the driver code in another address.

Save the change to ROM file by using a hex editor. no$gba is good for quick check, but it probably does not have a function to save altered ROM.

Minimize Initialization

Fill each bl #0xXXXXXXXX instructions with NOP, and test whether it affect to music playback. Remove all unwanted instructions out by repeating the above steps. It may take a time, but please be patient.

Convert ROM into 2SF

It's time to convert the ROM to 2SF.

  1. Convert the altered ROM file into 2sflib by rom2sf utility
  2. Make a number of mini2sf files by mini2sf utility

Optimizing the 2SF

Unfortunately, we do not have a handy tool like gsfopt yet. Therefore I cannot optimize a 2SF set yet.

I hope someone make a optimization tool based on vio2sf or something like that.

PlayStation (PS1) Dragon Quest VII and IV Music Format (SEQQ)

Dragon Quest VII and IV (DQ7/DQ4) do not use the generic SEQ/VAB driver. Both games are developed by Heart Beat and use the same custom driver (there could be some minor differences, as usual).

. Dragon Quest Monsters does not use SEQq because the game is probably developed by Enix and Tose, not Heart Beat.)). It is very similar to Generic SEQ, however, it is slightly different.


PSX Dragon Quest games have a single large archive in CD, which is named like HBD1PS1D.Q71 (note that it is a hidden file). A lot of virtual files (music data included) are stored in this file.

A sound file can have both wave banks and sequence at the same time. However, to share wave banks with multiple songs, the game seems to have a file for banks and files for sequences separately.

Offset Size Description
0x00 60 Sound format header
0x3c variable VB and regions
- variable SEQ entry

Sound Format Header

A sound file has a 60 bytes header at the beginning.

Offset Size Description
0x00 4 SEQ size (could be 0)
0x04 2 SEQ id (msq_id)
0x06 1 Wave bank count (usually 4)
0x07 1 Unknown (usually 0 for BGM?)
0x08 4 Unknown
0x0c 4 Wave bank #1 - size of VB (if 0, use preloaded bank)
0x10 4 Wave bank #1 - size of regions
0x14 2 Wave bank #1 - id/index?
0x16 2 Wave bank #1 - ?
0x18 12 Wave bank #2 - same as above
0x24 12 Wave bank #3 - same as above
0x30 12 Wave bank #4 - same as above

Sequence Data

SEQq is a sequence format for those games. It looks very similar to Generic SEQ, however, it is slightly different.

I've made a simple converter for SEQq, seqq2mid. Check it out if you want.

You can rip sequences by using bin2seq.

SEQq Header
Name Size Description
ID 4 bytes Signature: "qQES"
Version? 2 bytes 0
SEQ number? 2 bytes For instance, 0x1001
Resolution of quarter note 2 bytes TPQN
Tempo 3 bytes Tempo (length of quarter note in microseconds)
Rhythm (Numerator) 1 byte Numerator of time signature (n)
Rhythm (Denominator) 1 byte Denominator of time signature (2n)
Number of channels 1 byte Number of channels used in the sequence
Control Change

It has more control changes than SEQ.

  • 1
  • 2, 11
  • 4
  • 5
  • 6
  • 7
  • 9
  • 10
  • 20
  • 21
  • 22
  • 23
  • 32
  • 52
  • 53
  • 54
  • 55
  • 56
  • 64
  • 69
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 91
  • 92
  • 98
  • 99
  • 121
  • 126
  • 127
Meta Event

Unlike SEQ, SEQq has data length.

End Marker

SEQ ends with a meta event, "delta-time FF 2F". On the other hand, SEQq ends with "FF 2F 00", without delta-time!

My Generic PSF (Portable Sound Format: PSF1, GSF) Ripping Strategy

Here I introduce my PSF ripping method.

日本語に翻訳する (Yahoo) 日本語に翻訳する (Google)


I assume you already know about the following things:

  • What is PSF? - A format for video game music rips. In most cases, a PSF is a compressed game ROM whose non-sound stuff is removed by ripper.
  • "Streamed?" "Sequenced?" What's the difference? etc. - Read PSF Frequently Asked Questions - Neill Corlett's Home Page
  • What is pointer? - For this purpose, I recommend you to learn C.
  • Do I need to learn assembly? - At least you need to know basics. (for example: "What is a register?" "What is a stack?") If you already know one of assemblies, I think you can solve your problems during ripping by pinpoint googling.


  • Emulator (Debugger) - such as no$psx or no$gba debugger
    • It must have step execution function. (Step Into, Step Over, Run To Return)
    • It definitely should have a function that can change instructions by using assembly.
    • It should change register value. (If not available, use an external tool such as MHS.)
  • IDA Pro - it will help you in reading assembly a lot. See also: IDA Pro - How To Load Game ROM
  • Memory Scanner - such as Memory Hacking Software (MHS) or Cheat Engine.
    • This tool is optional. It is handy when the emulator does not have built-in RAM search function.
    • It can be used to set a memory breakpoint, when the emulator does not have a memory breakpoint feature. (thankfully, nocash debuggers has the feature)

Typical structure of unaltered game

I think a game has routines like the following typically:


IDA Pro - How To Load Game ROM

Example Of Sequenced VGM Analysis: PS1 Hokuto no Ken

Have you read How to Analyze Sequenced Video Game Music? This article is an actual example of it.

Note that this is a sort of platform-independent tip. Here I analyze sequences without disassembly.



How to Analyze Sequenced Video Game Music

This document introduces my generic analysis method for sequenced video game music. I hope this will help your research.



The following knowledge is necessary to understand this document.

  • Bit, byte, endianness
  • Decimal number, hexadecimal number (hex), two's complement
  • Basic knowledge about MIDI
    • How to view/create a MIDI file by using MIDI editor/sequencer
    • Concept of a track and a channel

The following knowledge is not a must, but it will help you to understand this document more deeply.

  • Specification of Standard MIDI File (SMF)
  • Hardware specification of the target platform (console, handheld)
    • Especially, it is good to know what plays a sound, and how to play a sound.
  • Experience of programming language (for instance, C) and assembly
    • This document does not require code analysis, but they will definitely help you to imagine the background of the music driver.
  • Debugger tools
  • Compression algorithms (such as RLE or LZSS)

My Favorite Tools For Video Game Music Analysis

This article shows what I use/know in my VGM analysis work.


If you know a good tool, let me know, please. :)