sfx_instrument_map_t *sfx_instrument_map_load_sci(byte *data, size_t size) { sfx_instrument_map_t * map; int i, m; if (data == NULL) return NULL; if (size < PATCH_MIN_SIZE) { warning("[instrument-map] Instrument map too small: %d of %d", (int) size, PATCH_MIN_SIZE); return NULL; } map = sfx_instrument_map_new(PATCH_INSTRUMENT_MAPS_NR); /* Set up MIDI intialisation data */ map->initialisation_block_size = (int16)READ_LE_UINT16(data + PATCH_INIT_DATA_SIZE_LE); if (map->initialisation_block_size) { if (size < PATCH_MIN_SIZE + map->initialisation_block_size) { warning("[instrument-map] Instrument map too small for initialisation block: %d of %d", (int) size, PATCH_MIN_SIZE); return NULL; } if (size > PATCH_MIN_SIZE + map->initialisation_block_size) warning("[instrument-map] Instrument larger than required by initialisation block: %d of %d", (int) size, PATCH_MIN_SIZE); if (map->initialisation_block_size != 0) { map->initialisation_block = (byte *)malloc(map->initialisation_block_size); memcpy(map->initialisation_block, data + PATCH_INIT_DATA, map->initialisation_block_size); } } /* Set up basic instrument info */ for (i = 0; i < SFX_INSTRUMENTS_NR; i++) { map->patch_map[i].patch = (char)data[PATCH_MAP_OFFSET + i]; map->patch_key_shift[i] = (char)data[PATCH_KEY_SHIFT_OFFSET + i]; map->patch_volume_adjust[i] = (char)data[PATCH_VOLUME_ADJUST_OFFSET + i]; map->patch_bend_range[i] = SFX_UNMAPPED; map->velocity_map_index[i] = data[PATCH_VELOCITY_MAP_INDEX + i]; } /* Set up percussion maps */ map->percussion_volume_adjust = data[PATCH_PERCUSSION_VOLUME_ADJUST]; for (i = 0; i < SFX_RHYTHM_NR; i++) { map->percussion_map[i] = data[PATCH_PERCUSSION_MAP_OFFSET + i]; map->percussion_velocity_scale[i] = SFX_MAX_VELOCITY; } /* Set up velocity maps */ for (m = 0; m < PATCH_INSTRUMENT_MAPS_NR; m++) { byte *velocity_map = map->velocity_map[m]; for (i = 0; i < SFX_VELOCITIES_NR; i++) velocity_map[i] = data[PATCH_VELOCITY_MAP(m) + i]; } map->percussion_velocity_map_index = 0; return map; }
sfx_instrument_map_t * sfx_instrument_map_mt32_to_gm(byte *data, size_t size) { int memtimbres, patches; guint8 group, number, keyshift, finetune, bender_range; guint8 *patchpointer; guint32 pos; sfx_instrument_map_t * map; int i; int type; map = sfx_instrument_map_new(0); for (i = 0; i < SFX_INSTRUMENTS_NR; i++) { map->patch_map[i].patch = MT32_PresetTimbreMaps[i].gm_instr; map->patch_key_shift[i] = 0; map->patch_volume_adjust[i] = 0; map->patch_bend_range[i] = 12; map->velocity_map_index[i] = SFX_NO_VELOCITY_MAP; } map->percussion_volume_adjust = 0; map->percussion_velocity_map_index = SFX_NO_VELOCITY_MAP; for (i = 0; i < SFX_RHYTHM_NR; i++) { map->percussion_map[i] = MT32_PresetRhythmKeymap[i]; map->percussion_velocity_scale[i] = SFX_MAX_VELOCITY; } if (!data) { sciprintf("[MT32-to-GM] No MT-32 patch data supplied, using default mapping\n"); return map; } type = sfx_instrument_map_detect(data, size); if (type == SFX_MAP_UNKNOWN) { sciprintf("[MT32-to-GM] Patch data format unknown, using default mapping\n"); return map; } if (type == SFX_MAP_MT32_GM) { sciprintf("[MT32-to-GM] Patch data format not supported, using default mapping\n"); return map; } memtimbres = *(data + 0x1EB); pos = 0x1EC + memtimbres * 0xF6; if (size > pos && ((0x100 * *(data + pos) + *(data +pos + 1)) == 0xABCD)) { patches = 96; pos += 2 + 8 * 48; } else patches = 48; sciprintf("[MT32-to-GM] %d MT-32 Patches detected\n", patches); sciprintf("[MT32-to-GM] %d MT-32 Memory Timbres\n", memtimbres); sciprintf("[MT32-to-GM] Mapping patches..\n"); for (i = 0; i < patches; i++) { char *name; if (i < 48) patchpointer = data + 0x6B + 8 * i; else patchpointer = data + 0x1EC + 8 * (i - 48) + memtimbres * 0xF6 + 2; group = *patchpointer; number = *(patchpointer + 1); keyshift = *(patchpointer + 2); finetune = *(patchpointer + 3); bender_range = *(patchpointer + 4); switch (group) { case 0: map->patch_map[i].patch = MT32_PresetTimbreMaps[number].gm_instr; map->patch_map[i].rhythm = MT32_PresetTimbreMaps[number].gm_rhythm_key; print_map(i, map->patch_map[i].patch, map->patch_map[i].rhythm, number); break; case 1: map->patch_map[i].patch = MT32_PresetTimbreMaps[number + 64].gm_instr; map->patch_map[i].rhythm = MT32_PresetTimbreMaps[number + 64].gm_rhythm_key; print_map(i, map->patch_map[i].patch, map->patch_map[i].rhythm, number + 64); break; case 2: name = (char *) data + 0x1EC + number * 0xF6; map->patch_map[i].patch = lookup_instrument(name); map->patch_map[i].rhythm = SFX_UNMAPPED; print_map_mem(i, map->patch_map[i].patch, map->patch_map[i].rhythm, name); break; case 3: map->patch_map[i].patch = MT32_RhythmTimbreMaps[number].gm_instr; map->patch_map[i].rhythm = SFX_UNMAPPED; print_map_rhythm(i, map->patch_map[i].patch, map->patch_map[i].rhythm, number); break; default: break; } /* map->patch_key_shift[i] = (int) (keyshift & 0x3F) - 24; */ map->patch_bend_range[i] = bender_range & 0x1F; } if (size > pos && ((0x100 * *(data + pos) + *(data + pos + 1)) == 0xDCBA)) { sciprintf("[MT32-to-GM] Mapping percussion..\n"); for (i = 0; i < 64 ; i++) { number = *(data + pos + 4 * i + 2); if (number < 64) { char *name = (char *) data + 0x1EC + number * 0xF6; map->percussion_map[i + 23] = lookup_rhythm_key(name); print_map_rhythm_mem(i, map->percussion_map[i + 23], name); } else { if (number < 94) { map->percussion_map[i + 23] = MT32_RhythmTimbreMaps[number - 64].gm_rhythmkey; print_map_rhythm(i, SFX_MAPPED_TO_RHYTHM, map->percussion_map[i + 23], number - 64); } else map->percussion_map[i + 23] = SFX_UNMAPPED; } map->percussion_velocity_scale[i + 23] = *(data + pos + 4 * i + 3) * SFX_MAX_VELOCITY / 100; } } return map; }