SOP Format

From ModdingWiki
Jump to navigation Jump to search
SOP Format
Format typeMusic
Notation typeCustom
Max channel count9 or 11 (OPL2), 18 or 20 (OPL3)
Max track count20
Max pattern count1
Max order count0
Tags?File name, Title, Comment, Instrument names

The SOP Format was created by Lee Ho Bum (sopepos) for the Note OPL3 music sequencer.

File format


Data Type Name Description
char[7] signature Header signature (must be "sopepos")
UINT8 majorVersion Major version number (normally 0)
UINT8 minorVersion Minor version number (normally 1)
BYTE padding Unused, must be zero
char[13] fileName File-name / short-name, null-terminated
char[31] title Song-title, null-terminated
UINT8 percussive OPL rhythm mode: 0 = melodic, 1 = percussive
BYTE padding Unused, must be zero
UINT8 tickBeat Number of ticks-per-beat
BYTE padding Unused, must be zero
UINT8 beatMeasure Number of beats-per-measure (normally 4)
UINT8 basicTempo Song-tempo, in beats-per-minute (normally 120)
char[13] comment Comment string, unused
UINT8 nTracks Number of tracks
UINT8 nInsts Number of instruments
BYTE padding Unused, must be zero

The only known version of this format is 0.1.

The fields tickBeat and beatMeasure are used to convert ticks into beats and measures for drawing a musical staff.

The header has a fixed size of 76 bytes, then it is followed by data-structure.

Data structure

The data-structure's size is dynamic, therefore, it varies depending upon the number of tracks and instruments:

Data Type Name Description
BYTE[nTracks] chanMode Channel modes
SOP_INST[nInsts] insts Instruments
SOP_STRK[nTracks] tracks Sequenced tracks
SOP_CTRK ctrlTrack Control track

Each section of the data-structure is described below:

Channel modes

Value Description
0x00 Unused channel
0x01 YMF-262M 4OP Mode
0x02 YM-3812 2OP Mode


The header is followed by the instrument-block. An instrument-structure is repeated nInsts times:

SOP_INST structure:

Data Type Name Description
UINT8 instType Instrument type
char[8] shortName Bank instrument-name / short-name
char[19] longName Long instrument-name
BYTE[] instData Instrument data

An instrument's data-size varies depending upon the instrument's type:

Type Size Description
0 22 Melody (YMF-262M, 4OP Mode)
1 11 Melody (YM-3812, 2OP Mode)
6 11 Bass Drum
7 11 Snare Drum
8 11 Tom Tom
9 11 Cymbal
10 11 Hi-Hat
12 0 Unused instrument (comment)

The actual instrument-data is merely just a dump of the OPL registers:

2OP Mode instrument data

Data Type Name OPL Base Register Description
UINT8 iModChar 0x20 Modulator characteristic
UINT8 iModScale 0x40 Modulator key scaling/output level
UINT8 iModAttack 0x60 Modulator attack/decay level
UINT8 iModSustain 0x80 Modulator sustain/release level
UINT8 iModWaveSel 0xE0 Modulator wave-select
UINT8 iFeedback 0xC0 Feedback/connection
UINT8 iCarChar 0x23 Carrier characteristic (only melody instruments and Bass Drum)
UINT8 iCarScale 0x43 Carrier key scaling/output level (only melody instruments)
UINT8 iCarAttack 0x63 Carrier attack/decay level (only melody instruments)
UINT8 iCarSustain 0x83 Carrier sustain/release level (only melody instruments)
UINT8 iCarWaveSel 0xE3 Carrier wave-select (only melody instruments)

4OP Mode instrument data

Data Type Name OPL Base Register Description
UINT8 iOp1Char 0x20 Operator 1 characteristic
UINT8 iOp1Scale 0x40 Operator 1 key scaling/output level
UINT8 iOp1Attack 0x60 Operator 1 attack/decay level
UINT8 iOp1Sustain 0x80 Operator 1 sustain/release level
UINT8 iOp1WaveSel 0xE0 Operator 1 wave-select
UINT8 iOp1Feedback 0xC0 Operator 1 feedback/connection
UINT8 iOp2Char 0x23 Operator 2 characteristic
UINT8 iOp2Scale 0x43 Operator 2 key scaling/output level
UINT8 iOp2Attack 0x63 Operator 2 attack/decay level
UINT8 iOp2Sustain 0x83 Operator 2 sustain/release level
UINT8 iOp2WaveSel 0xE3 Operator 2 wave-select
UINT8 iOp3Char 0x28 Operator 3 characteristic
UINT8 iOp3Scale 0x48 Operator 3 key scaling/output level
UINT8 iOp3Attack 0x68 Operator 3 attack/decay level
UINT8 iOp3Sustain 0x88 Operator 3 sustain/release level
UINT8 iOp3WaveSel 0xE8 Operator 3 wave-select
UINT8 iOp3Feedback 0xC8 Operator 3 feedback/connection
UINT8 iOp4Char 0x2B Operator 4 characteristic
UINT8 iOp4Scale 0x4B Operator 4 key scaling/output level
UINT8 iOp4Attack 0x6B Operator 4 attack/decay level
UINT8 iOp4Sustain 0x8B Operator 4 sustain/release level
UINT8 iOp4WaveSel 0xEB Operator 4 wave-select

Sequenced tracks

The instrument-block is followed by all sequenced tracks, which contain the music's events:

SOP_STRK structure:

Data Type Name Description
UINT16LE numEvents Number of events in track
UINT32LE dataSize Track's data-size, in bytes
SOP_EVNT[numEvents] events Track events

SOP_EVNT structure:

Data Type Name Description
UINT16LE ticks Delta-ticks (change position)
UINT8 event Event code
SOP_EVAL value Event structure

SOP_EVAL structure varies depending upon the event-code value:

Event Code Description Event Structure
Special Event UINT8 value
Note On UINT8 pitch, UINT16LE length (in ticks)
Change Volume UINT8 volume
Change Pitch UINT8 pitch (0x64 (100) is a center value)
Instrument Change UINT8 number
Set Panning UINT8 panning (0 - right, 1 - middle, 2 - left)

Special Event

This event has no effect on normal playback.

Pitch Change

The pitch is a signed char type with a value between -100 and +100. The actual pitch setting is the pitch of the current note plus the frequency of the next note in octave (or previous note, if value is negative). Its combined value can be calculated as a percentage. That is, when the pitch is +50 and the current frequency is 153, and if the next note frequency is 163, then, the actual output frequency can be calculated like this:

153 + (163-153) * 50/100 = 158

Control track

The last block in a SOP file is the control-track. It is used to control global playback parameters.

SOP_CTRK structure is similar to SOP_STRK:

Data Type Name Description
UINT16LE numEvents Number of control-events in track
UINT32LE dataSize Control-track data-size, in bytes
SOP_CEVT[numEvents] events Control-track events

SOP_CEVT structure:

Data Type Name Description
UINT16LE ticks Delta-ticks (change position)
UINT8 event Control-event code
SOP_CVAL value Control-event structure

SOP_CVAL structure varies depending upon the control-event code value:

Event Code Description Event Structure
Change Tempo UINT8 bpm
Global Volume UINT8 volume

Change Tempo

This event updates the tempo value. If it was not set before, then, it defaults to the basicTempo value, however, the official Note editor overrides that default value with 120.

The frequency is calculated with this formula:

frequency = bpm * tickBeat / 60


The following tools are able to work with files in this format.

Name PlatformPlay? Create new? Modify? Convert/export to other? Import from other? Access hidden data? Edit metadata? Notes
Note DOSYesYesYesNoYes; .imsNoYes Official player and editor
SOP Play Windows 9xYesNoNoNoNoNoNo Uses direct output to OPL chip
Testing SOP DOSYesNoNoNoNoNoNo Open-source player
Grassman software IMS/ROL/SOP Player Windows/WinampYesNoNoNoNoNoNo Uses emulated output

See also


This file format was described by Park Jeenhong in 1996 and then adapted and supplemented by binarymaster. If you find this information helpful in a project you're working on, please give credit where credit is due. (A link back to this wiki would be nice too!)