Code for loading and saving various FM voice formats meant for the Yamaha YM series of chips (OPL, OPM, OPN etc.), format autodetection code, and conversion between the various formats.
This library is meant to be used in fmtoy and vgm2x.
| Format | Type | Op | Max voices |
|---|---|---|---|
| INS | OPN | 4 | 1 |
| DMP | OPN | 4 | 1 |
| OPM | OPM | 4 | unlimited |
| TFI | OPN | 4 | 1 |
| Y12 | OPN | 4 | 1 |
| SBI | OPL | 2 | 1 |
| INS | OPL | 2 | 1 |
| BNK | OPL | 2 | 65536 |
| IBK | OPL | 2 | 128 |
| CMF | OPL | 2 | 128/256/65536 |
OPL
| Field | Bit | Description | |||||||
|---|---|---|---|---|---|---|---|---|---|
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ||
ch_fb_cnt[0] | D | C | B | A | FB | CNT | Channel mask, feedback, connection | ||
dam_dvb_ryt_bd_sd_tom_tc_hh | AM | VIB | RYT | BD | SD | TOM | TC | HH | |
am_vib_eg_ksr_mul | AM | VIB | EGT | KSR | MUL | ||||
ksl_tl | KSL | TL | |||||||
ar_dr | AR | DR | |||||||
sl_rr | SL | RR | |||||||
ws | WS | Waveform select | |||||||
Conversion between OPL, OPM and OPN voices is only possible in some cases, in other cases it involves approximation, and in others it is not possible.
Reading:
uint8_t*data; // Have your data in this buffersize_tdata_len; // with this lengthstructopm_fileopm;
intr=opm_file_load(&opm, data, data_len);
if(r!=OPM_FILE_SUCCESS) {
fprintf(stderr, "Could not load file: %s (%d)\n", opm_file_error_string(r), r);
exit(1);
}Writing:
size_twrite_fn(void*buf, size_tbufsize, void*data_ptr) {
FILE*f= (FILE*)data_ptr;
returnfwrite(buf, 1, bufsize, f);
}
structopm_fileopm;
opm_file_init(&opm);
FILE*f=fopen("out.opm", "w");
intopm_file_save(&opm, write_fn, f);
fclose(f);emmake make libfmvoice.aOPM LFO
OPN LFO