SOP Format
Format type | Music |
---|---|
Notation type | Custom |
Instruments | OPL |
Max channel count | 9 or 11 (OPL2), 18 or 20 (OPL3) |
Max track count | 20 |
Max pattern count | 1 |
Max order count | 0 |
Tags? | File name, Title, Comment, Instrument names |
Games | None |
The SOP Format was created by Lee Ho Bum (sopepos) for the Note OPL3 music sequencer.
File format
Header
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 |
Instruments
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
Tools
The following tools are able to work with files in this format.
Name | Platform | Play? | Create new? | Modify? | Convert/export to other? | Import from other? | Access hidden data? | Edit metadata? | Notes |
---|---|---|---|---|---|---|---|---|---|
Note | DOS | Yes | Yes | Yes | No | Yes; .ims | No | Yes | Official player and editor |
SOP Play | Windows 9x | Yes | No | No | No | No | No | No | Uses direct output to OPL chip |
Testing SOP | DOS | Yes | No | No | No | No | No | No | Open-source player |
Grassman software IMS/ROL/SOP Player | Windows/Winamp | Yes | No | No | No | No | No | No | Uses emulated output |
See also
- http://www.vogons.org/viewtopic.php?f=5&t=37849 - topic on VOGONS
- https://adplug.github.io/library/entry/Note10b2.html - AdPlug Library entry
- ROL Format - similar format
Credits
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!)