1 /* 2 * Schism Tracker - a cross-platform Impulse Tracker clone 3 * copyright (c) 2003-2005 Storlek <storlek@rigelseven.com> 4 * copyright (c) 2005-2008 Mrs. Brisby <mrs.brisby@nimh.org> 5 * copyright (c) 2009 Storlek & Mrs. Brisby 6 * copyright (c) 2010-2012 Storlek 7 * URL: http://schismtracker.org/ 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; either version 2 of the License, or 12 * (at your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program; if not, write to the Free Software 21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 */ 23 #define NEED_BYTESWAP 24 25 #include "headers.h" 26 #include "fmt.h" 27 28 #include "it.h" 29 #include "song.h" 30 #include "log.h" 31 32 #ifndef WIN32 33 #endif 34 35 #include "it_defs.h" 36 37 38 /* --------------------------------------------------------------------- */ 39 int fmt_iti_read_info(dmoz_file_t *file, const uint8_t *data, size_t length) 40 { 41 if (!(length > 554 && memcmp(data, "IMPI",4) == 0)) return 0; 42 file->description = "Impulse Tracker Instrument"; 43 file->title = strn_dup((const char *)data + 32, 25); 44 file->type = TYPE_INST_ITI; 45 46 return 1; 47 } 48 49 int fmt_iti_load_instrument(const uint8_t *data, size_t length, int slot) 50 { 51 struct it_instrument iti; 52 struct instrumentloader ii; 53 song_instrument_t *ins; 54 song_sample_t *smp; 55 int j; 56 57 if (!(length > 554 && memcmp(data, "IMPI",4) == 0)) return 0; 58 59 memcpy(&iti, data, sizeof(iti)); 60 61 ins = instrument_loader_init(&ii, slot); 62 strncpy(ins->filename, (char *)iti.filename, 12); 63 ins->filename[12] = 0; 64 65 ins->nna = iti.nna; 66 ins->dct = iti.dct; 67 ins->dca = iti.dca; 68 ins->fadeout = (bswapLE16(iti.fadeout) << 5); 69 ins->pitch_pan_separation = iti.pps; 70 ins->pitch_pan_center = iti.ppc; 71 ins->global_volume = iti.gbv; 72 ins->panning = (iti.dfp & 0x7F) << 2; 73 if (ins->panning > 256) ins->panning = 128; 74 ins->flags = 0; 75 if (iti.dfp & 0x80) ins->flags = ENV_SETPANNING; 76 ins->vol_swing = iti.rv; 77 ins->pan_swing = iti.rp; 78 79 strncpy(ins->name, (char *)iti.name, 25); 80 ins->name[25] = 0; 81 ins->ifc = iti.ifc; 82 ins->ifr = iti.ifr; 83 ins->midi_channel_mask = iti.mch > 16 ? (0x10000 + iti.mch) 84 : iti.mch == 0 ? (0) 85 : (1 << (iti.mch-1)); 86 ins->midi_program = iti.mpr; 87 ins->midi_bank = bswapLE16(iti.mbank); 88 89 for (j = 0; j < 120; j++) { 90 ins->sample_map[j] = instrument_loader_sample(&ii, iti.keyboard[2*j + 1]); 91 ins->note_map[j] = iti.keyboard[2 * j]+1; 92 } 93 if (iti.volenv.flags & 1) ins->flags |= ENV_VOLUME; 94 if (iti.volenv.flags & 2) ins->flags |= ENV_VOLLOOP; 95 if (iti.volenv.flags & 4) ins->flags |= ENV_VOLSUSTAIN; 96 if (iti.volenv.flags & 8) ins->flags |= ENV_VOLCARRY; 97 ins->vol_env.nodes = iti.volenv.num; 98 ins->vol_env.loop_start = iti.volenv.lpb; 99 ins->vol_env.loop_end = iti.volenv.lpe; 100 ins->vol_env.sustain_start = iti.volenv.slb; 101 ins->vol_env.sustain_end = iti.volenv.sle; 102 if (iti.panenv.flags & 1) ins->flags |= ENV_PANNING; 103 if (iti.panenv.flags & 2) ins->flags |= ENV_PANLOOP; 104 if (iti.panenv.flags & 4) ins->flags |= ENV_PANSUSTAIN; 105 if (iti.panenv.flags & 8) ins->flags |= ENV_PANCARRY; 106 ins->pan_env.nodes = iti.panenv.num; 107 ins->pan_env.loop_start = iti.panenv.lpb; 108 ins->pan_env.loop_end = iti.panenv.lpe; 109 ins->pan_env.sustain_start = iti.panenv.slb; 110 ins->pan_env.sustain_end = iti.panenv.sle; 111 if (iti.pitchenv.flags & 1) ins->flags |= ENV_PITCH; 112 if (iti.pitchenv.flags & 2) ins->flags |= ENV_PITCHLOOP; 113 if (iti.pitchenv.flags & 4) ins->flags |= ENV_PITCHSUSTAIN; 114 if (iti.pitchenv.flags & 8) ins->flags |= ENV_PITCHCARRY; 115 if (iti.pitchenv.flags & 0x80) ins->flags |= ENV_FILTER; 116 ins->pitch_env.nodes = iti.pitchenv.num; 117 ins->pitch_env.loop_start = iti.pitchenv.lpb; 118 ins->pitch_env.loop_end = iti.pitchenv.lpe; 119 ins->pitch_env.sustain_start = iti.pitchenv.slb; 120 ins->pitch_env.sustain_end = iti.pitchenv.sle; 121 122 for (j = 0; j < 25; j++) { 123 ins->vol_env.values[j] = iti.volenv.data[3 * j]; 124 ins->vol_env.ticks[j] = iti.volenv.data[3 * j + 1] 125 | (iti.volenv.data[3 * j + 2] << 8); 126 127 ins->pan_env.values[j] = iti.panenv.data[3 * j] + 32; 128 ins->pan_env.ticks[j] = iti.panenv.data[3 * j + 1] 129 | (iti.panenv.data[3 * j + 2] << 8); 130 131 ins->pitch_env.values[j] = iti.pitchenv.data[3 * j] + 32; 132 ins->pitch_env.ticks[j] = iti.pitchenv.data[3 * j + 1] 133 | (iti.pitchenv.data[3 * j + 2] << 8); 134 } 135 136 /* okay, on to samples */ 137 unsigned int pos = 554; 138 for (j = 0; j < ii.expect_samples; j++) { 139 smp = song_get_sample(ii.sample_map[j+1]); 140 if (!smp) break; 141 if (!load_its_sample(data + pos, data, length, smp)) { 142 log_appendf(4, "Could not load sample %d from ITI file", j); 143 return instrument_loader_abort(&ii); 144 } 145 pos += 80; /* length of ITS header */ 146 } 147 return 1; 148 } 149