bool RunData::decodeMessage(const uint8_t *buf) { auto runData = GetRunInfo(buf); if (runData->info_type_type() == InfoTypes_RunStart) { auto runStartData = static_cast<const RunStart *>(runData->info_type()); setStartTimeInNanoseconds(runStartData->start_time()); setInstrumentName(runStartData->instrument_name()->str()); setRunNumber(runStartData->run_number()); setNumberOfPeriods(runStartData->n_periods()); return true; } if (runData->info_type_type() == InfoTypes_RunStop) { auto runStopData = static_cast<const RunStop *>(runData->info_type()); setStopTime(runStopData->stop_time()); return true; } return false; // this is not a RunData message }
static int gtk_load(struct module_data *m, HIO_HANDLE *f, const int start) { struct xmp_module *mod = &m->mod; struct xmp_event *event; int i, j, k; uint8 buffer[40]; int rows, bits, c2spd, size; int ver, patmax; LOAD_INIT(); hio_read(buffer, 4, 1, f); ver = buffer[3]; hio_read(mod->name, 32, 1, f); set_type(m, "Graoumf Tracker GTK v%d", ver); hio_seek(f, 160, SEEK_CUR); /* skip comments */ mod->ins = hio_read16b(f); mod->smp = mod->ins; rows = hio_read16b(f); mod->chn = hio_read16b(f); mod->len = hio_read16b(f); mod->rst = hio_read16b(f); m->volbase = 0x100; MODULE_INFO(); D_(D_INFO "Instruments : %d ", mod->ins); if (instrument_init(mod) < 0) return -1; for (i = 0; i < mod->ins; i++) { if (subinstrument_alloc(mod, i, 1) < 0) return -1; hio_read(buffer, 28, 1, f); instrument_name(mod, i, buffer, 28); if (ver == 1) { hio_read32b(f); mod->xxs[i].len = hio_read32b(f); mod->xxs[i].lps = hio_read32b(f); size = hio_read32b(f); mod->xxs[i].lpe = mod->xxs[i].lps + size - 1; hio_read16b(f); hio_read16b(f); mod->xxi[i].sub[0].vol = 0xff; mod->xxi[i].sub[0].pan = 0x80; bits = 1; c2spd = 8363; } else { hio_seek(f, 14, SEEK_CUR); hio_read16b(f); /* autobal */ bits = hio_read16b(f); /* 1 = 8 bits, 2 = 16 bits */ c2spd = hio_read16b(f); c2spd_to_note(c2spd, &mod->xxi[i].sub[0].xpo, &mod->xxi[i].sub[0].fin); mod->xxs[i].len = hio_read32b(f); mod->xxs[i].lps = hio_read32b(f); size = hio_read32b(f); mod->xxs[i].lpe = mod->xxs[i].lps + size - 1; mod->xxi[i].sub[0].vol = hio_read16b(f); hio_read8(f); mod->xxi[i].sub[0].fin = hio_read8s(f); } if (mod->xxs[i].len > 0) mod->xxi[i].nsm = 1; mod->xxi[i].sub[0].sid = i; mod->xxs[i].flg = size > 2 ? XMP_SAMPLE_LOOP : 0; if (bits > 1) { mod->xxs[i].flg |= XMP_SAMPLE_16BIT; mod->xxs[i].len >>= 1; mod->xxs[i].lps >>= 1; mod->xxs[i].lpe >>= 1; } D_(D_INFO "[%2X] %-28.28s %05x%c%05x %05x %c " "V%02x F%+03d %5d", i, mod->xxi[i].name, mod->xxs[i].len, bits > 1 ? '+' : ' ', mod->xxs[i].lps, size, mod->xxs[i].flg & XMP_SAMPLE_LOOP ? 'L' : ' ', mod->xxi[i].sub[0].vol, mod->xxi[i].sub[0].fin, c2spd); }
static int hmn_load(struct module_data *m, HIO_HANDLE * f, const int start) { struct xmp_module *mod = &m->mod; int i, j; struct xmp_event *event; struct mod_header mh; struct mupp mupp[31]; uint8 mod_event[4]; int mupp_index, num_mupp; LOAD_INIT(); /* * clr.b $1c(a6) ;prog on/off * CMP.L #'Mupp',-$16(a3,d4.l) * bne.s noprgo * move.l a0,-(a7) * move.b #1,$1c(a6) ;prog on * move.l l697,a0 * lea $43c(a0),a0 * moveq #0,d2 * move.b -$16+$4(a3,d4.l),d2 ;pattno * mulu #$400,d2 * lea (a0,d2.l),a0 * move.l a0,4(a6) ;proginstr data-start * moveq #0,d2 * MOVE.B $3C0(A0),$12(A6) * AND.B #$7F,$12(A6) * move.b $380(a0),d2 * mulu #$20,d2 * lea (a0,d2.w),a0 * move.l a0,$a(a6) ;loopstartmempoi = startmempoi * move.B $3(a3,d4.l),$13(a6) ;volume * move.b -$16+$5(a3,d4.l),8(a6) ;dataloopstart * move.b -$16+$6(a3,d4.l),9(a6) ;dataloopend * move.w #$10,$e(a6) ;looplen * move.l (a7)+,a0 * MOVE.W $12(A6),(A2) * AND.W #$FF,(A2) * BRA.S L505_LQ */ /* * Wavetable structure is 22 * 32 byte waveforms and 32 byte * wave control data with looping. */ memset(mupp, 0, 31 * sizeof (struct mupp)); hio_read(&mh.name, 20, 1, f); num_mupp = 0; for (i = 0; i < 31; i++) { hio_read(&mh.ins[i].name, 22, 1, f); /* Instrument name */ if (memcmp(mh.ins[i].name, "Mupp", 4) == 0) { mupp[i].prgon = 1; mupp[i].pattno = mh.ins[i].name[4]; mupp[i].dataloopstart = mh.ins[i].name[5]; mupp[i].dataloopend = mh.ins[i].name[6]; num_mupp++; } mh.ins[i].size = hio_read16b(f); mh.ins[i].finetune = hio_read8(f); mh.ins[i].volume = hio_read8(f); mh.ins[i].loop_start = hio_read16b(f); mh.ins[i].loop_size = hio_read16b(f); } mh.len = hio_read8(f); mh.restart = hio_read8(f); hio_read(&mh.order, 128, 1, f); hio_read(&mh.magic, 4, 1, f); mod->chn = 4; mod->ins = 31; mod->smp = mod->ins + 28 * num_mupp; mod->len = mh.len; mod->rst = mh.restart; memcpy(mod->xxo, mh.order, 128); for (i = 0; i < 128; i++) { if (mod->xxo[i] > mod->pat) mod->pat = mod->xxo[i]; } mod->pat++; mod->trk = mod->chn * mod->pat; if (hmn_new_module_extras(m) != 0) return -1; strncpy(mod->name, (char *)mh.name, 20); set_type(m, "%s (%4.4s)", "His Master's Noise", mh.magic); MODULE_INFO(); if (instrument_init(mod) < 0) return -1; for (i = 0; i < mod->ins; i++) { if (mupp[i].prgon) { mod->xxi[i].nsm = 28; snprintf(mod->xxi[i].name, 32, "Mupp %02x %02x %02x", mupp[i].pattno, mupp[i].dataloopstart, mupp[i].dataloopend); if (hmn_new_instrument_extras(&mod->xxi[i]) != 0) return -1; } else { mod->xxi[i].nsm = 1; instrument_name(mod, i, mh.ins[i].name, 22); mod->xxs[i].len = 2 * mh.ins[i].size; mod->xxs[i].lps = 2 * mh.ins[i].loop_start; mod->xxs[i].lpe = mod->xxs[i].lps + 2 * mh.ins[i].loop_size; mod->xxs[i].flg = mh.ins[i].loop_size > 1 ? XMP_SAMPLE_LOOP : 0; } if (subinstrument_alloc(mod, i, mod->xxi[i].nsm) < 0) return -1; for (j = 0; j < mod->xxi[i].nsm; j++) { mod->xxi[i].sub[j].fin = -(int8)(mh.ins[i].finetune << 3); mod->xxi[i].sub[j].vol = mh.ins[i].volume; mod->xxi[i].sub[j].pan = 0x80; mod->xxi[i].sub[j].sid = i; } } if (pattern_init(mod) < 0) return -1; /* Load and convert patterns */ D_(D_INFO "Stored patterns: %d", mod->pat); for (i = 0; i < mod->pat; i++) { if (pattern_tracks_alloc(mod, i, 64) < 0) return -1; for (j = 0; j < (64 * 4); j++) { event = &EVENT(i, j % 4, j / 4); hio_read(mod_event, 1, 4, f); decode_protracker_event(event, mod_event); switch (event->fxt) { case 0x07: event->fxt = FX_MEGAARP; break; case 0x08: case 0x09: case 0x0e: event->fxt = event->fxp = 0; break; } } } m->quirk |= QUIRK_MODRNG; /* Load samples */ D_(D_INFO "Stored samples: %d", mod->smp); for (i = 0; i < 31; i++) { if (load_sample(m, f, SAMPLE_FLAG_FULLREP, &mod->xxs[i], NULL) < 0) { return -1; } } /* Load Mupp samples */ mupp_index = 0; for (i = 0; i < 31; i ++) { struct hmn_instrument_extras *extra = (struct hmn_instrument_extras *)mod->xxi[i].extra; if (!mupp[i].prgon) continue; hio_seek(f, start + 1084 + 1024 * mupp[i].pattno, SEEK_SET); for (j = 0; j < 28; j++) { int k = 31 + 28 * mupp_index + j; mod->xxi[i].sub[j].sid = k; mod->xxs[k].len = 32; mod->xxs[k].lps = 0; mod->xxs[k].lpe = 32; mod->xxs[k].flg = XMP_SAMPLE_LOOP; if (load_sample(m, f, 0, &mod->xxs[k], NULL) < 0) return -1; } extra->dataloopstart = mupp[i].dataloopstart; extra->dataloopend = mupp[i].dataloopend; hio_read(extra->data, 1, 64, f); hio_read(extra->progvolume, 1, 64, f); mupp_index++; } return 0; }
static int get_inst(struct module_data *m, int size, HIO_HANDLE *f, void *parm) { struct xmp_module *mod = &m->mod; int i, c2spd; uint8 name[30]; mod->ins = mod->smp = hio_read16b(f); D_(D_INFO "Instruments : %d ", mod->ins); if (instrument_init(mod) < 0) return -1; for (i = 0; i < mod->ins; i++) { int fine, replen, flag; if (subinstrument_alloc(mod, i, 1) < 0) return -1; hio_read32b(f); /* reserved */ mod->xxs[i].len = hio_read32b(f); mod->xxi[i].nsm = !!mod->xxs[i].len; fine = hio_read8s(f); /* finetune */ mod->xxi[i].sub[0].vol = hio_read8(f); mod->xxi[i].sub[0].pan = 0x80; mod->xxs[i].lps = hio_read32b(f); replen = hio_read32b(f); mod->xxs[i].lpe = mod->xxs[i].lps + replen - 1; mod->xxs[i].flg = replen > 2 ? XMP_SAMPLE_LOOP : 0; hio_read(name, 22, 1, f); instrument_name(mod, i, name, 22); flag = hio_read16b(f); /* bit 0-7:resol 8:stereo */ if ((flag & 0xff) > 8) { mod->xxs[i].flg |= XMP_SAMPLE_16BIT; mod->xxs[i].len >>= 1; mod->xxs[i].lps >>= 1; mod->xxs[i].lpe >>= 1; } hio_read32b(f); /* midi note (0x00300000) */ c2spd = hio_read32b(f); /* frequency */ c2spd_to_note(c2spd, &mod->xxi[i].sub[0].xpo, &mod->xxi[i].sub[0].fin); /* It's strange that we have both c2spd and finetune */ mod->xxi[i].sub[0].fin += fine; mod->xxi[i].sub[0].sid = i; D_(D_INFO "[%2X] %-22.22s %05x%c%05x %05x %c%c %2db V%02x F%+03d %5d", i, mod->xxi[i].name, mod->xxs[i].len, mod->xxs[i].flg & XMP_SAMPLE_16BIT ? '+' : ' ', mod->xxs[i].lps, replen, mod->xxs[i].flg & XMP_SAMPLE_LOOP ? 'L' : ' ', flag & 0x100 ? 'S' : ' ', flag & 0xff, mod->xxi[i].sub[0].vol, fine, c2spd); }
static int ptdt_load(struct module_data *m, HIO_HANDLE *f, const int start) { struct xmp_module *mod = &m->mod; int i, j; struct xmp_event *event; struct mod_header mh; uint8 mod_event[4]; hio_read(&mh.name, 20, 1, f); for (i = 0; i < 31; i++) { hio_read(&mh.ins[i].name, 22, 1, f); mh.ins[i].size = hio_read16b(f); mh.ins[i].finetune = hio_read8(f); mh.ins[i].volume = hio_read8(f); mh.ins[i].loop_start = hio_read16b(f); mh.ins[i].loop_size = hio_read16b(f); } mh.len = hio_read8(f); mh.restart = hio_read8(f); hio_read(&mh.order, 128, 1, f); hio_read(&mh.magic, 4, 1, f); mod->ins = 31; mod->smp = mod->ins; mod->chn = 4; mod->len = mh.len; mod->rst = mh.restart; memcpy(mod->xxo, mh.order, 128); for (i = 0; i < 128; i++) { if (mod->xxo[i] > mod->pat) mod->pat = mod->xxo[i]; } mod->pat++; mod->trk = mod->chn * mod->pat; if (instrument_init(mod) < 0) return -1; for (i = 0; i < mod->ins; i++) { if (subinstrument_alloc(mod, i, 1) < 0) return -1; mod->xxs[i].len = 2 * mh.ins[i].size; mod->xxs[i].lps = 2 * mh.ins[i].loop_start; mod->xxs[i].lpe = mod->xxs[i].lps + 2 * mh.ins[i].loop_size; mod->xxs[i].flg = mh.ins[i].loop_size > 1 ? XMP_SAMPLE_LOOP : 0; if (mod->xxs[i].len > 0) mod->xxi[i].nsm = 1; mod->xxi[i].sub[0].fin = (int8)(mh.ins[i].finetune << 4); mod->xxi[i].sub[0].vol = mh.ins[i].volume; mod->xxi[i].sub[0].pan = 0x80; mod->xxi[i].sub[0].sid = i; mod->xxi[i].rls = 0xfff; instrument_name(mod, i, mh.ins[i].name, 22); D_(D_INFO "[%2X] %-22.22s %04x %04x %04x %c V%02x %+d", i, mod->xxi[i].name, mod->xxs[i].len, mod->xxs[i].lps, mod->xxs[i].lpe, mh.ins[i].loop_size > 1 ? 'L' : ' ', mod->xxi[i].sub[0].vol, mod->xxi[i].sub[0].fin >> 4); } if (pattern_init(mod) < 0) return -1; /* Load and convert patterns */ D_(D_INFO "Stored patterns: %d", mod->pat); for (i = 0; i < mod->pat; i++) { if (pattern_tracks_alloc(mod, i, 64) < 0) return -1; for (j = 0; j < (64 * 4); j++) { event = &EVENT(i, j % 4, j / 4); hio_read(mod_event, 1, 4, f); decode_protracker_event(event, mod_event); } } m->quirk |= QUIRK_MODRNG; /* Load samples */ D_(D_INFO "Stored samples: %d", mod->smp); for (i = 0; i < mod->smp; i++) { if (!mod->xxs[i].len) continue; if (load_sample(m, f, 0, &mod->xxs[i], NULL) < 0) return -1; } return 0; }
static int stm_load(struct module_data *m, HIO_HANDLE *f, const int start) { struct xmp_module *mod = &m->mod; int i, j; struct xmp_event *event; struct stm_file_header sfh; uint8 b; int bmod2stm = 0; LOAD_INIT(); hio_read(&sfh.name, 20, 1, f); /* ASCIIZ song name */ hio_read(&sfh.magic, 8, 1, f); /* '!Scream!' */ sfh.rsvd1 = hio_read8(f); /* '\x1a' */ sfh.type = hio_read8(f); /* 1=song, 2=module */ sfh.vermaj = hio_read8(f); /* Major version number */ sfh.vermin = hio_read8(f); /* Minor version number */ sfh.tempo = hio_read8(f); /* Playback tempo */ sfh.patterns = hio_read8(f); /* Number of patterns */ sfh.gvol = hio_read8(f); /* Global volume */ hio_read(&sfh.rsvd2, 13, 1, f); /* Reserved */ for (i = 0; i < 31; i++) { hio_read(&sfh.ins[i].name, 12, 1, f); /* ASCIIZ instrument name */ sfh.ins[i].id = hio_read8(f); /* Id=0 */ sfh.ins[i].idisk = hio_read8(f); /* Instrument disk */ sfh.ins[i].rsvd1 = hio_read16l(f); /* Reserved */ sfh.ins[i].length = hio_read16l(f); /* Sample length */ sfh.ins[i].loopbeg = hio_read16l(f); /* Loop begin */ sfh.ins[i].loopend = hio_read16l(f); /* Loop end */ sfh.ins[i].volume = hio_read8(f); /* Playback volume */ sfh.ins[i].rsvd2 = hio_read8(f); /* Reserved */ sfh.ins[i].c2spd = hio_read16l(f); /* C4 speed */ sfh.ins[i].rsvd3 = hio_read32l(f); /* Reserved */ sfh.ins[i].paralen = hio_read16l(f); /* Length in paragraphs */ } if (!strncmp ((char *)sfh.magic, "BMOD2STM", 8)) bmod2stm = 1; mod->pat = sfh.patterns; mod->trk = mod->pat * mod->chn; mod->spd = MSN (sfh.tempo); mod->ins = 31; mod->smp = mod->ins; m->c4rate = C4_NTSC_RATE; copy_adjust(mod->name, sfh.name, 20); if (bmod2stm) { snprintf(mod->type, XMP_NAME_SIZE, "BMOD2STM STM"); } else { snprintf(mod->type, XMP_NAME_SIZE, "Scream Tracker %d.%02d STM", sfh.vermaj, sfh.vermin); } MODULE_INFO(); if (instrument_init(mod) < 0) return -1; /* Read and convert instruments and samples */ for (i = 0; i < mod->ins; i++) { if (subinstrument_alloc(mod, i, 1) < 0) return -1; mod->xxs[i].len = sfh.ins[i].length; mod->xxs[i].lps = sfh.ins[i].loopbeg; mod->xxs[i].lpe = sfh.ins[i].loopend; if (mod->xxs[i].lpe == 0xffff) mod->xxs[i].lpe = 0; mod->xxs[i].flg = mod->xxs[i].lpe > 0 ? XMP_SAMPLE_LOOP : 0; mod->xxi[i].sub[0].vol = sfh.ins[i].volume; mod->xxi[i].sub[0].pan = 0x80; mod->xxi[i].sub[0].sid = i; if (mod->xxs[i].len > 0) mod->xxi[i].nsm = 1; instrument_name(mod, i, sfh.ins[i].name, 12); D_(D_INFO "[%2X] %-14.14s %04x %04x %04x %c V%02x %5d", i, mod->xxi[i].name, mod->xxs[i].len, mod->xxs[i].lps, mod->xxs[i].lpe, mod->xxs[i].flg & XMP_SAMPLE_LOOP ? 'L' : ' ', mod->xxi[i].sub[0].vol, sfh.ins[i].c2spd); sfh.ins[i].c2spd = 8363 * sfh.ins[i].c2spd / 8448; c2spd_to_note (sfh.ins[i].c2spd, &mod->xxi[i].sub[0].xpo, &mod->xxi[i].sub[0].fin); } hio_read(mod->xxo, 1, 128, f); for (i = 0; i < 128; i++) if (mod->xxo[i] >= mod->pat) break; mod->len = i; D_(D_INFO "Module length: %d", mod->len); if (pattern_init(mod) < 0) return -1; /* Read and convert patterns */ D_(D_INFO "Stored patterns: %d", mod->pat); for (i = 0; i < mod->pat; i++) { if (pattern_tracks_alloc(mod, i, 64) < 0) return -1; for (j = 0; j < 64 * mod->chn; j++) { event = &EVENT (i, j % mod->chn, j / mod->chn); b = hio_read8(f); memset (event, 0, sizeof (struct xmp_event)); switch (b) { case 251: case 252: case 253: break; case 255: b = 0; default: event->note = b ? 13 + LSN(b) + 12 * (2 + MSN(b)) : 0; b = hio_read8(f); event->vol = b & 0x07; event->ins = (b & 0xf8) >> 3; b = hio_read8(f); event->vol += (b & 0xf0) >> 1; if (event->vol > 0x40) event->vol = 0; else event->vol++; event->fxt = fx[LSN(b)]; event->fxp = hio_read8(f); switch (event->fxt) { case FX_SPEED: event->fxp = MSN (event->fxp); break; case FX_NONE: event->fxp = event->fxt = 0; break; } } } } /* Read samples */ D_(D_INFO "Stored samples: %d", mod->smp); for (i = 0; i < mod->ins; i++) { if (mod->xxs[i].len > 1) { if (load_sample(m, f, 0, &mod->xxs[i], NULL) < 0) return -1; } else { mod->xxi[i].nsm = 0; } } m->quirk |= QUIRK_VSALL | QUIRKS_ST3; m->read_event_type = READ_EVENT_ST3; return 0; }
static int med3_load(struct module_data *m, HIO_HANDLE *f, const int start) { struct xmp_module *mod = &m->mod; int i, j; uint32 mask; int transp, sliding; LOAD_INIT(); hio_read32b(f); set_type(m, "MED 2.00 MED3"); mod->ins = mod->smp = 32; if (instrument_init(mod) < 0) return -1; /* read instrument names */ for (i = 0; i < 32; i++) { uint8 c, buf[40]; for (j = 0; j < 40; j++) { c = hio_read8(f); buf[j] = c; if (c == 0) break; } instrument_name(mod, i, buf, 32); if (subinstrument_alloc(mod, i, 1) < 0) return -1; } /* read instrument volumes */ mask = hio_read32b(f); for (i = 0; i < 32; i++, mask <<= 1) { mod->xxi[i].sub[0].vol = mask & MASK ? hio_read8(f) : 0; mod->xxi[i].sub[0].pan = 0x80; mod->xxi[i].sub[0].fin = 0; mod->xxi[i].sub[0].sid = i; } /* read instrument loops */ mask = hio_read32b(f); for (i = 0; i < 32; i++, mask <<= 1) { mod->xxs[i].lps = mask & MASK ? hio_read16b(f) : 0; } /* read instrument loop length */ mask = hio_read32b(f); for (i = 0; i < 32; i++, mask <<= 1) { uint32 lsiz = mask & MASK ? hio_read16b(f) : 0; mod->xxs[i].len = mod->xxs[i].lps + lsiz; mod->xxs[i].lpe = mod->xxs[i].lps + lsiz; mod->xxs[i].flg = lsiz > 1 ? XMP_SAMPLE_LOOP : 0; } mod->chn = 4; mod->pat = hio_read16b(f); mod->trk = mod->chn * mod->pat; mod->len = hio_read16b(f); hio_read(mod->xxo, 1, mod->len, f); mod->spd = hio_read16b(f); if (mod->spd > 10) { mod->bpm = 125 * mod->spd / 33; mod->spd = 6; } transp = hio_read8s(f); hio_read8(f); /* flags */ sliding = hio_read16b(f); /* sliding */ hio_read32b(f); /* jumping mask */ hio_seek(f, 16, SEEK_CUR); /* rgb */ /* read midi channels */ mask = hio_read32b(f); for (i = 0; i < 32; i++, mask <<= 1) { if (mask & MASK) hio_read8(f); } /* read midi programs */ mask = hio_read32b(f); for (i = 0; i < 32; i++, mask <<= 1) { if (mask & MASK) hio_read8(f); } MODULE_INFO(); D_(D_INFO "Sliding: %d", sliding); D_(D_INFO "Play transpose: %d", transp); if (sliding == 6) m->quirk |= QUIRK_VSALL | QUIRK_PBALL; for (i = 0; i < 32; i++) mod->xxi[i].sub[0].xpo = transp; if (pattern_init(mod) < 0) return -1; /* Load and convert patterns */ D_(D_INFO "Stored patterns: %d", mod->pat); for (i = 0; i < mod->pat; i++) { uint32 *conv; uint8 b, tracks; uint16 convsz; if (pattern_tracks_alloc(mod, i, 64) < 0) return -1; tracks = hio_read8(f); b = hio_read8(f); convsz = hio_read16b(f); conv = calloc(1, convsz + 16); if (conv == NULL) return -1; if (b & M0F_LINEMSK00) *conv = 0L; else if (b & M0F_LINEMSK0F) *conv = 0xffffffff; else *conv = hio_read32b(f); if (b & M0F_LINEMSK10) *(conv + 1) = 0L; else if (b & M0F_LINEMSK1F) *(conv + 1) = 0xffffffff; else *(conv + 1) = hio_read32b(f); if (b & M0F_FXMSK00) *(conv + 2) = 0L; else if (b & M0F_FXMSK0F) *(conv + 2) = 0xffffffff; else *(conv + 2) = hio_read32b(f); if (b & M0F_FXMSK10) *(conv + 3) = 0L; else if (b & M0F_FXMSK1F) *(conv + 3) = 0xffffffff; else *(conv + 3) = hio_read32b(f); hio_read(conv + 4, 1, convsz, f); if (unpack_block(m, i, (uint8 *)conv) < 0) { free(conv); return -1; } free(conv); } /* Load samples */ D_(D_INFO "Instruments: %d", mod->ins); mask = hio_read32b(f); for (i = 0; i < 32; i++, mask <<= 1) { if (~mask & MASK) continue; mod->xxi[i].nsm = 1; mod->xxs[i].len = hio_read32b(f); if (mod->xxs[i].len == 0) mod->xxi[i].nsm = 0; if (hio_read16b(f)) /* type */ continue; D_(D_INFO "[%2X] %-32.32s %04x %04x %04x %c V%02x ", i, mod->xxi[i].name, mod->xxs[i].len, mod->xxs[i].lps, mod->xxs[i].lpe, mod->xxs[i].flg & XMP_SAMPLE_LOOP ? 'L' : ' ', mod->xxi[i].sub[0].vol); if (load_sample(m, f, 0, &mod->xxs[i], NULL) < 0) return -1; } return 0; }
static int ptm_load(struct module_data *m, HIO_HANDLE *f, const int start) { struct xmp_module *mod = &m->mod; int c, r, i, smp_ofs[256]; struct xmp_event *event; struct ptm_file_header pfh; struct ptm_instrument_header pih; uint8 n, b; LOAD_INIT(); /* Load and convert header */ hio_read(&pfh.name, 28, 1, f); /* Song name */ pfh.doseof = hio_read8(f); /* 0x1a */ pfh.vermin = hio_read8(f); /* Minor version */ pfh.vermaj = hio_read8(f); /* Major type */ pfh.rsvd1 = hio_read8(f); /* Reserved */ pfh.ordnum = hio_read16l(f); /* Number of orders (must be even) */ pfh.insnum = hio_read16l(f); /* Number of instruments */ pfh.patnum = hio_read16l(f); /* Number of patterns */ pfh.chnnum = hio_read16l(f); /* Number of channels */ pfh.flags = hio_read16l(f); /* Flags (set to 0) */ pfh.rsvd2 = hio_read16l(f); /* Reserved */ pfh.magic = hio_read32b(f); /* 'PTMF' */ if (pfh.magic != MAGIC_PTMF) return -1; /* Sanity check */ if (pfh.ordnum > 256 || pfh.insnum > 255 || pfh.patnum > 128 || pfh.chnnum > 32) { return -1; } hio_read(&pfh.rsvd3, 16, 1, f); /* Reserved */ hio_read(&pfh.chset, 32, 1, f); /* Channel settings */ hio_read(&pfh.order, 256, 1, f); /* Orders */ for (i = 0; i < 128; i++) pfh.patseg[i] = hio_read16l(f); mod->len = pfh.ordnum; mod->ins = pfh.insnum; mod->pat = pfh.patnum; mod->chn = pfh.chnnum; mod->trk = mod->pat * mod->chn; mod->smp = mod->ins; mod->spd = 6; mod->bpm = 125; memcpy (mod->xxo, pfh.order, 256); m->c4rate = C4_NTSC_RATE; copy_adjust(mod->name, pfh.name, 28); set_type(m, "Poly Tracker PTM %d.%02x", pfh.vermaj, pfh.vermin); MODULE_INFO(); if (instrument_init(mod) < 0) return -1; /* Read and convert instruments and samples */ for (i = 0; i < mod->ins; i++) { struct xmp_instrument *xxi = &mod->xxi[i]; struct xmp_sample *xxs = &mod->xxs[i]; struct xmp_subinstrument *sub; pih.type = hio_read8(f); /* Sample type */ hio_read(&pih.dosname, 12, 1, f); /* DOS file name */ pih.vol = hio_read8(f); /* Volume */ pih.c4spd = hio_read16l(f); /* C4 speed */ pih.smpseg = hio_read16l(f); /* Sample segment (not used) */ pih.smpofs = hio_read32l(f); /* Sample offset */ pih.length = hio_read32l(f); /* Length */ pih.loopbeg = hio_read32l(f); /* Loop begin */ pih.loopend = hio_read32l(f); /* Loop end */ pih.gusbeg = hio_read32l(f); /* GUS begin address */ pih.guslps = hio_read32l(f); /* GUS loop start address */ pih.guslpe = hio_read32l(f); /* GUS loop end address */ pih.gusflg = hio_read8(f); /* GUS loop flags */ pih.rsvd1 = hio_read8(f); /* Reserved */ hio_read(&pih.name, 28, 1, f); /* Instrument name */ pih.magic = hio_read32b(f); /* 'PTMS' */ if ((pih.type & 3) != 1) continue; if (subinstrument_alloc(mod, i, 1) < 0) return -1; sub = &xxi->sub[0]; smp_ofs[i] = pih.smpofs; xxs->len = pih.length; xxs->lps = pih.loopbeg; xxs->lpe = pih.loopend; if (mod->xxs[i].len > 0) mod->xxi[i].nsm = 1; xxs->flg = 0; if (pih.type & 0x04) { xxs->flg |= XMP_SAMPLE_LOOP; } if (pih.type & 0x08) { xxs->flg |= XMP_SAMPLE_LOOP | XMP_SAMPLE_LOOP_BIDIR; } if (pih.type & 0x10) { xxs->flg |= XMP_SAMPLE_16BIT; xxs->len >>= 1; xxs->lps >>= 1; xxs->lpe >>= 1; } sub->vol = pih.vol; sub->pan = 0x80; sub->sid = i; pih.magic = 0; instrument_name(mod, i, pih.name, 28); D_(D_INFO "[%2X] %-28.28s %05x%c%05x %05x %c V%02x %5d", i, mod->xxi[i].name, mod->xxs[i].len, pih.type & 0x10 ? '+' : ' ', xxs->lps, xxs->lpe, xxs->flg & XMP_SAMPLE_LOOP ? 'L' : ' ', sub->vol, pih.c4spd); /* Convert C4SPD to relnote/finetune */ c2spd_to_note(pih.c4spd, &sub->xpo, &sub->fin); }
static int far_load(struct module_data *m, HIO_HANDLE *f, const int start) { struct xmp_module *mod = &m->mod; int i, j, vib = 0; struct xmp_event *event; struct far_header ffh; struct far_header2 ffh2; struct far_instrument fih; uint8 sample_map[8]; LOAD_INIT(); hio_read32b(f); /* File magic: 'FAR\xfe' */ hio_read(&ffh.name, 40, 1, f); /* Song name */ hio_read(&ffh.crlf, 3, 1, f); /* 0x0d 0x0a 0x1A */ ffh.headersize = hio_read16l(f); /* Remaining header size in bytes */ ffh.version = hio_read8(f); /* Version MSN=major, LSN=minor */ hio_read(&ffh.ch_on, 16, 1, f); /* Channel on/off switches */ hio_seek(f, 9, SEEK_CUR); /* Current editing values */ ffh.tempo = hio_read8(f); /* Default tempo */ hio_read(&ffh.pan, 16, 1, f); /* Channel pan definitions */ hio_read32l(f); /* Grid, mode (for editor) */ ffh.textlen = hio_read16l(f); /* Length of embedded text */ /* Sanity check */ if (ffh.tempo == 0) { return -1; } hio_seek(f, ffh.textlen, SEEK_CUR); /* Skip song text */ hio_read(&ffh2.order, 256, 1, f); /* Orders */ ffh2.patterns = hio_read8(f); /* Number of stored patterns (?) */ ffh2.songlen = hio_read8(f); /* Song length in patterns */ ffh2.restart = hio_read8(f); /* Restart pos */ for (i = 0; i < 256; i++) { ffh2.patsize[i] = hio_read16l(f); /* Size of each pattern in bytes */ } mod->chn = 16; /*mod->pat=ffh2.patterns; (Error in specs? --claudio) */ mod->len = ffh2.songlen; mod->spd = 6; mod->bpm = 8 * 60 / ffh.tempo; memcpy (mod->xxo, ffh2.order, mod->len); for (mod->pat = i = 0; i < 256; i++) { if (ffh2.patsize[i]) mod->pat = i + 1; } mod->trk = mod->chn * mod->pat; strncpy(mod->name, (char *)ffh.name, 40); set_type(m, "Farandole Composer %d.%d", MSN(ffh.version), LSN(ffh.version)); MODULE_INFO(); if (pattern_init(mod) < 0) return -1; /* Read and convert patterns */ D_(D_INFO "Comment bytes : %d", ffh.textlen); D_(D_INFO "Stored patterns: %d", mod->pat); for (i = 0; i < mod->pat; i++) { uint8 brk, note, ins, vol, fxb; int rows; if (pattern_alloc(mod, i) < 0) return -1; if (!ffh2.patsize[i]) continue; rows = (ffh2.patsize[i] - 2) / 64; /* Sanity check */ if (rows <= 0 || rows > 256) { return -1; } mod->xxp[i]->rows = rows; if (tracks_in_pattern_alloc(mod, i) < 0) return -1; brk = hio_read8(f) + 1; hio_read8(f); for (j = 0; j < mod->xxp[i]->rows * mod->chn; j++) { event = &EVENT(i, j % mod->chn, j / mod->chn); if ((j % mod->chn) == 0 && (j / mod->chn) == brk) event->f2t = FX_BREAK; note = hio_read8(f); ins = hio_read8(f); vol = hio_read8(f); fxb = hio_read8(f); if (note) event->note = note + 48; if (event->note || ins) event->ins = ins + 1; vol = 16 * LSN(vol) + MSN(vol); if (vol) event->vol = vol - 0x10; /* ? */ event->fxt = fx[MSN(fxb)]; event->fxp = LSN(fxb); switch (event->fxt) { case NONE: event->fxt = event->fxp = 0; break; case FX_FAR_PORTA_UP: event->fxt = FX_EXTENDED; event->fxp |= (EX_F_PORTA_UP << 4); break; case FX_FAR_PORTA_DN: event->fxt = FX_EXTENDED; event->fxp |= (EX_F_PORTA_DN << 4); break; case FX_FAR_RETRIG: event->fxt = FX_EXTENDED; event->fxp |= (EX_RETRIG << 4); break; case FX_FAR_DELAY: event->fxt = FX_EXTENDED; event->fxp |= (EX_DELAY << 4); break; case FX_FAR_SETVIBRATO: vib = event->fxp & 0x0f; event->fxt = event->fxp = 0; break; case FX_VIBRATO: event->fxp = (event->fxp << 4) + vib; break; case FX_PER_VIBRATO: event->fxp = (event->fxp << 4) + vib; break; case FX_FAR_VSLIDE_UP: /* Fine volume slide up */ event->fxt = FX_EXTENDED; event->fxp |= (EX_F_VSLIDE_UP << 4); break; case FX_FAR_VSLIDE_DN: /* Fine volume slide down */ event->fxt = FX_EXTENDED; event->fxp |= (EX_F_VSLIDE_DN << 4); break; case FX_SPEED: if (event->fxp != 0) { event->fxp = 8 * 60 / event->fxp; } else { event->fxt = 0; } break; } } } mod->ins = -1; hio_read(sample_map, 1, 8, f); for (i = 0; i < 64; i++) { if (sample_map[i / 8] & (1 << (i % 8))) mod->ins = i; } mod->ins++; mod->smp = mod->ins; if (instrument_init(mod) < 0) return -1; /* Read and convert instruments and samples */ for (i = 0; i < mod->ins; i++) { if (!(sample_map[i / 8] & (1 << (i % 8)))) continue; if (subinstrument_alloc(mod, i, 1) < 0) return -1; hio_read(&fih.name, 32, 1, f); /* Instrument name */ fih.length = hio_read32l(f); /* Length of sample (up to 64Kb) */ fih.finetune = hio_read8(f); /* Finetune (unsuported) */ fih.volume = hio_read8(f); /* Volume (unsuported?) */ fih.loop_start = hio_read32l(f);/* Loop start */ fih.loopend = hio_read32l(f); /* Loop end */ fih.sampletype = hio_read8(f); /* 1=16 bit sample */ fih.loopmode = hio_read8(f); /* Sanity check */ if (fih.length > 0x10000 || fih.loop_start > 0x10000 || fih.loopend > 0x10000) { return -1; } mod->xxs[i].len = fih.length; mod->xxs[i].lps = fih.loop_start; mod->xxs[i].lpe = fih.loopend; mod->xxs[i].flg = 0; if (mod->xxs[i].len > 0) mod->xxi[i].nsm = 1; if (fih.sampletype != 0) { mod->xxs[i].flg |= XMP_SAMPLE_16BIT; mod->xxs[i].len >>= 1; mod->xxs[i].lps >>= 1; mod->xxs[i].lpe >>= 1; } mod->xxs[i].flg |= fih.loopmode ? XMP_SAMPLE_LOOP : 0; mod->xxi[i].sub[0].vol = 0xff; /* fih.volume; */ mod->xxi[i].sub[0].sid = i; instrument_name(mod, i, fih.name, 32); D_(D_INFO "[%2X] %-32.32s %04x %04x %04x %c V%02x", i, mod->xxi[i].name, mod->xxs[i].len, mod->xxs[i].lps, mod->xxs[i].lpe, fih.loopmode ? 'L' : ' ', mod->xxi[i].sub[0].vol); if (load_sample(m, f, 0, &mod->xxs[i], NULL) < 0) return -1; }
static int amf_load(struct module_data *m, HIO_HANDLE *f, const int start) { struct xmp_module *mod = &m->mod; int i, j; struct xmp_event *event; uint8 buf[1024]; int *trkmap, newtrk; int ver; LOAD_INIT(); hio_read(buf, 1, 3, f); ver = hio_read8(f); hio_read(buf, 1, 32, f); strncpy(mod->name, (char *)buf, 32); set_type(m, "DSMI %d.%d AMF", ver / 10, ver % 10); mod->ins = hio_read8(f); mod->len = hio_read8(f); mod->trk = hio_read16l(f); mod->chn = hio_read8(f); mod->smp = mod->ins; mod->pat = mod->len; if (ver == 0x0a) hio_read(buf, 1, 16, f); /* channel remap table */ if (ver >= 0x0d) { hio_read(buf, 1, 32, f); /* panning table */ for (i = 0; i < 32; i++) { mod->xxc->pan = 0x80 + 2 * (int8)buf[i]; } mod->bpm = hio_read8(f); mod->spd = hio_read8(f); } else if (ver >= 0x0b) { hio_read(buf, 1, 16, f); } MODULE_INFO(); /* Orders */ /* * Andre Timmermans <*****@*****.**> says: * * Order table: track numbers in this table are not explained, * but as you noticed you have to perform -1 to obtain the index * in the track table. For value 0, found in some files, I think * it means an empty track. */ for (i = 0; i < mod->len; i++) mod->xxo[i] = i; D_(D_INFO "Stored patterns: %d", mod->pat); mod->xxp = calloc(sizeof(struct xmp_pattern *), mod->pat + 1); if (mod->xxp == NULL) return -1; for (i = 0; i < mod->pat; i++) { if (pattern_alloc(mod, i) < 0) return -1; mod->xxp[i]->rows = ver >= 0x0e ? hio_read16l(f) : 64; for (j = 0; j < mod->chn; j++) { uint16 t = hio_read16l(f); mod->xxp[i]->index[j] = t; } } /* Instruments */ if (instrument_init(mod) < 0) return -1; /* Probe for 2-byte loop start 1.0 format * in facing_n.amf and sweetdrm.amf have only the sample * loop start specified in 2 bytes */ if (ver <= 0x0a) { uint8 b; uint32 len, start, end; long pos = hio_tell(f); for (i = 0; i < mod->ins; i++) { b = hio_read8(f); if (b != 0 && b != 1) { ver = 0x09; break; } hio_seek(f, 32 + 13, SEEK_CUR); if (hio_read32l(f) > 0x100000) { /* check index */ ver = 0x09; break; } len = hio_read32l(f); if (len > 0x100000) { /* check len */ ver = 0x09; break; } if (hio_read16l(f) == 0x0000) { /* check c2spd */ ver = 0x09; break; } if (hio_read8(f) > 0x40) { /* check volume */ ver = 0x09; break; } start = hio_read32l(f); if (start > len) { /* check loop start */ ver = 0x09; break; } end = hio_read32l(f); if (end > len) { /* check loop end */ ver = 0x09; break; } } hio_seek(f, pos, SEEK_SET); } for (i = 0; i < mod->ins; i++) { /*uint8 b;*/ int c2spd; if (subinstrument_alloc(mod, i, 1) < 0) return -1; /*b =*/ hio_read8(f); hio_read(buf, 1, 32, f); instrument_name(mod, i, buf, 32); hio_read(buf, 1, 13, f); /* sample name */ hio_read32l(f); /* sample index */ mod->xxi[i].nsm = 1; mod->xxi[i].sub[0].sid = i; mod->xxi[i].sub[0].pan = 0x80; mod->xxs[i].len = hio_read32l(f); c2spd = hio_read16l(f); c2spd_to_note(c2spd, &mod->xxi[i].sub[0].xpo, &mod->xxi[i].sub[0].fin); mod->xxi[i].sub[0].vol = hio_read8(f); /* * Andre Timmermans <*****@*****.**> says: * * [Miodrag Vallat's] doc tells that in version 1.0 only * sample loop start is present (2 bytes) but the files I * have tells both start and end are present (2*4 bytes). * Maybe it should be read as version < 1.0. * * CM: confirmed with Maelcum's "The tribal zone" */ if (ver < 0x0a) { mod->xxs[i].lps = hio_read16l(f); mod->xxs[i].lpe = mod->xxs[i].len; } else { mod->xxs[i].lps = hio_read32l(f); mod->xxs[i].lpe = hio_read32l(f); } if (ver < 0x0a) { mod->xxs[i].flg = mod->xxs[i].lps > 0 ? XMP_SAMPLE_LOOP : 0; } else { mod->xxs[i].flg = mod->xxs[i].lpe > mod->xxs[i].lps ? XMP_SAMPLE_LOOP : 0; } D_(D_INFO "[%2X] %-32.32s %05x %05x %05x %c V%02x %5d", i, mod->xxi[i].name, mod->xxs[i].len, mod->xxs[i].lps, mod->xxs[i].lpe, mod->xxs[i].flg & XMP_SAMPLE_LOOP ? 'L' : ' ', mod->xxi[i].sub[0].vol, c2spd); } /* Tracks */ trkmap = calloc(sizeof(int), mod->trk); if (trkmap == NULL) return -1; newtrk = 0; for (i = 0; i < mod->trk; i++) { /* read track table */ uint16 t; t = hio_read16l(f); trkmap[i] = t; if (t > newtrk) newtrk = t; /*printf("%d -> %d\n", i, t);*/ } for (i = 0; i < mod->pat; i++) { /* read track table */ for (j = 0; j < mod->chn; j++) { int k = mod->xxp[i]->index[j] - 1; /* Use empty track if an invalid track is requested * (such as in Lasse Makkonen "faster and louder") */ if (k < 0 || k >= mod->trk) k = 0; mod->xxp[i]->index[j] = trkmap[k]; /*printf("mod->xxp[%d]->info[%d].index = %d (k = %d)\n", i, j, trkmap[k], k);*/ } } mod->trk = newtrk; /* + empty track */ free(trkmap); D_(D_INFO "Stored tracks: %d", mod->trk); mod->trk++; mod->xxt = calloc (sizeof (struct xmp_track *), mod->trk); if (mod->xxt == NULL) return -1; /* Alloc track 0 as empty track */ if (track_alloc(mod, 0, 64) < 0) return -1; /* Alloc rest of the tracks */ for (i = 1; i < mod->trk; i++) { uint8 t1, t2, t3; int size; if (track_alloc(mod, i, 64) < 0) return -1; size = hio_read24l(f); /*printf("TRACK %d SIZE %d\n", i, size);*/ for (j = 0; j < size; j++) { t1 = hio_read8(f); /* row */ t2 = hio_read8(f); /* type */ t3 = hio_read8(f); /* parameter */ /*printf("track %d row %d: %02x %02x %02x\n", i, t1, t1, t2, t3);*/ if (t1 == 0xff && t2 == 0xff && t3 == 0xff) break; event = &mod->xxt[i]->event[t1]; if (t2 < 0x7f) { /* note */ if (t2 > 0) event->note = t2 + 1; event->vol = t3; } else if (t2 == 0x7f) { /* copy previous */ memcpy(event, &mod->xxt[i]->event[t1 - 1], sizeof(struct xmp_event)); } else if (t2 == 0x80) { /* instrument */ event->ins = t3 + 1; } else { /* effects */ uint8 fxp, fxt; fxp = fxt = 0; switch (t2) { case 0x81: fxt = FX_SPEED; fxp = t3; break; case 0x82: if ((int8)t3 > 0) { fxt = FX_VOLSLIDE; fxp = t3 << 4; } else { fxt = FX_VOLSLIDE; fxp = -(int8)t3 & 0x0f; } break; case 0x83: event->vol = t3; break; case 0x84: /* AT: Not explained for 0x84, pitch * slide, value 0x00 corresponds to * S3M E00 and 0x80 stands for S3M F00 * (I checked with M2AMF) */ if ((int8)t3 >= 0) { fxt = FX_PORTA_DN; fxp = t3; } else if (t3 == 0x80) { fxt = FX_PORTA_UP; fxp = 0; } else { fxt = FX_PORTA_UP; fxp = -(int8)t3; } break; case 0x85: /* porta abs -- unknown */ break; case 0x86: fxt = FX_TONEPORTA; fxp = t3; break; /* AT: M2AMF maps both tremolo and tremor to * 0x87. Since tremor is only found in certain * formats, maybe it would be better to * consider it is a tremolo. */ case 0x87: fxt = FX_TREMOLO; fxp = t3; break; case 0x88: fxt = FX_ARPEGGIO; fxp = t3; break; case 0x89: fxt = FX_VIBRATO; fxp = t3; break; case 0x8a: if ((int8)t3 > 0) { fxt = FX_TONE_VSLIDE; fxp = t3 << 4; } else { fxt = FX_TONE_VSLIDE; fxp = -(int8)t3 & 0x0f; } break; case 0x8b: if ((int8)t3 > 0) { fxt = FX_VIBRA_VSLIDE; fxp = t3 << 4; } else { fxt = FX_VIBRA_VSLIDE; fxp = -(int8)t3 & 0x0f; } break; case 0x8c: fxt = FX_BREAK; fxp = t3; break; case 0x8d: fxt = FX_JUMP; fxp = t3; break; case 0x8e: /* sync -- unknown */ break; case 0x8f: fxt = FX_EXTENDED; fxp = (EX_RETRIG << 4) | (t3 & 0x0f); break; case 0x90: fxt = FX_OFFSET; fxp = t3; break; case 0x91: if ((int8)t3 > 0) { fxt = FX_EXTENDED; fxp = (EX_F_VSLIDE_UP << 4) | (t3 & 0x0f); } else { fxt = FX_EXTENDED; fxp = (EX_F_VSLIDE_DN << 4) | (t3 & 0x0f); } break; case 0x92: if ((int8)t3 > 0) { fxt = FX_PORTA_DN; fxp = 0xf0 | (fxp & 0x0f); } else { fxt = FX_PORTA_UP; fxp = 0xf0 | (fxp & 0x0f); } break; case 0x93: fxt = FX_EXTENDED; fxp = (EX_DELAY << 4) | (t3 & 0x0f); break; case 0x94: fxt = FX_EXTENDED; fxp = (EX_CUT << 4) | (t3 & 0x0f); break; case 0x95: fxt = FX_SPEED; if (t3 < 0x21) t3 = 0x21; fxp = t3; break; case 0x96: if ((int8)t3 > 0) { fxt = FX_PORTA_DN; fxp = 0xe0 | (fxp & 0x0f); } else { fxt = FX_PORTA_UP; fxp = 0xe0 | (fxp & 0x0f); } break; case 0x97: fxt = FX_SETPAN; fxp = 0x80 + 2 * (int8)t3; break; } event->fxt = fxt; event->fxp = fxp; } } } /* Samples */ D_(D_INFO "Stored samples: %d", mod->smp); for (i = 0; i < mod->ins; i++) { if (load_sample(m, f, SAMPLE_FLAG_UNS, &mod->xxs[i], NULL) < 0) return -1; } m->quirk |= QUIRK_FINEFX; return 0; }
static int chip_load(struct module_data *m, HIO_HANDLE *f, const int start) { struct xmp_module *mod = &m->mod; struct mod_header mh; uint8 *tidx; int i, j, tnum; LOAD_INIT(); if ((tidx = calloc(1, 1024)) == NULL) { goto err; } hio_read(&mh.name, 20, 1, f); hio_read16b(f); for (i = 0; i < 31; i++) { hio_read(&mh.ins[i].name, 22, 1, f); mh.ins[i].size = hio_read16b(f); mh.ins[i].finetune = hio_read8(f); mh.ins[i].volume = hio_read8(f); mh.ins[i].loop_start = hio_read16b(f); mh.ins[i].loop_size = hio_read16b(f); } hio_read(&mh.magic, 4, 1, f); mh.len = hio_read8(f); mh.restart = hio_read8(f); hio_read(tidx, 1024, 1, f); hio_read16b(f); mod->chn = 4; mod->ins = 31; mod->smp = mod->ins; mod->len = mh.len; mod->pat = mh.len; mod->rst = mh.restart; tnum = 0; for (i = 0; i < mod->len; i++) { mod->xxo[i] = i; for (j = 0; j < 4; j++) { int t = tidx[2 * (4 * i + j)]; if (t > tnum) tnum = t; } } mod->trk = tnum + 1; strncpy(mod->name, (char *)mh.name, 20); set_type(m, "Chiptracker"); MODULE_INFO(); if (instrument_init(mod) < 0) goto err2; for (i = 0; i < mod->ins; i++) { struct xmp_instrument *xxi = &mod->xxi[i]; struct xmp_sample *xxs = &mod->xxs[i]; struct xmp_subinstrument *sub; if (subinstrument_alloc(mod, i, 1) < 0) goto err2; sub = &xxi->sub[0]; xxs->len = 2 * mh.ins[i].size; xxs->lps = mh.ins[i].loop_start; xxs->lpe = xxs->lps + 2 * mh.ins[i].loop_size; xxs->flg = mh.ins[i].loop_size > 1 ? XMP_SAMPLE_LOOP : 0; sub->fin = (int8) (mh.ins[i].finetune << 4); sub->vol = mh.ins[i].volume; sub->pan = 0x80; sub->sid = i; if (xxs->len > 0) xxi->nsm = 1; instrument_name(mod, i, mh.ins[i].name, 22); } if (pattern_init(mod) < 0) goto err2; for (i = 0; i < mod->len; i++) { if (pattern_alloc(mod, i) < 0) goto err2; mod->xxp[i]->rows = 64; for (j = 0; j < 4; j++) { int t = tidx[2 * (4 * i + j)]; mod->xxp[i]->index[j] = t; } } /* Load and convert tracks */ D_(D_INFO "Stored tracks: %d", mod->trk); for (i = 0; i < mod->trk; i++) { if (track_alloc(mod, i, 64) < 0) goto err2; for (j = 0; j < 64; j++) { struct xmp_event *event = &mod->xxt[i]->event[j]; uint8 e[4]; hio_read(e, 1, 4, f); if (e[0] && e[0] != 0xa8) event->note = 13 + e[0] / 2; event->ins = e[1]; event->fxt = e[2] & 0x0f; event->fxp = e[3]; } } m->quirk |= QUIRK_MODRNG; /* Load samples */ D_(D_INFO "Stored samples: %d", mod->smp); for (i = 0; i < mod->smp; i++) { if (mod->xxs[i].len == 0) continue; if (load_sample(m, f, SAMPLE_FLAG_FULLREP, &mod->xxs[i], NULL) < 0) goto err2; } free(tidx); return 0; err2: free(tidx); err: return -1; }
static int stx_load(struct module_data *m, HIO_HANDLE *f, const int start) { struct xmp_module *mod = &m->mod; int c, r, i, broken = 0; struct xmp_event *event = 0, dummy; struct stx_file_header sfh; struct stx_instrument_header sih; uint8 n, b; uint16 x16; int bmod2stm = 0; uint16 *pp_ins; /* Parapointers to instruments */ uint16 *pp_pat; /* Parapointers to patterns */ LOAD_INIT(); hio_read(&sfh.name, 20, 1, f); hio_read(&sfh.magic, 8, 1, f); sfh.psize = hio_read16l(f); sfh.unknown1 = hio_read16l(f); sfh.pp_pat = hio_read16l(f); sfh.pp_ins = hio_read16l(f); sfh.pp_chn = hio_read16l(f); sfh.unknown2 = hio_read16l(f); sfh.unknown3 = hio_read16l(f); sfh.gvol = hio_read8(f); sfh.tempo = hio_read8(f); sfh.unknown4 = hio_read16l(f); sfh.unknown5 = hio_read16l(f); sfh.patnum = hio_read16l(f); sfh.insnum = hio_read16l(f); sfh.ordnum = hio_read16l(f); sfh.unknown6 = hio_read16l(f); sfh.unknown7 = hio_read16l(f); sfh.unknown8 = hio_read16l(f); hio_read(&sfh.magic2, 4, 1, f); /* Sanity check */ if (sfh.patnum > 254 || sfh.insnum > 256 || sfh.ordnum > 256) return -1; /* BMOD2STM does not convert pitch */ if (!strncmp ((char *) sfh.magic, "BMOD2STM", 8)) bmod2stm = 1; #if 0 if ((strncmp ((char *) sfh.magic, "!Scream!", 8) && !bmod2stm) || strncmp ((char *) sfh.magic2, "SCRM", 4)) return -1; #endif mod->ins = sfh.insnum; mod->pat = sfh.patnum; mod->trk = mod->pat * mod->chn; mod->len = sfh.ordnum; mod->spd = MSN (sfh.tempo); mod->smp = mod->ins; m->c4rate = C4_NTSC_RATE; /* STM2STX 1.0 released with STMIK 0.2 converts STMs with the pattern * length encoded in the first two bytes of the pattern (like S3M). */ hio_seek(f, start + (sfh.pp_pat << 4), SEEK_SET); x16 = hio_read16l(f); hio_seek(f, start + (x16 << 4), SEEK_SET); x16 = hio_read16l(f); if (x16 == sfh.psize) broken = 1; strncpy(mod->name, (char *)sfh.name, 20); if (bmod2stm) set_type(m, "BMOD2STM STX"); else snprintf(mod->type, XMP_NAME_SIZE, "STM2STX 1.%d", broken ? 0 : 1); MODULE_INFO(); pp_pat = calloc (2, mod->pat); if (pp_pat == NULL) goto err; pp_ins = calloc (2, mod->ins); if (pp_ins == NULL) goto err2; /* Read pattern pointers */ hio_seek(f, start + (sfh.pp_pat << 4), SEEK_SET); for (i = 0; i < mod->pat; i++) pp_pat[i] = hio_read16l(f); /* Read instrument pointers */ hio_seek(f, start + (sfh.pp_ins << 4), SEEK_SET); for (i = 0; i < mod->ins; i++) pp_ins[i] = hio_read16l(f); /* Skip channel table (?) */ hio_seek(f, start + (sfh.pp_chn << 4) + 32, SEEK_SET); /* Read orders */ for (i = 0; i < mod->len; i++) { mod->xxo[i] = hio_read8(f); hio_seek(f, 4, SEEK_CUR); } if (instrument_init(mod) < 0) goto err3; /* Read and convert instruments and samples */ for (i = 0; i < mod->ins; i++) { if (subinstrument_alloc(mod, i, 1) < 0) goto err3; hio_seek(f, start + (pp_ins[i] << 4), SEEK_SET); sih.type = hio_read8(f); hio_read(&sih.dosname, 13, 1, f); sih.memseg = hio_read16l(f); sih.length = hio_read32l(f); sih.loopbeg = hio_read32l(f); sih.loopend = hio_read32l(f); sih.vol = hio_read8(f); sih.rsvd1 = hio_read8(f); sih.pack = hio_read8(f); sih.flags = hio_read8(f); sih.c2spd = hio_read16l(f); sih.rsvd2 = hio_read16l(f); hio_read(&sih.rsvd3, 4, 1, f); sih.int_gp = hio_read16l(f); sih.int_512 = hio_read16l(f); sih.int_last = hio_read32l(f); hio_read(&sih.name, 28, 1, f); hio_read(&sih.magic, 4, 1, f); mod->xxs[i].len = sih.length; mod->xxs[i].lps = sih.loopbeg; mod->xxs[i].lpe = sih.loopend; if (mod->xxs[i].lpe == 0xffff) mod->xxs[i].lpe = 0; mod->xxs[i].flg = mod->xxs[i].lpe > 0 ? XMP_SAMPLE_LOOP : 0; mod->xxi[i].sub[0].vol = sih.vol; mod->xxi[i].sub[0].pan = 0x80; mod->xxi[i].sub[0].sid = i; mod->xxi[i].nsm = 1; instrument_name(mod, i, sih.name, 12); D_(D_INFO "[%2X] %-14.14s %04x %04x %04x %c V%02x %5d\n", i, mod->xxi[i].name, mod->xxs[i].len, mod->xxs[i].lps, mod->xxs[i].lpe, mod->xxs[i].flg & XMP_SAMPLE_LOOP ? 'L' : ' ', mod->xxi[i].sub[0].vol, sih.c2spd); sih.c2spd = 8363 * sih.c2spd / 8448; c2spd_to_note(sih.c2spd, &mod->xxi[i].sub[0].xpo, &mod->xxi[i].sub[0].fin); } if (pattern_init(mod) < 0) goto err3; /* Read and convert patterns */ D_(D_INFO "Stored patterns: %d", mod->pat); for (i = 0; i < mod->pat; i++) { if (pattern_tracks_alloc(mod, i, 64) < 0) goto err3; if (pp_pat[i] == 0) continue; hio_seek(f, start + (pp_pat[i] << 4), SEEK_SET); if (broken) hio_seek(f, 2, SEEK_CUR); for (r = 0; r < 64; ) { b = hio_read8(f); if (b == S3M_EOR) { r++; continue; } c = b & S3M_CH_MASK; event = c >= mod->chn ? &dummy : &EVENT (i, c, r); if (b & S3M_NI_FOLLOW) { n = hio_read8(f); switch (n) { case 255: n = 0; break; /* Empty note */ case 254: n = XMP_KEY_OFF; break; /* Key off */ default: n = 37 + 12 * MSN (n) + LSN (n); } event->note = n; event->ins = hio_read8(f);; } if (b & S3M_VOL_FOLLOWS) { event->vol = hio_read8(f) + 1; } if (b & S3M_FX_FOLLOWS) { event->fxt = fx[hio_read8(f)]; event->fxp = hio_read8(f); switch (event->fxt) { case FX_SPEED: event->fxp = MSN (event->fxp); break; case FX_NONE: event->fxp = event->fxt = 0; break; } } } } free (pp_ins); free (pp_pat); /* Read samples */ D_(D_INFO "Stored samples: %d", mod->smp); for (i = 0; i < mod->ins; i++) { if (load_sample(m, f, 0, &mod->xxs[i], NULL) < 0) goto err; } m->quirk |= QUIRK_VSALL | QUIRKS_ST3; m->read_event_type = READ_EVENT_ST3; return 0; err3: free(pp_ins); err2: free(pp_pat); err: return -1; }
static int mod_load(struct module_data *m, HIO_HANDLE *f, const int start) { struct xmp_module *mod = &m->mod; int i, j; int smp_size, pat_size, wow, ptsong = 0; struct xmp_event *event; struct mod_header mh; uint8 mod_event[4]; char *x, pathname[PATH_MAX] = "", *tracker = ""; int detected = 0; char magic[8], idbuffer[32]; int ptkloop = 0; /* Protracker loop */ int tracker_id = TRACKER_PROTRACKER; LOAD_INIT(); mod->ins = 31; mod->smp = mod->ins; mod->chn = 0; smp_size = 0; pat_size = 0; m->quirk |= QUIRK_MODRNG; hio_read(&mh.name, 20, 1, f); for (i = 0; i < 31; i++) { hio_read(&mh.ins[i].name, 22, 1, f); /* Instrument name */ mh.ins[i].size = hio_read16b(f); /* Length in 16-bit words */ mh.ins[i].finetune = hio_read8(f); /* Finetune (signed nibble) */ mh.ins[i].volume = hio_read8(f); /* Linear playback volume */ mh.ins[i].loop_start = hio_read16b(f); /* Loop start in 16-bit words */ mh.ins[i].loop_size = hio_read16b(f); /* Loop size in 16-bit words */ smp_size += 2 * mh.ins[i].size; } mh.len = hio_read8(f); mh.restart = hio_read8(f); hio_read(&mh.order, 128, 1, f); memset(magic, 0, 8); hio_read(magic, 4, 1, f); for (i = 0; mod_magic[i].ch; i++) { if (!(strncmp (magic, mod_magic[i].magic, 4))) { mod->chn = mod_magic[i].ch; tracker_id = mod_magic[i].id; detected = mod_magic[i].flag; break; } } if (!mod->chn) { if (!strncmp(magic + 2, "CH", 2) && isdigit((int)magic[0]) && isdigit((int)magic[1])) { mod->chn = (*magic - '0') * 10 + magic[1] - '0'; } else if (!strncmp(magic + 1, "CHN", 3) && isdigit((int)*magic)) { mod->chn = *magic - '0'; } else { return -1; } tracker_id = mod->chn & 1 ? TRACKER_TAKETRACKER : TRACKER_FASTTRACKER2; detected = 1; m->quirk &= ~QUIRK_MODRNG; } strncpy(mod->name, (char *) mh.name, 20); mod->len = mh.len; /* mod->rst = mh.restart; */ if (mod->rst >= mod->len) mod->rst = 0; memcpy(mod->xxo, mh.order, 128); for (i = 0; i < 128; i++) { /* This fixes dragnet.mod (garbage in the order list) */ if (mod->xxo[i] > 0x7f) break; if (mod->xxo[i] > mod->pat) mod->pat = mod->xxo[i]; } mod->pat++; pat_size = 256 * mod->chn * mod->pat; if (instrument_init(mod) < 0) return -1; for (i = 0; i < mod->ins; i++) { if (subinstrument_alloc(mod, i, 1) < 0) return -1; mod->xxs[i].len = 2 * mh.ins[i].size; mod->xxs[i].lps = 2 * mh.ins[i].loop_start; mod->xxs[i].lpe = mod->xxs[i].lps + 2 * mh.ins[i].loop_size; if (mod->xxs[i].lpe > mod->xxs[i].len) mod->xxs[i].lpe = mod->xxs[i].len; mod->xxs[i].flg = (mh.ins[i].loop_size > 1 && mod->xxs[i].lpe >= 4) ? XMP_SAMPLE_LOOP : 0; mod->xxi[i].sub[0].fin = (int8)(mh.ins[i].finetune << 4); mod->xxi[i].sub[0].vol = mh.ins[i].volume; mod->xxi[i].sub[0].pan = 0x80; mod->xxi[i].sub[0].sid = i; instrument_name(mod, i, mh.ins[i].name, 22); if (mod->xxs[i].len > 0) mod->xxi[i].nsm = 1; } /* * Experimental tracker-detection routine */ if (detected) goto skip_test; /* Test for Flextrax modules * * FlexTrax is a soundtracker for Atari Falcon030 compatible computers. * FlexTrax supports the standard MOD file format (up to eight channels) * for compatibility reasons but also features a new enhanced module * format FLX. The FLX format is an extended version of the standard * MOD file format with support for real-time sound effects like reverb * and delay. */ if (0x43c + mod->pat * 4 * mod->chn * 0x40 + smp_size < m->size) { int pos = hio_tell(f); hio_seek(f, start + 0x43c + mod->pat * 4 * mod->chn * 0x40 + smp_size, SEEK_SET); hio_read(idbuffer, 1, 4, f); hio_seek(f, start + pos, SEEK_SET); if (!memcmp(idbuffer, "FLEX", 4)) { tracker_id = TRACKER_FLEXTRAX; goto skip_test; } } /* Test for Mod's Grave WOW modules * * Stefan Danes <*****@*****.**> said: * This weird format is identical to '8CHN' but still uses the 'M.K.' ID. * You can only test for WOW by calculating the size of the module for 8 * channels and comparing this to the actual module length. If it's equal, * the module is an 8 channel WOW. */ if ((wow = (!strncmp(magic, "M.K.", 4) && (0x43c + mod->pat * 32 * 0x40 + smp_size == m->size)))) { mod->chn = 8; tracker_id = TRACKER_MODSGRAVE; goto skip_test; } /* Test for Protracker song files */ else if ((ptsong = (!strncmp((char *)magic, "M.K.", 4) && (0x43c + mod->pat * 0x400 == m->size)))) { tracker_id = TRACKER_PROTRACKER; goto skip_test; } /* Test Protracker-like files */ if (mod->chn == 4 && mh.restart == mod->pat) { tracker_id = TRACKER_SOUNDTRACKER; } else if (mod->chn == 4 && mh.restart == 0x78) { tracker_id = TRACKER_NOISETRACKER; } else if (mh.restart < 0x7f) { if (mod->chn == 4) { tracker_id = TRACKER_NOISETRACKER; } else { tracker_id = TRACKER_UNKNOWN; } mod->rst = mh.restart; } if (mod->chn != 4 && mh.restart == 0x7f) { tracker_id = TRACKER_SCREAMTRACKER3; m->quirk &= ~QUIRK_MODRNG; m->read_event_type = READ_EVENT_ST3; } if (mod->chn == 4 && mh.restart == 0x7f) { for (i = 0; i < 31; i++) { if (mh.ins[i].loop_size == 0) break; } if (i < 31) { tracker_id = TRACKER_CLONE; } } if (mh.restart != 0x78 && mh.restart < 0x7f) { for (i = 0; i < 31; i++) { if (mh.ins[i].loop_size == 0) break; } if (i == 31) { /* All loops are size 2 or greater */ for (i = 0; i < 31; i++) { if (mh.ins[i].size == 1 && mh.ins[i].volume == 0) { tracker_id = TRACKER_CONVERTED; goto skip_test; } } for (i = 0; i < 31; i++) { if (is_st_ins((char *)mh.ins[i].name)) break; } if (i == 31) { /* No st- instruments */ for (i = 0; i < 31; i++) { if (mh.ins[i].size == 0 && mh.ins[i].loop_size == 1) { switch (mod->chn) { case 4: tracker_id = TRACKER_NOISETRACKER; /* or Octalyser */ break; case 6: case 8: tracker_id = TRACKER_OCTALYSER; break; default: tracker_id = TRACKER_UNKNOWN; } goto skip_test; } } if (mod->chn == 4) { tracker_id = TRACKER_PROTRACKER; } else if (mod->chn == 6 || mod->chn == 8) { tracker_id = TRACKER_FASTTRACKER; /* FastTracker 1.01? */ m->quirk &= ~QUIRK_MODRNG; } else { tracker_id = TRACKER_UNKNOWN; } } } else { /* Has loops with 0 size */ for (i = 15; i < 31; i++) { if (strlen((char *)mh.ins[i].name) || mh.ins[i].size > 0) break; } if (i == 31 && is_st_ins((char *)mh.ins[14].name)) { tracker_id = TRACKER_CONVERTEDST; goto skip_test; } /* Assume that Fast Tracker modules won't have ST- instruments */ for (i = 0; i < 31; i++) { if (is_st_ins((char *)mh.ins[i].name)) break; } if (i < 31) { tracker_id = TRACKER_UNKNOWN_CONV; goto skip_test; } if (mod->chn == 4 || mod->chn == 6 || mod->chn == 8) { tracker_id = TRACKER_FASTTRACKER; m->quirk &= ~QUIRK_MODRNG; goto skip_test; } tracker_id = TRACKER_UNKNOWN; /* ??!? */ } } skip_test: switch (tracker_id) { case TRACKER_PROTRACKER: tracker = "Protracker"; ptkloop = 1; break; case TRACKER_NOISETRACKER: tracker = "Noisetracker"; ptkloop = 1; break; case TRACKER_SOUNDTRACKER: tracker = "Soundtracker"; ptkloop = 1; break; case TRACKER_FASTTRACKER: tracker = "Fast Tracker"; break; case TRACKER_FASTTRACKER2: tracker = "FastTracker 2"; break; case TRACKER_OCTALYSER: tracker = "Octalyser"; break; case TRACKER_TAKETRACKER: tracker = "TakeTracker"; break; case TRACKER_DIGITALTRACKER: tracker = "Digital Tracker"; break; case TRACKER_FLEXTRAX: tracker = "Flextrax"; break; case TRACKER_MODSGRAVE: tracker = "Mod's Grave"; break; case TRACKER_SCREAMTRACKER3: tracker = "Scream Tracker III"; break; case TRACKER_UNKNOWN_CONV: tracker = "unknown or converted"; break; case TRACKER_CONVERTEDST: tracker = "converted ST2.2 or earlier"; break; case TRACKER_CONVERTED: tracker = "converted"; break; case TRACKER_CLONE: tracker = "Protracker clone"; break; default: case TRACKER_UNKNOWN: tracker = "unknown"; break; } mod->trk = mod->chn * mod->pat; snprintf(mod->type, XMP_NAME_SIZE, "%s (%s)", tracker, magic); MODULE_INFO(); for (i = 0; i < mod->ins; i++) { D_(D_INFO "[%2X] %-22.22s %04x %04x %04x %c V%02x %+d %c\n", i, mod->xxi[i].name, mod->xxs[i].len, mod->xxs[i].lps, mod->xxs[i].lpe, (mh.ins[i].loop_size > 1 && mod->xxs[i].lpe > 8) ? 'L' : ' ', mod->xxi[i].sub[0].vol, mod->xxi[i].sub[0].fin >> 4, ptkloop && mod->xxs[i].lps == 0 && mh.ins[i].loop_size > 1 && mod->xxs[i].len > mod->xxs[i].lpe ? '!' : ' '); } if (pattern_init(mod) < 0) return -1; /* Load and convert patterns */ D_(D_INFO "Stored patterns: %d", mod->pat); for (i = 0; i < mod->pat; i++) { if (pattern_tracks_alloc(mod, i, 64) < 0) return -1; for (j = 0; j < (64 * mod->chn); j++) { event = &EVENT (i, j % mod->chn, j / mod->chn); hio_read (mod_event, 1, 4, f); switch (tracker_id) { case TRACKER_NOISETRACKER: decode_noisetracker_event(event, mod_event); break; case TRACKER_PROTRACKER: default: decode_protracker_event(event, mod_event); break; } } } /* Load samples */ if (m->filename && (x = strrchr(m->filename, '/'))) strncpy(pathname, m->filename, x - m->filename); D_(D_INFO "Stored samples: %d", mod->smp); for (i = 0; i < mod->smp; i++) { int flags; if (!mod->xxs[i].len) continue; flags = ptkloop ? SAMPLE_FLAG_FULLREP : 0; if (ptsong) { HIO_HANDLE *s; char sn[256]; snprintf(sn, XMP_NAME_SIZE, "%s%s", pathname, mod->xxi[i].name); if ((s = hio_open_file(sn, "rb"))) { if (load_sample(m, s, flags, &mod->xxs[i], NULL) < 0) { hio_close(s); return -1; } hio_close(s); } } else { if (load_sample(m, f, flags, &mod->xxs[i], NULL) < 0) return -1; } } if (mod->chn > 4) { m->quirk &= ~QUIRK_MODRNG; m->quirk |= QUIRKS_FT2; m->read_event_type = READ_EVENT_FT2; } else if (strcmp(tracker, "Protracker") == 0) { m->quirk |= QUIRK_INVLOOP; } return 0; }
static int gdm_load(struct module_data *m, HIO_HANDLE *f, const int start) { struct xmp_module *mod = &m->mod; struct xmp_event *event; int vermaj, vermin, tvmaj, tvmin, tracker; int /*origfmt,*/ ord_ofs, pat_ofs, ins_ofs, smp_ofs; uint8 buffer[32], panmap[32]; int i; LOAD_INIT(); hio_read32b(f); /* skip magic */ hio_read(mod->name, 1, 32, f); hio_seek(f, 32, SEEK_CUR); /* skip author */ hio_seek(f, 7, SEEK_CUR); vermaj = hio_read8(f); vermin = hio_read8(f); tracker = hio_read16l(f); tvmaj = hio_read8(f); tvmin = hio_read8(f); if (tracker == 0) { set_type(m, "GDM %d.%02d (2GDM %d.%02d)", vermaj, vermin, tvmaj, tvmin); } else { set_type(m, "GDM %d.%02d (unknown tracker %d.%02d)", vermaj, vermin, tvmaj, tvmin); } hio_read(panmap, 32, 1, f); for (i = 0; i < 32; i++) { if (panmap[i] == 255) { panmap[i] = 8; mod->xxc[i].vol = 0; mod->xxc[i].flg |= XMP_CHANNEL_MUTE; } else if (panmap[i] == 16) { panmap[i] = 8; } mod->xxc[i].pan = 0x80 + (panmap[i] - 8) * 16; } mod->gvl = hio_read8(f); mod->spd = hio_read8(f); mod->bpm = hio_read8(f); /*origfmt =*/ hio_read16l(f); ord_ofs = hio_read32l(f); mod->len = hio_read8(f) + 1; pat_ofs = hio_read32l(f); mod->pat = hio_read8(f) + 1; ins_ofs = hio_read32l(f); smp_ofs = hio_read32l(f); mod->ins = mod->smp = hio_read8(f) + 1; MODULE_INFO(); hio_seek(f, start + ord_ofs, SEEK_SET); for (i = 0; i < mod->len; i++) mod->xxo[i] = hio_read8(f); /* Read instrument data */ hio_seek(f, start + ins_ofs, SEEK_SET); if (instrument_init(mod) < 0) return -1; for (i = 0; i < mod->ins; i++) { int flg, c4spd, vol, pan; if (subinstrument_alloc(mod, i, 1) < 0) return -1; hio_read(buffer, 32, 1, f); instrument_name(mod, i, buffer, 32); hio_seek(f, 12, SEEK_CUR); /* skip filename */ hio_read8(f); /* skip EMS handle */ mod->xxs[i].len = hio_read32l(f); mod->xxs[i].lps = hio_read32l(f); mod->xxs[i].lpe = hio_read32l(f); flg = hio_read8(f); c4spd = hio_read16l(f); vol = hio_read8(f); pan = hio_read8(f); mod->xxi[i].sub[0].vol = vol > 0x40 ? 0x40 : vol; mod->xxi[i].sub[0].pan = pan > 15 ? 0x80 : 0x80 + (pan - 8) * 16; c2spd_to_note(c4spd, &mod->xxi[i].sub[0].xpo, &mod->xxi[i].sub[0].fin); mod->xxi[i].sub[0].sid = i; mod->xxs[i].flg = 0; if (mod->xxs[i].len > 0) mod->xxi[i].nsm = 1; if (flg & 0x01) { mod->xxs[i].flg |= XMP_SAMPLE_LOOP; } if (flg & 0x02) { mod->xxs[i].flg |= XMP_SAMPLE_16BIT; mod->xxs[i].len >>= 1; mod->xxs[i].lps >>= 1; mod->xxs[i].lpe >>= 1; } D_(D_INFO "[%2X] %-32.32s %05x%c%05x %05x %c V%02x P%02x %5d", i, mod->xxi[i].name, mod->xxs[i].len, mod->xxs[i].flg & XMP_SAMPLE_16BIT ? '+' : ' ', mod->xxs[i].lps, mod->xxs[i].lpe, mod->xxs[i].flg & XMP_SAMPLE_LOOP ? 'L' : ' ', mod->xxi[i].sub[0].vol, mod->xxi[i].sub[0].pan, c4spd); }
static int mtm_load(struct module_data *m, HIO_HANDLE *f, const int start) { struct xmp_module *mod = &m->mod; int i, j; struct mtm_file_header mfh; struct mtm_instrument_header mih; uint8 mt[192]; uint16 mp[32]; LOAD_INIT(); hio_read(&mfh.magic, 3, 1, f); /* "MTM" */ mfh.version = hio_read8(f); /* MSN=major, LSN=minor */ hio_read(&mfh.name, 20, 1, f); /* ASCIIZ Module name */ mfh.tracks = hio_read16l(f); /* Number of tracks saved */ mfh.patterns = hio_read8(f); /* Number of patterns saved */ mfh.modlen = hio_read8(f); /* Module length */ mfh.extralen = hio_read16l(f); /* Length of the comment field */ mfh.samples = hio_read8(f); /* Number of samples */ mfh.attr = hio_read8(f); /* Always zero */ mfh.rows = hio_read8(f); /* Number rows per track */ mfh.channels = hio_read8(f); /* Number of tracks per pattern */ hio_read(&mfh.pan, 32, 1, f); /* Pan positions for each channel */ #if 0 if (strncmp ((char *)mfh.magic, "MTM", 3)) return -1; #endif mod->trk = mfh.tracks + 1; mod->pat = mfh.patterns + 1; mod->len = mfh.modlen + 1; mod->ins = mfh.samples; mod->smp = mod->ins; mod->chn = mfh.channels; mod->spd = 6; mod->bpm = 125; strncpy(mod->name, (char *)mfh.name, 20); set_type(m, "MultiTracker %d.%02d MTM", MSN(mfh.version), LSN(mfh.version)); MODULE_INFO(); if (instrument_init(mod) < 0) return -1; /* Read and convert instruments */ for (i = 0; i < mod->ins; i++) { if (subinstrument_alloc(mod, i, 1) < 0) return -1; hio_read(&mih.name, 22, 1, f); /* Instrument name */ mih.length = hio_read32l(f); /* Instrument length in bytes */ mih.loop_start = hio_read32l(f); /* Sample loop start */ mih.loopend = hio_read32l(f); /* Sample loop end */ mih.finetune = hio_read8(f); /* Finetune */ mih.volume = hio_read8(f); /* Playback volume */ mih.attr = hio_read8(f); /* &0x01: 16bit sample */ mod->xxs[i].len = mih.length; mod->xxs[i].lps = mih.loop_start; mod->xxs[i].lpe = mih.loopend; mod->xxs[i].flg = mod->xxs[i].lpe ? XMP_SAMPLE_LOOP : 0; /* 1 == Forward loop */ if (mfh.attr & 1) { mod->xxs[i].flg |= XMP_SAMPLE_16BIT; mod->xxs[i].len >>= 1; mod->xxs[i].lps >>= 1; mod->xxs[i].lpe >>= 1; } mod->xxi[i].sub[0].vol = mih.volume; mod->xxi[i].sub[0].fin = mih.finetune; mod->xxi[i].sub[0].pan = 0x80; mod->xxi[i].sub[0].sid = i; instrument_name(mod, i, mih.name, 22); if (mod->xxs[i].len > 0) mod->xxi[i].nsm = 1; D_(D_INFO "[%2X] %-22.22s %04x%c%04x %04x %c V%02x F%+03d\n", i, mod->xxi[i].name, mod->xxs[i].len, mod->xxs[i].flg & XMP_SAMPLE_16BIT ? '+' : ' ', mod->xxs[i].lps, mod->xxs[i].lpe, mod->xxs[i].flg & XMP_SAMPLE_LOOP ? 'L' : ' ', mod->xxi[i].sub[0].vol, mod->xxi[i].sub[0].fin - 0x80); }
static int mod_load(struct module_data *m, HIO_HANDLE *f, const int start) { struct xmp_module *mod = &m->mod; int i, j; struct xmp_event *event; struct mod_header mh; uint8 mod_event[4]; char magic[8]; int ptkloop = 0; /* Protracker loop */ LOAD_INIT(); mod->ins = 31; mod->smp = mod->ins; mod->chn = 0; m->quirk |= QUIRK_MODRNG; hio_read(&mh.name, 20, 1, f); for (i = 0; i < 31; i++) { hio_read(&mh.ins[i].name, 22, 1, f); /* Instrument name */ mh.ins[i].size = hio_read16b(f); /* Length in 16-bit words */ mh.ins[i].finetune = hio_read8(f); /* Finetune (signed nibble) */ mh.ins[i].volume = hio_read8(f); /* Linear playback volume */ mh.ins[i].loop_start = hio_read16b(f); /* Loop start in 16-bit words */ mh.ins[i].loop_size = hio_read16b(f); /* Loop size in 16-bit words */ } mh.len = hio_read8(f); mh.restart = hio_read8(f); hio_read(&mh.order, 128, 1, f); memset(magic, 0, 8); hio_read(magic, 4, 1, f); if (!memcmp(magic, "M.K.", 4)) { mod->chn = 4; } else if (!strncmp(magic + 2, "CH", 2) && isdigit((int)magic[0]) && isdigit((int)magic[1])) { mod->chn = (*magic - '0') * 10 + magic[1] - '0'; } else if (!strncmp(magic + 1, "CHN", 3) && isdigit((int)*magic)) { mod->chn = *magic - '0'; } else { return -1; } strncpy(mod->name, (char *) mh.name, 20); mod->len = mh.len; /* mod->rst = mh.restart; */ if (mod->rst >= mod->len) mod->rst = 0; memcpy(mod->xxo, mh.order, 128); for (i = 0; i < 128; i++) { /* This fixes dragnet.mod (garbage in the order list) */ if (mod->xxo[i] > 0x7f) break; if (mod->xxo[i] > mod->pat) mod->pat = mod->xxo[i]; } mod->pat++; if (instrument_init(mod) < 0) return -1; for (i = 0; i < mod->ins; i++) { if (subinstrument_alloc(mod, i, 1) < 0) return -1; mod->xxs[i].len = 2 * mh.ins[i].size; mod->xxs[i].lps = 2 * mh.ins[i].loop_start; mod->xxs[i].lpe = mod->xxs[i].lps + 2 * mh.ins[i].loop_size; if (mod->xxs[i].lpe > mod->xxs[i].len) mod->xxs[i].lpe = mod->xxs[i].len; mod->xxs[i].flg = (mh.ins[i].loop_size > 1 && mod->xxs[i].lpe >= 4) ? XMP_SAMPLE_LOOP : 0; mod->xxi[i].sub[0].fin = (int8)(mh.ins[i].finetune << 4); mod->xxi[i].sub[0].vol = mh.ins[i].volume; mod->xxi[i].sub[0].pan = 0x80; mod->xxi[i].sub[0].sid = i; instrument_name(mod, i, mh.ins[i].name, 22); if (mod->xxs[i].len > 0) mod->xxi[i].nsm = 1; } mod->trk = mod->chn * mod->pat; set_type(m, mod->chn == 4 ? "Protracker" : "Fasttracker"); MODULE_INFO(); for (i = 0; i < mod->ins; i++) { D_(D_INFO "[%2X] %-22.22s %04x %04x %04x %c V%02x %+d %c\n", i, mod->xxi[i].name, mod->xxs[i].len, mod->xxs[i].lps, mod->xxs[i].lpe, (mh.ins[i].loop_size > 1 && mod->xxs[i].lpe > 8) ? 'L' : ' ', mod->xxi[i].sub[0].vol, mod->xxi[i].sub[0].fin >> 4, ptkloop && mod->xxs[i].lps == 0 && mh.ins[i].loop_size > 1 && mod->xxs[i].len > mod->xxs[i].lpe ? '!' : ' '); } if (pattern_init(mod) < 0) return -1; /* Load and convert patterns */ D_(D_INFO "Stored patterns: %d", mod->pat); for (i = 0; i < mod->pat; i++) { if (pattern_tracks_alloc(mod, i, 64) < 0) return -1; for (j = 0; j < (64 * mod->chn); j++) { event = &EVENT (i, j % mod->chn, j / mod->chn); hio_read (mod_event, 1, 4, f); decode_protracker_event(event, mod_event); } } /* Load samples */ D_(D_INFO "Stored samples: %d", mod->smp); for (i = 0; i < mod->smp; i++) { int flags; if (!mod->xxs[i].len) continue; flags = ptkloop ? SAMPLE_FLAG_FULLREP : 0; if (load_sample(m, f, flags, &mod->xxs[i], NULL) < 0) return -1; } if (mod->chn > 4) { m->quirk &= ~QUIRK_MODRNG; m->quirk |= QUIRKS_FT2; m->read_event_type = READ_EVENT_FT2; } return 0; }
static int asylum_load(struct module_data *m, HIO_HANDLE *f, const int start) { struct xmp_module *mod = &m->mod; struct xmp_event *event; int i, j; LOAD_INIT(); hio_seek(f, 32, SEEK_CUR); /* skip magic */ mod->spd = hio_read8(f); /* initial speed */ mod->bpm = hio_read8(f); /* initial BPM */ mod->ins = hio_read8(f); /* number of instruments */ mod->pat = hio_read8(f); /* number of patterns */ mod->len = hio_read8(f); /* module length */ hio_read8(f); hio_read(mod->xxo, 1, mod->len, f); /* read orders */ hio_seek(f, start + 294, SEEK_SET); mod->chn = 8; mod->smp = mod->ins; mod->trk = mod->pat * mod->chn; snprintf(mod->type, XMP_NAME_SIZE, "Asylum Music Format v1.0"); MODULE_INFO(); if (instrument_init(mod) < 0) return -1; /* Read and convert instruments and samples */ for (i = 0; i < mod->ins; i++) { uint8 insbuf[37]; if (subinstrument_alloc(mod, i, 1) < 0) return -1; hio_read(insbuf, 1, 37, f); instrument_name(mod, i, insbuf, 22); mod->xxi[i].sub[0].fin = (int8)(insbuf[22] << 4); mod->xxi[i].sub[0].vol = insbuf[23]; mod->xxi[i].sub[0].xpo = (int8)insbuf[24]; mod->xxi[i].sub[0].pan = 0x80; mod->xxi[i].sub[0].sid = i; mod->xxs[i].len = readmem32l(insbuf + 25); mod->xxs[i].lps = readmem32l(insbuf + 29); mod->xxs[i].lpe = mod->xxs[i].lps + readmem32l(insbuf + 33); mod->xxs[i].flg = mod->xxs[i].lpe > 2 ? XMP_SAMPLE_LOOP : 0; D_(D_INFO "[%2X] %-22.22s %04x %04x %04x %c V%02x %d", i, mod->xxi[i].name, mod->xxs[i].len, mod->xxs[i].lps, mod->xxs[i].lpe, mod->xxs[i].flg & XMP_SAMPLE_LOOP ? 'L' : ' ', mod->xxi[i].sub[0].vol, mod->xxi[i].sub[0].fin); } hio_seek(f, 37 * (64 - mod->ins), SEEK_CUR); D_(D_INFO "Module length: %d", mod->len); if (pattern_init(mod) < 0) return -1; /* Read and convert patterns */ D_(D_INFO "Stored patterns: %d", mod->pat); for (i = 0; i < mod->pat; i++) { if (pattern_tracks_alloc(mod, i, 64) < 0) return -1; for (j = 0; j < 64 * mod->chn; j++) { uint8 note; event = &EVENT(i, j % mod->chn, j / mod->chn); memset(event, 0, sizeof(struct xmp_event)); note = hio_read8(f); if (note != 0) { event->note = note + 13; } event->ins = hio_read8(f); event->fxt = hio_read8(f); event->fxp = hio_read8(f); } } /* Read samples */ D_(D_INFO "Stored samples: %d", mod->smp); for (i = 0; i < mod->ins; i++) { if (mod->xxs[i].len > 1) { if (load_sample(m, f, 0, &mod->xxs[i], NULL) < 0) return -1; mod->xxi[i].nsm = 1; } } return 0; }
static int mtp_load(struct module_data *m, HIO_HANDLE *f, const int start) { struct xmp_module *mod = &m->mod; struct xmp_event *event; int i, j, k; uint8 buffer[25]; int blocksize; LOAD_INIT(); hio_read(buffer, 6, 1, f); if (!memcmp(buffer, "SONGOK", 6)) set_type(m, "IIgs SoundSmith"); else if (!memcmp(buffer, "IAN92a", 8)) set_type(m, "IIgs MegaTracker"); else return -1; blocksize = hio_read16l(f); mod->spd = hio_read16l(f); hio_seek(f, 10, SEEK_CUR); /* skip 10 reserved bytes */ mod->ins = mod->smp = 15; if (instrument_init(mod) < 0) return -1; for (i = 0; i < mod->ins; i++) { if (subinstrument_alloc(mod, i, 1) < 0) return -1; hio_read(buffer, 1, 22, f); if (buffer[0]) { buffer[buffer[0] + 1] = 0; instrument_name(mod, i, buffer + 1, 22); } hio_read16l(f); /* skip 2 reserved bytes */ mod->xxi[i].sub[0].vol = hio_read8(f) >> 2; mod->xxi[i].sub[0].pan = 0x80; hio_seek(f, 5, SEEK_CUR); /* skip 5 bytes */ } mod->len = hio_read8(f) & 0x7f; hio_read8(f); hio_read(mod->xxo, 1, 128, f); MODULE_INFO(); hio_seek(f, start + 600, SEEK_SET); mod->chn = 14; mod->pat = blocksize / (14 * 64); mod->trk = mod->pat * mod->chn; if (pattern_init(mod) < 0) return -1; /* Read and convert patterns */ D_(D_INFO "Stored patterns: %d", mod->pat); /* Load notes */ for (i = 0; i < mod->pat; i++) { if (pattern_tracks_alloc(mod, i, 64) < 0) return -1; for (j = 0; j < mod->xxp[i]->rows; j++) { for (k = 0; k < mod->chn; k++) { event = &EVENT(i, k, j); event->note = hio_read8(f);; if (event->note) event->note += 24; } } } /* Load fx1 */ for (i = 0; i < mod->pat; i++) { for (j = 0; j < mod->xxp[i]->rows; j++) { for (k = 0; k < mod->chn; k++) { uint8 x; event = &EVENT(i, k, j); x = hio_read8(f);; event->ins = x >> 4; switch (x & 0x0f) { case 0x00: event->fxt = FX_ARPEGGIO; break; case 0x03: event->fxt = FX_VOLSET; break; case 0x05: event->fxt = FX_VOLSLIDE_DN; break; case 0x06: event->fxt = FX_VOLSLIDE_UP; break; case 0x0f: event->fxt = FX_SPEED; break; } } } } /* Load fx2 */ for (i = 0; i < mod->pat; i++) { for (j = 0; j < mod->xxp[i]->rows; j++) { for (k = 0; k < mod->chn; k++) { event = &EVENT(i, k, j); event->fxp = hio_read8(f);; switch (event->fxt) { case FX_VOLSET: case FX_VOLSLIDE_DN: case FX_VOLSLIDE_UP: event->fxp >>= 2; } } } } /* Read instrument data */ D_(D_INFO "Instruments : %d ", mod->ins); for (i = 0; i < mod->ins; i++) { HIO_HANDLE *s; char filename[1024]; if (!mod->xxi[i].name[0]) continue; strncpy(filename, m->dirname, NAME_SIZE); if (*filename) strncat(filename, "/", NAME_SIZE); strncat(filename, (char *)mod->xxi[i].name, NAME_SIZE); if ((s = hio_open_file(filename, "rb")) != NULL) { asif_load(m, s, i); hio_close(s); } #if 0 mod->xxs[i].lps = 0; mod->xxs[i].lpe = 0; mod->xxs[i].flg = mod->xxs[i].lpe > 0 ? XMP_SAMPLE_LOOP : 0; mod->xxi[i].sub[0].fin = 0; mod->xxi[i].sub[0].pan = 0x80; #endif D_(D_INFO "[%2X] %-22.22s %04x %04x %04x %c V%02x", i, mod->xxi[i].name, mod->xxs[i].len, mod->xxs[i].lps, mod->xxs[i].lpe, mod->xxs[i].flg & XMP_SAMPLE_LOOP ? 'L' : ' ', mod->xxi[i].sub[0].vol); } return 0; }