Thank you Jepael.
I had problems to see the byteorder In the sourcecode I see the OPL Register addresses like 0x20, 0x40, 0x20. I think data get written there to control the fm synth.
But I don`t understand the order from the the 11 instrument bytes.
If I understand the code right the procedure Player::setupChannel will be invoked with the two parameter channel with datatype uint8_t and instrOffset with datatype uint16_t.
Player::setupOperator will be invoked with the two parameter opr with datatype uint8_t and &instrOffset with datatype uint16_t.
But I don`t understand the things below the first lines from the procedure. I see some addition with the parameter that was given with the procedure and the OPL register addresses.
I have looked at the .sbi file format documentation. I see there the OPL register with datatype and description. But I don`t see where the instrument bytes should be.
Maybe I mixed up chip register and instrument bytes.
Extract/Convert Adlib Instruments
Moderator: ScummVM Team
OK, I can explain a bit more. The following register values mean only first OPL channel, but you get the idea.
SBI file format:
First header information, 4+32+16 bytes.
Istrument data, 11 bytes:
data for register 0x20
data for register 0x23
data for register 0x40
data for register 0x43
data for register 0x60
data for register 0x63
data for register 0x80
data for register 0x83
data for register 0xe0
data for register 0xe3
data for register 0xc0
padding: 5 bytes of zeroes
How LordHoto's code loads data into chip (when enough bytes are skipped from start):
data for register 0xc0
data for register 0x20
data for register 0x40
data for register 0x60
data for register 0x80
data for register 0xe0
data for register 0x23
data for register 0x43
data for register 0x63
data for register 0x83
data for register 0xe3
So as you can see, both files contain data for same registers, just the order inside the file is different.
SBI file format:
First header information, 4+32+16 bytes.
Istrument data, 11 bytes:
data for register 0x20
data for register 0x23
data for register 0x40
data for register 0x43
data for register 0x60
data for register 0x63
data for register 0x80
data for register 0x83
data for register 0xe0
data for register 0xe3
data for register 0xc0
padding: 5 bytes of zeroes
How LordHoto's code loads data into chip (when enough bytes are skipped from start):
data for register 0xc0
data for register 0x20
data for register 0x40
data for register 0x60
data for register 0x80
data for register 0xe0
data for register 0x23
data for register 0x43
data for register 0x63
data for register 0x83
data for register 0xe3
So as you can see, both files contain data for same registers, just the order inside the file is different.
Thanks a lot for guiding me through the data jungle
In adplayer.cpp I only see the following register adresses:
Player::setupChannel
0xC0
Player::setupOperator
0x20
0x40
0x60
0x80
0xE0
Where are the others you listed?
However I looked at the adplug sources. I have not found mid.c. I also looked in prior versions. But in mid.cpp i found some chip register adresses:
Specially these lines looks interesting (341-379):
So if I look from top to bottom I see this order:
0x20
0x23
0x40
0x43
0x60
0x63
0x80
0x83
0xe0
0xe3
0xc0
This looks exactly like the SBI Format. As you mention before.
In adplayer.cpp I only see the following register adresses:
Player::setupChannel
0xC0
Player::setupOperator
0x20
0x40
0x60
0x80
0xE0
Where are the others you listed?
However I looked at the adplug sources. I have not found mid.c. I also looked in prior versions. But in mid.cpp i found some chip register adresses:
Specially these lines looks interesting (341-379):
Code: Select all
void CmidPlayer::midi_fm_instrument(int voice, unsigned char *inst)
{
if ((adlib_style&SIERRA_STYLE)!=0)
midi_write_adlib(0xbd,0); //just gotta make sure this happens..
//'cause who knows when it'll be
//reset otherwise.
midi_write_adlib(0x20+adlib_opadd[voice],inst[0]);
midi_write_adlib(0x23+adlib_opadd[voice],inst[1]);
if (adlib_style & LUCAS_STYLE) {
midi_write_adlib(0x43+adlib_opadd[voice],0x3f);
if ((inst[10] & 1)==0)
midi_write_adlib(0x40+adlib_opadd[voice],inst[2]);
else
midi_write_adlib(0x40+adlib_opadd[voice],0x3f);
} else if ((adlib_style & SIERRA_STYLE) || (adlib_style & CMF_STYLE)) {
midi_write_adlib(0x40+adlib_opadd[voice],inst[2]);
midi_write_adlib(0x43+adlib_opadd[voice],inst[3]);
} else {
midi_write_adlib(0x40+adlib_opadd[voice],inst[2]);
if ((inst[10] & 1)==0)
midi_write_adlib(0x43+adlib_opadd[voice],inst[3]);
else
midi_write_adlib(0x43+adlib_opadd[voice],0);
}
midi_write_adlib(0x60+adlib_opadd[voice],inst[4]);
midi_write_adlib(0x63+adlib_opadd[voice],inst[5]);
midi_write_adlib(0x80+adlib_opadd[voice],inst[6]);
midi_write_adlib(0x83+adlib_opadd[voice],inst[7]);
midi_write_adlib(0xe0+adlib_opadd[voice],inst[8]);
midi_write_adlib(0xe3+adlib_opadd[voice],inst[9]);
midi_write_adlib(0xc0+voice,inst[10]);
}
0x20
0x23
0x40
0x43
0x60
0x63
0x80
0x83
0xe0
0xe3
0xc0
This looks exactly like the SBI Format. As you mention before.
jepael wrote: My guess is the internal order in myinsbank (array of instrument bytes) is same as in .sbi instrument file
An OPL channel consists of two operators. Player::setupChannel loads the 0xC0 register and calls Player::setupOperator twice, first with offset 0 to write parameters to first operator and then with offset 3 to write parameters to second operator.tashiy wrote:Thanks a lot for guiding me through the data jungle
In adplayer.cpp I only see the following register adresses:
Player::setupChannel
0xC0
Player::setupOperator
0x20
0x40
0x60
0x80
0xE0
Where are the others you listed?
Sorry, I may have written .c instead of .cpp.tashiy wrote: However I looked at the adplug sources. I have not found mid.c. I also looked in prior versions. But in mid.cpp i found some chip register adresses:
This looks exactly like the SBI Format. As you mention before.
But anyway, I had my thoughts about this. One reason might be that different file formats use similar instrument formats to be compatible with other formats more easily.
Ah ok then all the 0x23,0x43,0x63,0x83,0xE3 are loaded when Player::setupOperator is called the second time.jepael wrote: An OPL channel consists of two operators. Player::setupChannel loads the 0xC0 register and calls Player::setupOperator twice, first with offset 0 to write parameters to first operator and then with offset 3 to write parameters to second operator.
I see this is how the FM Synth works, with operator and carrier. Where one oscillator modulates the other.
Now the question is how i find the instruments in the .laa file. Cause there must me many more data in there. Like sequencing data (notes).jepael wrote: One reason might be that different file formats use similar instrument formats to be compatible with other formats more easily.
Sorry it must be a bit tendious for you to help someone that is not experienced in such way. I really appreciate to understand this technologie more.