/*
	$Id: instrum.cpp,v 1.9 2000/08/19 01:45:50 greglee Exp $

    TiMidity -- Experimental MIDI to WAVE converter
    Copyright (C) 1995 Tuukka Toivonen <toivonen@clinet.fi>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

   instrum.c 
   
   Code to load and unload GUS-compatible instrument patches.

*/

#include <stdio.h>

#ifndef NO_STRING_H
#    include <string.h>
#else
#    include <strings.h>
#endif

#include <stdlib.h>
#include <malloc.h>

#include "gtim.h"

#ifdef USE_POSIX_MAPPED_FILES
#    define DFD
#    include <sys/mman.h>
#endif

#ifdef DFD
#    include <sys/types.h>
#    include <sys/stat.h>
#    include <unistd.h>
#endif

#include "common.h"
#include "instrum.h"
#include "playmidi.h"
#include "output.h"
#include "controls.h"
#include "resample.h"
#include "tables.h"
#include "filter.h"


/* Some functions get aggravated if not even the standard banks are 
   available. */
static ToneBank standard_tonebank, standard_drumset;
ToneBank * tonebank[MAXBANK] = {
&standard_tonebank}, *drumset[MAXBANK] = {
&standard_drumset};

/* This is a special instrument, used for all melodic programs */
InstrumentLayer *default_instrument = 0;

/* This is only used for tracks that don't specify a program */
int     default_program = DEFAULT_PROGRAM;

int     antialiasing_allowed = 0;

#ifdef FAST_DECAY
int     fast_decay = 1;
#else
int     fast_decay = 0;
#endif

int     fast_load = 0;

int     current_tune_number = 0;
int     last_tune_purged = 0;
int     current_patch_memory = 0;
int     max_patch_memory = 350000000;

static int default_cutoff[128] = {
/* p=000 cutoff= */11998,
/* p=001 cutoff= */20004,
/* p=002 cutoff= */    1,
/* p=003 cutoff= */ 8999,
/* p=004 cutoff= */15997,
/* p=005 cutoff= */19912,
/* p=006 cutoff= */ 8803,
/* p=007 cutoff= */19912,
/* p=008 cutoff= */19912,
/* p=009 cutoff= */10002,
/* p=010 cutoff= */19912,
/* p=011 cutoff= */ 1200,
/* p=012 cutoff= */19912,
/* p=013 cutoff= */ 6999,
/* p=014 cutoff= */19912,
/* p=015 cutoff= */ 7998,
/* p=016 cutoff= */ 8597,
/* p=017 cutoff= */19912,
/* p=018 cutoff= */19912,
/* p=019 cutoff= */19912,
/* p=020 cutoff= */19912,
/* p=021 cutoff= */19912,
/* p=022 cutoff= */ 5999,
/* p=023 cutoff= */19912,
/* p=024 cutoff= */10361,
/* p=025 cutoff= */19912,
/* p=026 cutoff= */ 6143,
/* p=027 cutoff= */19912,
/* p=028 cutoff= */19912,
/* p=029 cutoff= */19912,
/* p=030 cutoff= */ 5001,
/* p=031 cutoff= */19912,
/* p=032 cutoff= */10002,
/* p=033 cutoff= */19912,
/* p=034 cutoff= */19912,
/* p=035 cutoff= */19912,
/* p=036 cutoff= */19912,
/* p=037 cutoff= */19912,
/* p=038 cutoff= */  120,
/* p=039 cutoff= */19912,
/* p=040 cutoff= */19912,
/* p=041 cutoff= */19912,
/* p=042 cutoff= */19912,
/* p=043 cutoff= */19912,
/* p=044 cutoff= */10002,
/* p=045 cutoff= */10002,
/* p=046 cutoff= */ 7105,
/* p=047 cutoff= */ 7998,
/* p=048 cutoff= */10002,
/* p=049 cutoff= */10002,
/* p=050 cutoff= */ 8523,
/* p=051 cutoff= */ 5545,
/* p=052 cutoff= */19912,
/* p=053 cutoff= */19912,
/* p=054 cutoff= */19912,
/* p=055 cutoff= */19912,
/* p=056 cutoff= */10002,
/* p=057 cutoff= */10002,
/* p=058 cutoff= */20004,
/* p=059 cutoff= */10002,
/* p=060 cutoff= */ 8999,
/* p=061 cutoff= */10002,
/* p=062 cutoff= */20004,
/* p=063 cutoff= */  499,
/* p=064 cutoff= */10002,
/* p=065 cutoff= */10002,
/* p=066 cutoff= */10002,
/* p=067 cutoff= */10002,
/* p=068 cutoff= */ 8999,
/* p=069 cutoff= */ 3421,
/* p=070 cutoff= */19912,
/* p=071 cutoff= */19912,
/* p=072 cutoff= */ 7998,
/* p=073 cutoff= */ 7998,
/* p=074 cutoff= */ 7998,
/* p=075 cutoff= */  800,
/* p=076 cutoff= */20004,
/* p=077 cutoff= */  700,
/* p=078 cutoff= */19912,
/* p=079 cutoff= */ 7998,
/* p=080 cutoff= */ 4502,
/* p=081 cutoff= */ 5400,
/* p=082 cutoff= */    3,
/* p=083 cutoff= */ 4655,
/* p=084 cutoff= */19912,
/* p=085 cutoff= */20004,
/* p=086 cutoff= */  200,
/* p=087 cutoff= */  999,
/* p=088 cutoff= */20004,
/* p=089 cutoff= */  587,
/* p=090 cutoff= */ 2854,
/* p=091 cutoff= */19912,
/* p=092 cutoff= */ 2286,
/* p=093 cutoff= */19912,
/* p=094 cutoff= */19912,
/* p=095 cutoff= */ 3100,
/* p=096 cutoff= */ 2004,
/* p=097 cutoff= */19912,
/* p=098 cutoff= */ 4981,
/* p=099 cutoff= */19912,
/* p=100 cutoff= */19912,
/* p=101 cutoff= */  800,
/* p=102 cutoff= */ 5001,
/* p=103 cutoff= */19912,
/* p=104 cutoff= */ 7998,
/* p=105 cutoff= */19912,
/* p=106 cutoff= */19912,
/* p=107 cutoff= */19912,
/* p=108 cutoff= */19912,
/* p=109 cutoff= */19912,
/* p=110 cutoff= */19912,
/* p=111 cutoff= */ 1295,
/* p=112 cutoff= */ 5304,
/* p=113 cutoff= */19912,
/* p=114 cutoff= */19912,
/* p=115 cutoff= */19912,
/* p=116 cutoff= */ 8237,
/* p=117 cutoff= */19912,
/* p=118 cutoff= */ 7998,
/* p=119 cutoff= */19912,
/* p=120 cutoff= */19912,
/* p=121 cutoff= */19912,
/* p=122 cutoff= */19912,
/* p=123 cutoff= */19912,
/* p=124 cutoff= */19912,
/* p=125 cutoff= */19912,
/* p=126 cutoff= */ 4696,
/* p=127 cutoff= */19912
};


static int def_percussion_cutoff[128] = {
/* p = 00 */  19912,
/* p = 01 */  19912,
/* p = 02 */  19912,
/* p = 03 */  19912,
/* p = 04 */  19912,
/* p = 05 */  19912,
/* p = 06 */  19912,
/* p = 07 */  19912,
/* p = 08 */  19912,
/* p = 09 */  19912,
/* p = 10 */  19912,
/* p = 11 */  19912,
/* p = 12 */  19912,
/* p = 13 */  19912,
/* p = 14 */  19912,
/* p = 15 */  19912,
/* p = 16 */  19912,
/* p = 17 */  19912,
/* p = 18 */  19912,
/* p = 19 */  19912,
/* p = 20 */  19912,
/* p = 21 */  19912,
/* p = 22 */  19912,
/* p = 23 */  19912,
/* p = 24 */  19912,
/* p = 25 */  19912,
/* p = 26 */  19912,
/* p= 27 cutoff = */ 19912,
/* p= 28 cutoff = */ 19912,
/* p= 29 cutoff = */ 19912,
/* p= 30 cutoff = */ 19912,
/* p= 31 cutoff = */ 19912,
/* p= 32 cutoff = */ 19912,
/* p= 33 cutoff = */ 19912,
/* p= 34 cutoff = */ 19912,
/* p= 35 cutoff = */  7998,
/* p= 36 cutoff = */ 19912,
/* p= 37 cutoff = */ 19912,
/* p= 38 cutoff = */ 10002,
/* p= 39 cutoff = */ 19912,
/* p= 40 cutoff = */ 10002,
/* p= 41 cutoff = */  7998,
/* p= 42 cutoff = */ 19912,
/* p= 43 cutoff = */  7998,
/* p= 44 cutoff = */ 19912,
/* p= 45 cutoff = */  4499,
/* p= 46 cutoff = */ 19912,
/* p= 47 cutoff = */  7998,
/* p= 48 cutoff = */  7998,
/* p= 49 cutoff = */ 19912,
/* p= 50 cutoff = */  7998,
/* p= 51 cutoff = */ 19912,
/* p= 52 cutoff = */ 19912,
/* p= 53 cutoff = */ 19912,
/* p= 54 cutoff = */ 19912,
/* p= 55 cutoff = */ 19912,
/* p= 56 cutoff = */ 19912,
/* p= 57 cutoff = */ 19912,
/* p= 58 cutoff = */ 19912,
/* p= 59 cutoff = */ 19912,
/* p= 60 cutoff = */ 19912,
/* p= 61 cutoff = */ 19912,
/* p= 62 cutoff = */ 19912,
/* p= 63 cutoff = */ 19912,
/* p= 64 cutoff = */ 19912,
/* p= 65 cutoff = */ 19912,
/* p= 66 cutoff = */ 19912,
/* p= 67 cutoff = */ 19912,
/* p= 68 cutoff = */ 19912,
/* p= 69 cutoff = */ 19912,
/* p= 70 cutoff = */ 19912,
/* p= 71 cutoff = */ 19912,
/* p= 72 cutoff = */ 19912,
/* p= 73 cutoff = */ 19912,
/* p= 74 cutoff = */ 19912,
/* p= 75 cutoff = */ 19912,
/* p= 76 cutoff = */ 19912,
/* p= 77 cutoff = */ 19912,
/* p= 78 cutoff = */ 19912,
/* p= 79 cutoff = */ 19912,
/* p= 80 cutoff = */ 19912,
/* p= 81 cutoff = */ 19912,
/* p= 82 cutoff = */ 19912,
/* p= 83 cutoff = */ 19912,
/* p= 84 cutoff = */ 19912,
/* p= 85 cutoff = */ 19912,
/* p= 86 cutoff = */ 19912,
/* p= 87 cutoff = */ 19912,
/* p = 88 */  19912,
/* p = 89 */  19912,
/* p = 90 */  19912,
/* p = 91 */  19912,
/* p = 92 */  19912,
/* p = 93 */  19912,
/* p = 94 */  19912,
/* p = 95 */  19912,
/* p = 96 */  19912,
/* p = 97 */  19912,
/* p = 98 */  19912,
/* p = 99 */  19912,
/* p =100 */  19912,
/* p =101 */  19912,
/* p =102 */  19912,
/* p =103 */  19912,
/* p =104 */  19912,
/* p =105 */  19912,
/* p =106 */  19912,
/* p =107 */  19912,
/* p =108 */  19912,
/* p =109 */  19912,
/* p =110 */  19912,
/* p =111 */  19912,
/* p =112 */  19912,
/* p =113 */  19912,
/* p =114 */  19912,
/* p =115 */  19912,
/* p =116 */  19912,
/* p =117 */  19912,
/* p =118 */  19912,
/* p =119 */  19912,
/* p =120 */  19912,
/* p =121 */  19912,
/* p =122 */  19912,
/* p =123 */  19912,
/* p =124 */  19912,
/* p =125 */  19912,
/* p =126 */  19912,
/* p =127 */  19912
};
static void purge_as_required (void);

static void
free_instrument (Instrument * ip)
{
#if 0
    Sample *sp;
    int     i;
#endif
    if (!ip)
	return;

#if 0
    if (!ip->contents)
	for (i = 0; i < ip->samples; i++) {
	    sp = &(ip->sample[i]);
	    if (sp->data)
		free (sp->data);
	}
#endif
    if (ip->sample)
    free (ip->sample);

#if 0
    if (!ip->contents)
	for (i = 0; i < ip->right_samples; i++) {
	    sp = &(ip->right_sample[i]);
	    if (sp->data)
		free (sp->data);
	}
#endif
    if (ip->right_sample)
	free (ip->right_sample);
    free (ip);
}

void
add_purge (InstrumentLayer *lp, sample_t *data)
{
	PurgeList *pl, *next;
	if (!lp || !data) return;
	if (!lp->purgelist) {
		pl = (PurgeList *)safe_malloc(sizeof(PurgeList));
		pl->next = NULL;
		pl->purge_me = data;
		lp->purgelist = pl;
		return;
	}
	pl = lp->purgelist;
	next = pl->next;
	pl = (PurgeList *)safe_malloc(sizeof(PurgeList));
	pl->next = next;
	pl->purge_me = data;
}

static void
free_purgelist (PurgeList *pl)
{
    PurgeList *next;
    for (; pl; pl = next) {
	    next = pl->next;
#if 0
if (pl->purge_me)
ctl->cmsg(CMSG_TRACE, VERB_VERBOSE,
"purging %p", pl->purge_me);
#endif
	    if (pl->purge_me) free (pl->purge_me);
	    free (pl);
    }
}

int
free_layer (InstrumentLayer * lp)
{
    InstrumentLayer *next;
#ifdef DFD
    uint8 *mp;
    int mp_size;
#endif

    if (!lp) return 1;
    if (lp == MAGIC_LOAD_INSTRUMENT) return 1;
    //if (lp->font_type == FONT_SFZ) return 0;
    if (lp->font_type == FONT_SFZ) free_sfz_data(lp);
#ifdef DFD
    mp = lp->all_layers;
    mp_size = lp->map_size;
#endif
    current_patch_memory -= lp->size;

    for (; lp; lp = next) {
	next = lp->next;
	free_instrument (lp->instrument);
	free_purgelist (lp->purgelist);
	free (lp);
    }


#ifdef DFD
    if (mp) {
#if 0
    ctl->cmsg (CMSG_INFO, VERB_VERBOSE,
	       "-mem %d (freeing %d) free %ul", current_patch_memory, mp_size, mp);
#endif
#ifdef USE_POSIX_MAPPED_FILES
    	    munmap(mp, mp_size);
#else
	    free (mp);
#endif
    }
#endif

#ifdef DEBUG_MEM_PATCH
    ctl->cmsg (CMSG_ERROR, VERB_NORMAL,
	       "-mem %d (freed %d)", current_patch_memory, mp_size);
#endif
    return 1;
}

static void
free_bank (int dr, int b)
{
    int     i;
    ToneBank *bank = ((dr) ? drumset[b] : tonebank[b]);
    for (i = 0; i < MAXPROG; i++)
	if (bank->tone[i].layer) {
	    /* Not that this could ever happen, of course */
	    if (bank->tone[i].layer != MAGIC_LOAD_INSTRUMENT) {
		if (free_layer (bank->tone[i].layer)) {
			bank->tone[i].layer = 0;
			bank->tone[i].last_used = -1;
		}
	    }
	}
}

static void
free_old_bank (int dr, int b, int how_old)
{
    int     i;
    ToneBank *bank = ((dr) ? drumset[b] : tonebank[b]);
    for (i = 0; i < MAXPROG; i++)
	if (bank->tone[i].layer && bank->tone[i].last_used < how_old) {
	    if (bank->tone[i].layer != MAGIC_LOAD_INSTRUMENT) {
		ctl->cmsg (CMSG_INFO, VERB_DEBUG,
			   "Unloading %s %s[%d,%d] - last used %d.",
			   (dr) ? "drum" : "inst", bank->tone[i].name,
			   i, b, bank->tone[i].last_used);
		if (free_layer (bank->tone[i].layer)) {
			bank->tone[i].layer = 0;
			bank->tone[i].last_used = -1;
		}
	    }
	}
}

int32
convert_envelope_rate_attack (uint32 rate)
{
    int32   r;

    r = 3 - ((rate >> 6) & 0x3);
    r *= 3;
    r = (int32) (rate & 0x3f) << r;	/* 6.9 fixed point */

    /* 15.15 fixed point. */
    return (((r * 44100) / play_mode->rate) * control_ratio)
//	<< 10;
	<< 9;
}

int32
convert_envelope_rate (uint32 rate)
{
    int32   r;

    r = 3 - ((rate >> 6) & 0x3);
    r *= 3;
    r = (int32) (rate & 0x3f) << r;	/* 6.9 fixed point */

    /* 15.15 fixed point. */
    return (((r * 44100) / play_mode->rate) * control_ratio)
	<< ((fast_decay) ? 10 : 9);
}

int32
convert_envelope_offset (uint32 offset)
{
    /* This is not too good... Can anyone tell me what these values mean?
       Are they GUS-style "exponential" volumes? And what does that mean? */

    /* 15.15 fixed point */
    return offset << (7 + 15);
}

int32
convert_tremolo_sweep (uint32 sweep)
{
    if (!sweep)
	return 0;

#if 0
    printf ("tremolo sweep %d -> %d\n",
	    (int) sweep,
	    ((control_ratio * SWEEP_TUNING) << SWEEP_SHIFT) /
	    (play_mode->rate * sweep)
	);
#endif

    return
	((control_ratio * SWEEP_TUNING) << SWEEP_SHIFT) /
	(play_mode->rate * sweep);
}

int32
convert_vibrato_sweep (uint32 sweep, uint32 vib_control_ratio)
{
    if (!sweep)
	return 0;

#if 0
    printf ("vibrato sweep %d (vcr %d) -> %d\n",
	    (int) sweep, (int) vib_control_ratio,
	    (int) (FRSCALE
		   ((double) (vib_control_ratio) * SWEEP_TUNING, SWEEP_SHIFT)
		   / (double) (play_mode->rate * sweep))
	);
#endif
    return
	(int32) (FRSCALE
		 ((double) (vib_control_ratio) * SWEEP_TUNING, SWEEP_SHIFT)
		 / (double) (play_mode->rate * sweep));

    /* this was overflowing with seashore.pat

       ((vib_control_ratio * SWEEP_TUNING) << SWEEP_SHIFT) /
       (play_mode->rate * sweep); */
}

int32
convert_tremolo_rate (uint32 rate)
{
#if 0
    printf ("tremolo rate %d -> %d\n",
	    (int) rate,
	    ((SINE_CYCLE_LENGTH * control_ratio * rate) << RATE_SHIFT) /
	    (TREMOLO_RATE_TUNING * play_mode->rate)
	);
#endif
    return
	((SINE_CYCLE_LENGTH * control_ratio * rate) << RATE_SHIFT) /
	(TREMOLO_RATE_TUNING * play_mode->rate);
}

int32
convert_vibrato_rate (uint32 rate)
{
#if 0
    printf ("vibrato rate %d -> %d\n",
	    (int) rate,
	    (VIBRATO_RATE_TUNING * play_mode->rate) /
	    (rate * 2 * VIBRATO_SAMPLE_INCREMENTS)
	);
#endif
    /* Return a suitable vibrato_control_ratio value */
    return
	(VIBRATO_RATE_TUNING * play_mode->rate) /
	(rate * 2 * VIBRATO_SAMPLE_INCREMENTS);
}

static void
reverse_data (int16 *sp, uint32 ls, uint32 le)
{
    int16   s, *ep = sp + le;
    sp += ls;
    le -= ls;
    le /= 2;
    while (le--) {
	s = *sp;
	*sp++ = *ep;
	*ep-- = s;
    }
}

/* 
   If panning or note_to_use != -1, it will be used for all samples,
   instead of the sample-specific values in the instrument file. 

   For note_to_use, any value <0 or >127 will be forced to 0.
 
   For other parameters, 1 means yes, 0 means no, other values are
   undefined.

   TODO: do reverse loops right */


static InstrumentLayer *
load_instrument (ToneBank *b, int bank, int tn, int percussion)
{
    const char *name = b->tone[tn].name;
    int amp = b->tone[tn].amp;
    int note_to_use = b->tone[tn].note;
    int strip_loop = b->tone[tn].strip_loop;
    int strip_envelope = b->tone[tn].strip_envelope;
    int strip_tail = b->tone[tn].strip_tail;
    InstrumentLayer *lp = NULL, *lastlp, *headlp = NULL;
    Instrument *ip;
#ifdef DFD
    uint8   *tmp;
#else
    FILE   *fp;
    uint8   tmp[1024];
#endif
    char    tmpbuf[1024];
    int     i, j, noluck = 0;
#ifdef PATCH_EXT_LIST
    static const char *patch_ext[] = PATCH_EXT_LIST;
#endif
    int     sf2flag = 0;
    int     right_samples = 0;
    int     stereo_channels = 1, stereo_layer;
    int     vlayer_list[19][4], vlayer, vlayer_count = 1;
#ifdef DFD
    int     fd;
    struct stat info;
    uint8   *whole_file;
    int     whole_file_offset;
#endif

    if (tn < 0 || tn > 127) {
	ctl->cmsg (CMSG_ERROR, VERB_NORMAL, "Weird note %d for `%s'.", tn,
		   name);
	    return NULL;
    }

    if (note_to_use == -1 && percussion) note_to_use = tn;

    if (b->tone[tn].font_type == FONT_SF) {
	if ( (lp = load_sf_instrument(b, bank, tn, percussion)) )
	    return (lp);
	else return 0;
    }

    if (check_for_rc ())
	return 0;
    if (!name)
	return 0;

    if (!strcmp(name + strlen(name) - 4, ".sfz"))
	return load_sfz_instrument(b, bank, tn, percussion);

    /* Open patch file */
#ifdef DFD
    if ((fd = open_file_raw (name, OF_NORMAL, 0)) < 0) {
#else
    if (!(fp = open_file (name, 1, OF_NORMAL, 0))) {
#endif
	noluck = 1;
#ifdef PATCH_EXT_LIST
	/* Try with various extensions */
	for (i = 0; patch_ext[i]; i++) {
	    if (strlen (name) + strlen (patch_ext[i]) < 1024) {
		strcpy (tmpbuf, name);
		strcat (tmpbuf, patch_ext[i]);
#ifdef DFD
		if ((fd = open_file_raw (tmpbuf, OF_NORMAL, 0)) > 0) {
#else
		if ((fp = open_file (tmpbuf, 1, OF_NORMAL, 0))) {
#endif
		    noluck = 0;
		    break;
		}
	    }
	}
#endif
    }

    if (noluck) {
	ctl->cmsg (CMSG_INFO, VERB_NORMAL,
		   "Instrument `%s' can't be found.", name);

	return 0;
    }

#ifdef DFD
    if (fstat (fd, &info)) {
	ctl->cmsg (CMSG_ERROR, VERB_NORMAL, "Can't find file `%s'.",
		   current_filename);
	close(fd);
	return 0;
    }
#if 0
/* check here if size less than what we are allowed */
    if (info.st_size + current_patch_memory > max_patch_memory) {
	ctl->cmsg (CMSG_ERROR, VERB_NORMAL,
		   "File `%s' at %d bytes is too big to fit in memory.",
		   current_filename, info.st_size);
	close(fd);
	return 0;
    }
#endif
#   ifdef USE_POSIX_MAPPED_FILES
    whole_file = (unsigned char *) mmap (0, (unsigned)info.st_size, PROT_READ, MAP_SHARED, fd, 0);

    if (whole_file == (unsigned char *) (-1)) {
	ctl->cmsg (CMSG_INFO, VERB_NOISY, "Couldn't mmap `%s'.", current_filename);
	close(fd);
	return 0;
    }
#   else
    if (!(whole_file = (uint8 *)malloc (info.st_size))) {
	ctl->cmsg (CMSG_ERROR, VERB_NORMAL, "Memory allocation of %ld bytes failed.", info.st_size,
		   current_filename);
	close (fd);
	return 0;
    }

    ctl->cmsg (CMSG_INFO, VERB_VERBOSE, "CPM=%d, File `%s' has %ld bytes. ->%u",
		    current_patch_memory,
		   current_filename, info.st_size, whole_file);

    if (info.st_size != read (fd, whole_file, info.st_size)) {
	ctl->cmsg (CMSG_ERROR, VERB_NORMAL, "Can't read file `%s'.",
		   current_filename);
	close (fd);
	free(whole_file);
	return 0;
    }
#   endif

    close (fd);
#endif

    /* Read some headers and do cursory sanity checks. There are loads
       of magic offsets. This could be rewritten... */

#ifdef DFD
    tmp = whole_file;
    whole_file_offset = 239;

    if ( memcmp (tmp, "GF1PATCH110\0ID#000002", 22) && memcmp (tmp, "GF1PATCH100\0ID#000002", 22)) {
    	    /* don't know what the differences are */
	ctl->cmsg (CMSG_ERROR, VERB_NORMAL, "%s: not an instrument", name);
	free(whole_file);
	return 0;
    }
#else
    if ((239 != fread (tmp, 1, 239, fp)) ||
		    (memcmp (tmp, "GF1PATCH110\0ID#000002", 22) &&
		     memcmp (tmp, "GF1PATCH100\0ID#000002", 22))) {
    	    /* don't know what the differences are */
	ctl->cmsg (CMSG_ERROR, VERB_NORMAL, "%s: not an instrument", name);
    	close_file (fp);
	return 0;
    }
#endif

    if (!memcmp (tmp + 93, "SF2EXT", 6)) {
	sf2flag = 1;
	vlayer_count = tmp[152];
    }

    if (!sf2flag && percussion) {
	    if (strip_loop == -1) strip_loop = 1;
	    if (strip_envelope == -1) strip_envelope = 1;
    }

    if (tmp[82] != 1 && tmp[82] != 0) {	/* instruments. To some patch makers, 
					   0 means 1 */
	ctl->cmsg (CMSG_ERROR, VERB_NORMAL,
		   "Can't handle patches with %d instruments", tmp[82]);
#ifdef DFD
	free(whole_file);
#else
    	close_file (fp);
#endif
	return 0;
    }

    if (tmp[151] != 1 && tmp[151] != 0) {	/* layers. What's a layer? */
	ctl->cmsg (CMSG_ERROR, VERB_NORMAL,
		   "Can't handle instruments with %d layers", tmp[151]);
#ifdef DFD
	free(whole_file);
#else
    	close_file (fp);
#endif
	return 0;
    }

    if (sf2flag && vlayer_count > 0) {
	for (i = 0; i < 9; i++)
	    for (j = 0; j < 4; j++)
		vlayer_list[i][j] = tmp[153 + i * 4 + j];
	for (i = 9; i < 19; i++)
	    for (j = 0; j < 4; j++)
		vlayer_list[i][j] = tmp[199 + (i - 9) * 4 + j];
    }
    else {
	vlayer_count = 1;
	vlayer_list[0][0] = 0;
	vlayer_list[0][1] = 127;
	vlayer_list[0][2] = tmp[198];
	vlayer_list[0][3] = 0;
	for (i = 1; i < 19; i++)
	    for (j = 0; j < 4; j++)
		vlayer_list[i][j] = 0;
    }

    lastlp = NULL;

    for (vlayer = 0; vlayer < vlayer_count; vlayer++) {

	if (fast_load && vlayer > 0) break;

	lp = (InstrumentLayer *) safe_malloc (sizeof (InstrumentLayer));
	lp->size = 0;
	lp->map_size = 0;
	lp->lo = vlayer_list[vlayer][0];
	lp->hi = vlayer_list[vlayer][1];
	ip = (Instrument *) safe_malloc (sizeof (Instrument));
	lp->instrument = ip;
	lp->purgelist = NULL;
	lp->next = NULL;
	lp->all_layers = NULL;
	if (sf2flag)
	    lp->font_type = FONT_GUS | FONT_SF;
	else
	    lp->font_type = FONT_GUS;

	if (lastlp)
	    lastlp->next = lp;
	else {
	    headlp = lp;
#ifdef DFD
	    headlp->all_layers = whole_file;
	    headlp->size += info.st_size;
	    headlp->map_size = info.st_size;
#endif
	}

	lastlp = lp;

	if (sf2flag)
	    ip->type = FONT_GUS | FONT_SF;
	else
	    ip->type = FONT_GUS;
	ip->samples = vlayer_list[vlayer][2];
	ip->sample = (Sample *) safe_malloc (sizeof (Sample) * ip->samples);
	ip->left_samples = ip->samples;
	ip->left_sample = ip->sample;
	right_samples = vlayer_list[vlayer][3];
	ip->right_samples = right_samples;
	if (right_samples) {
	    ip->right_sample =
		(Sample *) safe_malloc (sizeof (Sample) * right_samples);
	    stereo_channels = 2;
	}
	else
	    ip->right_sample = 0;
	ip->contents = 0;


	if (!vlayer)
	ctl->cmsg (CMSG_LOAD, VERB_NOISY,
		   "%s%s[%d,%d] %s(%d layer%s)",
		   (percussion) ? "   " : "", name,
		   (percussion) ? note_to_use : tn, bank,
		   (right_samples) ? "(2) " : "", vlayer_count, (vlayer_count>1)? "s":"");

	for (stereo_layer = 0; stereo_layer < stereo_channels; stereo_layer++) {
	    int     sample_count;

	    if (stereo_layer == 0)
		sample_count = ip->left_samples;
	    else
		sample_count = ip->right_samples;

	    for (i = 0; i < sample_count; i++) {

		uint8   fractions;
		int32   tmplong;
		uint16  tmpshort;
		uint16  sample_volume = 0;
		uint8   tmpchar, stereo_code = 0;
		Sample *sp = NULL;
#ifdef DFD
		uint32  tmpindex;

		tmp = whole_file + whole_file_offset;
		whole_file_offset += 96;

#define READ_CHAR(thing) \
      thing = tmp[tmpindex++];
#define READ_SHORT(thing) \
      tmpshort = *((uint16 *)(tmp + tmpindex)); \
      tmpindex += 2; \
      thing = LE_SHORT(tmpshort);
#define READ_LONG(thing) \
      tmplong = *((int32 *)(tmp + tmpindex)); \
      tmpindex += 4; \
      thing = LE_LONG(tmplong);
#define READ_SPLEN(thing) \
      tmplong = *((int32 *)(tmp + tmpindex)); \
      tmpindex += 4; \
      thing = (splen_t)(LE_LONG(tmplong));
#else

#define READ_CHAR(thing) \
      if (1 != fread(&tmpchar, 1, 1, fp)) goto fail; \
      thing = tmpchar;
#define READ_SHORT(thing) \
      if (1 != fread(&tmpshort, 2, 1, fp)) goto fail; \
      thing = LE_SHORT(tmpshort);
#define READ_LONG(thing) \
      if (1 != fread(&tmplong, 4, 1, fp)) goto fail; \
      thing = LE_LONG(tmplong);
#define READ_SPLEN(thing) \
      if (1 != fread(&tmplong, 4, 1, fp)) goto fail; \
      thing = (splen_t)(LE_LONG(tmplong));
#endif

#ifdef DFD
      		if (sf2flag) {
			tmpindex = 5;
			READ_CHAR(stereo_code);
			tmpindex++;
		}
		else tmpindex = 7; /* Skip the wave name */
#else
      		if (sf2flag) {
			skip (fp, 5);
			READ_CHAR(stereo_code);
			skip (fp, 1);
		}
		else skip (fp, 7);	/* Skip the wave name */
#endif

#ifdef DFD
		READ_CHAR(fractions);
		if (0) {
#else
		if (1 != fread (&fractions, 1, 1, fp)) {
#endif
		  fail:
		    ctl->cmsg (CMSG_ERROR, VERB_NORMAL,
			       "Error reading sample %d", i);
#ifndef DFD
    		    close_file (fp);
#endif
		    free_layer (headlp);
		    return NULL;
		}

		if (check_for_rc()) goto fail;


		if (stereo_layer == 0) {
		    sp = &(ip->left_sample[i]);
		    sp->stereo_mode = LEFT_SAMPLE;
		    if (sf2flag && stereo_code == 'M')
		        sp->stereo_mode = MONO_SAMPLE;
		}
		else if (stereo_layer == 1) {
		    sp = &(ip->right_sample[i]);
		    sp->stereo_mode = RIGHT_SAMPLE;
		}

		READ_SPLEN (sp->data_length);
		READ_SPLEN (sp->loop_start);
		READ_SPLEN (sp->loop_end);
		READ_SHORT (sp->sample_rate);
		READ_LONG (sp->low_freq);
		READ_LONG (sp->high_freq);
		READ_LONG (sp->root_freq);
#ifdef DFD
		tmpindex += 2;
#else
		skip (fp, 2);	/* Why have a "root frequency" and then "tuning"?? */

		READ_CHAR (tmp[0]);
#endif

		if (b->tone[tn].pan == -1)
#ifdef DFD
		    sp->panning = (tmp[tmpindex] * 8 + 4) & 0x7f;
#else
		    sp->panning = (tmp[0] * 8 + 4) & 0x7f;
#endif
		else
		    sp->panning = (uint8) (b->tone[tn].pan & 0x7F);
#ifdef DFD
		tmpindex++;
#endif


		if (b->tone[tn].tuning) {
		    double  tune_factor = (double) (b->tone[tn].tuning) / 1200.0;
		    tune_factor = pow (2.0, tune_factor);
		    sp->root_freq =
			(uint32) (tune_factor * (double) sp->root_freq);
		}

		/* envelope, tremolo, and vibrato */
#ifdef DFD
		tmpindex += 18;
#define OFIT 37
#else
		if (18 != fread (tmp, 1, 18, fp))
		    goto fail;
#define OFIT 0
#endif

		if (!tmp[13+OFIT] || !tmp[14+OFIT]) {
		    sp->tremolo_sweep_increment =
			sp->tremolo_phase_increment = sp->tremolo_depth = 0;
		    ctl->cmsg (CMSG_INFO, VERB_DEBUG, " * no tremolo");
		}
		else {
		    sp->tremolo_sweep_increment =
			convert_tremolo_sweep ((uint32)tmp[12+OFIT]);
		    sp->tremolo_phase_increment =
			convert_tremolo_rate ((uint32)tmp[13+OFIT]);
		    sp->tremolo_depth = tmp[14+OFIT];
		    ctl->cmsg (CMSG_INFO, VERB_DEBUG,
			       " * tremolo: sweep %d, phase %d, depth %d",
			       sp->tremolo_sweep_increment,
			       sp->tremolo_phase_increment,
			       sp->tremolo_depth);
		}

		if (!tmp[16+OFIT] || !tmp[17+OFIT]) {
		    sp->vibrato_sweep_increment =
			sp->vibrato_control_ratio = sp->vibrato_depth = 0;
		    ctl->cmsg (CMSG_INFO, VERB_DEBUG, " * no vibrato");
		}
		else {
		    sp->vibrato_control_ratio =
			convert_vibrato_rate ((uint32)tmp[16+OFIT]);
		    sp->vibrato_sweep_increment =
			convert_vibrato_sweep ((uint32)tmp[15+OFIT],
					       sp->vibrato_control_ratio);
		    sp->vibrato_depth = tmp[17+OFIT];
		    ctl->cmsg (CMSG_INFO, VERB_DEBUG,
			       " * vibrato: sweep %d, ctl %d, depth %d",
			       sp->vibrato_sweep_increment,
			       sp->vibrato_control_ratio, sp->vibrato_depth);

		}

		READ_CHAR (sp->modes);
		READ_SHORT (sp->freq_center);
		READ_SHORT (sp->freq_scale);

		if (sf2flag) {
		    READ_SHORT (sample_volume);
		    READ_CHAR (tmpchar);
		    if (tmpchar > 5)
			tmpchar = 5;
		    sp->envelope_rate[DELAY] =
			(int32) ((tmpchar * play_mode->rate) / 1000);
		    READ_CHAR (sp->exclusiveClass);

		    READ_CHAR (tmpchar);
		    sp->vibrato_delay = tmpchar * control_ratio;

		    for (j = ATTACK; j < DELAY; j++) {
			READ_CHAR (tmpchar);
			sp->modulation_rate[j] =
			    (j <
			     3) ? convert_envelope_rate_attack ((uint32)tmpchar) :
			    convert_envelope_rate ((uint32)tmpchar);
		    }

		    for (j = ATTACK; j < DELAY; j++) {
			READ_CHAR (tmpchar);
			sp->modulation_offset[j] =
			    convert_envelope_offset ((uint32)tmpchar);
		    }

		    READ_CHAR (tmpchar);
		    sp->modulation_rate[DELAY] =
			sp->modulation_offset[DELAY] =
			(int32) ((tmpchar * play_mode->rate) / 1000);

		    READ_CHAR (sp->chorusdepth);
		    READ_CHAR (sp->reverberation);
		    READ_SHORT (tmpshort);
		    //sp->resonance =
		    //	pow (10.0, (double) tmpshort / 2.0 / 200.0) - 1;
		    sp->resonance = tmpshort;
		    READ_SHORT (tmpshort);
		    if (tmpshort > 24000) tmpshort = 19192;
		    sp->cutoff_freq = (int32) tmpshort;
		    READ_CHAR (sp->modEnvToPitch);
		    READ_CHAR (sp->modEnvToFilterFc);
		    READ_CHAR (sp->modLfoToFilterFc);
		    READ_CHAR (sp->keyToModEnvHold);
		    READ_CHAR (sp->keyToModEnvDecay);
		    READ_CHAR (sp->keyToVolEnvHold);
		    READ_CHAR (sp->keyToVolEnvDecay);
		    READ_CHAR (tmpchar);
		    if (b->tone[tn].pan == -1)
			sp->panning = tmpchar / 2;
		    READ_SHORT (tmpshort);
		    READ_CHAR (sp->lfo_depth);

		    if (!tmpshort) {
		        sp->lfo_sweep_increment =
			    sp->lfo_phase_increment = sp->lfo_depth = 0;
		        ctl->cmsg (CMSG_INFO, VERB_DEBUG, " * no lfo for filter");
		    }
		    else {
		        sp->lfo_phase_increment = convert_vibrato_rate ((uint32)tmpshort);
		        sp->lfo_sweep_increment =
			    convert_vibrato_sweep ((1<<SWEEP_SHIFT)/tmpshort, 8176);
					           //sp->lfo_phase_increment);
		        ctl->cmsg (CMSG_INFO, VERB_DEBUG,
			           " * lfo: sweep %d, ctl %d, depth %d",
			           sp->lfo_sweep_increment,
			           sp->lfo_phase_increment, sp->lfo_depth);
		    }
		    READ_CHAR (sp->aps_parameter);
		    /* skip (fp, 1); */
		}
		else {
		    sp->resonance = 0;
		    if (percussion) sp->cutoff_freq = def_percussion_cutoff[tn];
		    else if (bank < 120 && default_cutoff[tn] >= 2000)
		    	sp->cutoff_freq = default_cutoff[tn];
		    else sp->cutoff_freq = 0;
		    sp->reverberation = 0;
		    sp->chorusdepth = 0;
		    sp->exclusiveClass = 0;
		    sp->keyToModEnvHold = 0;
		    sp->keyToModEnvDecay = 0;
		    sp->keyToVolEnvHold = 0;
		    sp->keyToVolEnvDecay = 0;
		    sp->modEnvToFilterFc = 0;
		    sp->modEnvToPitch = 0;
		    sp->lfo_sweep_increment = 0;
		    sp->lfo_phase_increment = 0;
		    sp->lfo_depth = 0;
		    sp->modLfoToFilterFc = 0;
		    sp->vibrato_delay = 0;
		    sp->envelope_rate[DELAY] = 0;
#ifdef DFD
		    tmpindex += 36;
#else
		    skip (fp, 36);
#endif
		}

		if (b->tone[tn].cutoff != -1) sp->cutoff_freq = b->tone[tn].cutoff;

		sp->trigger = TRIGGER_NONE;
		sp->sw_hikey = sp->sw_lokey = sp->sw_up = sp->sw_down = -1;
		sp->hirand = 1; sp->lorand = 0;
		sp->amp_random = 0;
		sp->samplesize = 16;

		/* Mark this as a fixed-pitch instrument if such a deed is desired. */
		if (note_to_use != -1)
		    sp->note_to_use = (uint8) (note_to_use);
		else
		    sp->note_to_use = 0;

		/* seashore.pat in the Midia patch set has no Sustain. I don't
		   understand why, and fixing it by adding the Sustain flag to
		   all looped patches probably breaks something else. We do it
		   anyway. */

		if (b->tone[tn].sustain != -1 && sp->modes & MODES_LOOPING) {
		    if (b->tone[tn].sustain == 1) sp->modes |= MODES_SUSTAIN;
		    else sp->modes &= ~MODES_SUSTAIN;
		}

		/* Strip any loops and envelopes we're permitted to */
		if ((strip_loop == 1) &&
		    (sp->modes & (MODES_SUSTAIN | MODES_LOOPING |
				  MODES_PINGPONG | MODES_REVERSE))) {
		    ctl->cmsg (CMSG_INFO, VERB_DEBUG,
			       " - Removing loop and/or sustain");
		    sp->modes &=
			~(MODES_SUSTAIN | MODES_LOOPING | MODES_PINGPONG |
			  MODES_REVERSE);
		}

		if (strip_envelope == 1) {
		    if (sp->modes & MODES_ENVELOPE)
			ctl->cmsg (CMSG_INFO, VERB_DEBUG,
				   " - Removing envelope");
		    sp->modes &= ~MODES_ENVELOPE;
		}
		else if (!sf2flag && strip_envelope != 0) {
		    /* Have to make a guess. */
		    if (!(sp->modes & (MODES_LOOPING | MODES_PINGPONG |
				  MODES_REVERSE))) {
			/* No loop? Then what's there to sustain? No envelope needed
			   either... */
			sp->modes &= ~(MODES_SUSTAIN | MODES_ENVELOPE);
			ctl->cmsg (CMSG_INFO, VERB_DEBUG,
				   " - No loop, removing sustain and envelope");
		    }
		    else if (!memcmp (tmp+OFIT, "??????", 6) || tmp[11+OFIT] >= 100) {
			/* Envelope rates all maxed out? Envelope end at a high "offset"?
			   That's a weird envelope. Take it out. */
			sp->modes &= ~MODES_ENVELOPE;
			ctl->cmsg (CMSG_INFO, VERB_DEBUG,
				   " - Weirdness, removing envelope");
		    }
		    else if (!(sp->modes & MODES_SUSTAIN)) {
			/* No sustain? Then no envelope.  I don't know if this is
			   justified, but patches without sustain usually don't need the
			   envelope either... at least the Gravis ones. They're mostly
			   drums.  I think. */
			sp->modes &= ~MODES_ENVELOPE;
			ctl->cmsg (CMSG_INFO, VERB_DEBUG,
				   " - No sustain, removing envelope");
		    }
		}

		sp->attenuation = 0;

		for (j = ATTACK; j < DELAY; j++) {
		    sp->envelope_rate[j] =
			(j < 3) ? convert_envelope_rate_attack ((uint32)tmp[j+OFIT]) :
			convert_envelope_rate ((uint32)tmp[j+OFIT]);
		    sp->envelope_offset[j] =
			convert_envelope_offset ((uint32)tmp[6 + j+OFIT]);
		}
		sp->envelope_offset[DELAY] = 0;

		if (!sf2flag)
		    for (j = ATTACK; j < DELAY; j++) {
			sp->modulation_rate[j] = sp->envelope_rate[j];
			sp->modulation_offset[j] = sp->envelope_offset[j];
		    }
		if (!sf2flag)
		    sp->modulation_rate[DELAY] =
			sp->modulation_offset[DELAY] = 0;

#ifdef EXAMINE_SOME_ENVELOPES
		if (percussion /* && (tn >= 42 && tn <= 51) */ ) {
		    printf ("\nPRESET %d:\n", tn);
		    printf (" attack(0): off %ld  rate %ld\n",
			    sp->envelope_offset[0] >> (7 + 15),
			    sp->envelope_rate[0] >> (7 + 15));
		    printf ("   hold(1): off %ld  rate %ld\n",
			    sp->envelope_offset[1] >> (7 + 15),
			    sp->envelope_rate[1] >> (7 + 15));
		    printf ("sustain(2): off %ld  rate %ld\n",
			    sp->envelope_offset[2] >> (7 + 15),
			    sp->envelope_rate[2] >> (7 + 15));
		    printf ("release(3): off %ld  rate %ld\n",
			    sp->envelope_offset[3] >> (7 + 15),
			    sp->envelope_rate[3] >> (7 + 15));
		    printf ("  decay(4): off %ld  rate %ld\n",
			    sp->envelope_offset[4] >> (7 + 15),
			    sp->envelope_rate[4] >> (7 + 15));
		    printf ("    die(5): off %ld  rate %ld\n",
			    sp->envelope_offset[5] >> (7 + 15),
			    sp->envelope_rate[5] >> (7 + 15));
		    printf ("  delay(6): off %ld  rate %ld\n",
			    sp->envelope_offset[6] >> (7 + 15),
			    sp->envelope_rate[6] >> (7 + 15));
		    printf ("MODES: %s%s%s%s\n",
			    (sp->modes & MODES_LOOPING) ? "looping " : "",
			    (sp->modes & MODES_SUSTAIN) ? "sustain " : "",
			    (sp->modes & MODES_PINGPONG) ? "pingpong " : "",
			    (sp->modes & MODES_REVERSE) ? "reverse " : "");
		}
#endif

		if (sp->data_length / 2 > MAX_SAMPLE_SIZE) {
		    ctl->cmsg (CMSG_ERROR, VERB_NORMAL,
			       "Sample length of %d is too big for me to handle",
			       sp->data_length);
		    goto fail;
		}

		/* Then read the sample data */
#ifdef DFD
		sp->data = (sample_t *)(whole_file + whole_file_offset);
		whole_file_offset += sp->data_length;
#else

#ifdef tplus
		sp->data = (sample_t *) safe_malloc (sp->data_length + 1);
#else
		sp->data = safe_malloc (sp->data_length);
#endif
		if (1 != fread (sp->data, sp->data_length, 1, fp)) {
		    ctl->cmsg (CMSG_ERROR, VERB_NORMAL,
			       "Data should have %d bytes, but does not.",
			       sp->data_length);
		    goto fail;
		}
#endif

		if (!(sp->modes & MODES_16BIT)) {	/* convert to 16-bit data */
		    int32   data_len = sp->data_length;
		    uint8  *cp = (uint8 *) (sp->data);
		    uint16 *tmpdta, *newdta;
#ifdef tplus
		    tmpdta = newdta =
			(uint16 *) safe_malloc (sp->data_length * 2 + 2);
#else
		    tmpdta = newdta = safe_malloc (sp->data_length * 2);
#endif
		    while (data_len--)
			*tmpdta++ = (uint16) (*cp++) << 8;
		    cp = (uint8 *) (sp->data);
		    sp->data = (sample_t *) newdta;
#ifdef DFD
		    add_purge(headlp, sp->data);
#else
		    free (cp);
#endif
		    sp->data_length *= 2;
		    sp->loop_start *= 2;
		    sp->loop_end *= 2;
		}
#ifndef LITTLE_ENDIAN
		else
		    /* convert to machine byte order */
		{
		    int32   data_len = sp->data_length / 2;
		    int16  *tmpdta = (int16 *) sp->data, s;
		    while (data_len--) {
			s = LE_SHORT (*tmpdta);
			*tmpdta++ = s;
		    }
		}
#endif

#ifndef DFD
		add_purge(headlp, sp->data);
#endif

#ifdef tplus
		headlp->size += sp->data_length + 1;
#else
		headlp->size += sp->data_length;
#endif

		if (sp->modes & MODES_UNSIGNED) {	/* convert to signed data */
		    int32   data_len = sp->data_length / 2;
#ifdef USE_POSIX_MAPPED_FILES
		    uint8  *cp = (uint8 *) (sp->data);
		    int16 *tmpdta;
		    tmpdta = (int16 *) safe_malloc (sp->data_length);
		    memcpy (tmpdta, cp, sp->data_length);
		    add_purge(headlp, tmpdta);
		    sp->data = tmpdta;
#else
		    int16  *tmpdta = (int16 *) sp->data;
#endif
		    while (data_len--)
			*tmpdta++ ^= 0x8000;
		    sp->modes &= ~MODES_UNSIGNED;
		}

		/* Reverse reverse loops and pass them off as normal loops */
		if (sp->modes & MODES_REVERSE) {
		    int32   t;
#ifdef USE_POSIX_MAPPED_FILES
		    uint8  *cp = (uint8 *) (sp->data);
		    int16 *tmpdta;
		    tmpdta = (int16 *) safe_malloc (sp->data_length);
		    memcpy (tmpdta, cp, sp->data_length);
		    add_purge(headlp, tmpdta);
		    sp->data = tmpdta;
#endif
		    /* The GUS apparently plays reverse loops by reversing the
		       whole sample. We do the same because the GUS does not SUCK. */

		    ctl->cmsg (CMSG_WARNING, VERB_NORMAL,
			       "Reverse loop in %s", name);
		    reverse_data ((int16 *) sp->data, 0, sp->data_length / 2);

		    t = sp->loop_start;
		    sp->loop_start = sp->data_length - sp->loop_end;
		    sp->loop_end = sp->data_length - t;

		    sp->modes &= ~MODES_REVERSE;
		    sp->modes |= MODES_LOOPING;	/* just in case */
		}

		/* If necessary do some anti-aliasing filtering  */

		if (antialiasing_allowed)
		    antialiasing (sp, play_mode->rate);

		if (amp != -1)
		    sp->volume = (double) (amp) / 100.0;
		else if (sf2flag) {
		    sp->volume=(FLOAT_T)((sample_volume) / 255.0);
		}
		else {
		    /* Try to determine a volume scaling factor for the sample.
		     * This is a very crude adjustment, but things sound more
		     * balanced with it.  Still, this should be a runtime option.
		     */
		    uint32  u;
		    int32   a, maxamp = 0;
		    int16  *ttmp = (int16 *) sp->data;

		    for (u = 0; u < sp->data_length / 2; u++)
			if ((a = abs (ttmp[u])) > maxamp)
			    maxamp = a;
		    sp->volume = 32768 / (double) maxamp;
		    ctl->cmsg (CMSG_INFO, VERB_DEBUG,
			       " * volume comp: %f", sp->volume);
		}

		sp->data_length /= 2;	/* These are in bytes. Convert into samples. */
		sp->loop_start /= 2;
		sp->loop_end /= 2;

#ifdef tplus
		/* The sample must be padded out by 1 extra sample, so that
		   round off errors in the offsets used in interpolation will not
		   cause a "pop" by reading random data beyond data_length */
#ifndef DFD
		sp->data[sp->data_length] = sp->data[sp->data_length - 1];
#endif
#endif

		/* Then fractional samples */
		sp->data_length <<= FRACTION_BITS;
		sp->loop_start <<= FRACTION_BITS;
		sp->loop_end <<= FRACTION_BITS;

		/* Adjust for fractional loop points. This is a guess. Does anyone
		   know what "fractions" really stands for? */
		sp->loop_start |= (fractions & 0x0F) << (FRACTION_BITS - 4);
		sp->loop_end |=
		    ((fractions >> 4) & 0x0F) << (FRACTION_BITS - 4);

		/* trim off zero data at end */
		{
		    int     ls = sp->loop_start >> FRACTION_BITS;
		    int     le = sp->loop_end >> FRACTION_BITS;
		    int     se = sp->data_length >> FRACTION_BITS;
		    while (se > 1 && !sp->data[se - 1])
			se--;
		    if (le > se)
			le = se;
		    if (ls >= le)
			sp->modes &= ~MODES_LOOPING;
		    sp->loop_end = le << FRACTION_BITS;
		    sp->data_length = se << FRACTION_BITS;
		}
#ifndef DFD
#ifdef LOOKUP_HACK
		/* Squash the 16-bit data into 8 bits. */
		{
		    uint8  *gulp, *ulp;
		    int16  *swp;
		    int     l = sp->data_length >> FRACTION_BITS;
		    gulp = ulp = safe_malloc (l + 1);
		    swp = (int16 *) sp->data;
		    while (l--)
			*ulp++ = (*swp++ >> 8) & 0xFF;
		    free (sp->data);
		    sp->data = (sample_t *) gulp;
		}
#endif
#endif

		if (strip_tail == 1) {
		    /* Let's not really, just say we did. */
		    ctl->cmsg (CMSG_INFO, VERB_DEBUG, " - Stripping tail");
		    sp->data_length = sp->loop_end;
		}
	    }			/* end of sample loop */
	}			/* end of stereo layer loop */
    }				/* end of vlayer loop */

#ifndef DFD
    close_file (fp);
#endif
    return headlp;
}


static int
fill_bank (int dr, int b)
{
    int     i, errors = 0;
    ToneBank *bank = ((dr) ? drumset[b] : tonebank[b]);
    if (!bank) {
	ctl->cmsg (CMSG_ERROR, VERB_NORMAL,
		   "Huh. Tried to load instruments in non-existent %s %d",
		   (dr) ? "drumset" : "tone bank", b);
	return 0;
    }
    for (i = 0; i < MAXPROG; i++) {
	if (check_for_rc ())
	    return 0;
	if (bank->tone[i].layer == MAGIC_LOAD_INSTRUMENT) {
	    if (!(bank->tone[i].name)) {
		const char *s;
		if (dr)
		    s = gm_voice[i + 128].vname;
		else
		    s = gm_voice[i].vname;
		if (s)
		    ctl->cmsg (CMSG_WARNING,
			       (b != 0) ? VERB_VERBOSE : VERB_NORMAL,
			       "No patch for %s %d, %s.",
			       (dr) ? "drumset" : "bank", b, s);
		else
		    ctl->cmsg (CMSG_WARNING,
			       (b != 0) ? VERB_VERBOSE : VERB_NORMAL,
			       "No patch for %s %d, program %d.",
			       (dr) ? "drumset" : "bank", b, i);
		if (b != 0) {
		    /* Mark the corresponding instrument in the default
		       bank / drumset for loading (if it isn't already) */
		    if (!dr) {
			if (!(standard_tonebank.tone[i].layer))
			    standard_tonebank.tone[i].layer =
				MAGIC_LOAD_INSTRUMENT;
		    }
		    else {
			if (!(standard_drumset.tone[i].layer))
			    standard_drumset.tone[i].layer =
				MAGIC_LOAD_INSTRUMENT;
		    }
		}
		bank->tone[i].layer = 0;
		errors++;
	    }
	    else if (!(bank->tone[i].layer = load_instrument (bank, b, i, dr))) {
		ctl->cmsg (CMSG_INFO, VERB_NORMAL,
			   "Couldn't load instrument %s (%s %d, program %d)",
			   bank->tone[i].name,
			   (dr) ? "drum set" : "tone bank", b, i);
		errors++;
	    }
	    else {		/* it's loaded now */
		bank->tone[i].last_used = current_tune_number;
		current_patch_memory += bank->tone[i].layer->size;
#ifdef DEBUG_MEM_PATCH
		ctl->cmsg (CMSG_ERROR, VERB_NORMAL,
			   "+mem %d (added %d)", current_patch_memory,
			   bank->tone[i].layer->size);
#endif
		purge_as_required ();
#if 0
		if (current_patch_memory > max_patch_memory) {
		    ctl->cmsg (CMSG_ERROR, VERB_NORMAL,
			       "Not enough memory to load instrument %s (%s %d, program %d)",
			       bank->tone[i].name,
			       (dr) ? "drum set" : "tone bank", b, i);
		    errors++;
		    free_layer (bank->tone[i].layer);
		    bank->tone[i].layer = 0;
		    bank->tone[i].last_used = -1;
		}
#endif
		if (check_for_rc ()) {
		    if (free_layer (bank->tone[i].layer)) {
		    	bank->tone[i].layer = 0;
		    	bank->tone[i].last_used = -1;
		    }
		    return 0;
		}
	    }

	}			/* if MAGIC ... */
    }				/* for */
    return errors;
}

static void
free_old_instruments (int how_old)
{
    int     i = MAXBANK;
    while (i--) {
	if (tonebank[i])
	    free_old_bank (0, i, how_old);
	if (drumset[i])
	    free_old_bank (1, i, how_old);
    }
}

static void
purge_as_required (void)
{
    if (!max_patch_memory)
	return;

    while (last_tune_purged < current_tune_number
	   && current_patch_memory > max_patch_memory) {
	last_tune_purged++;
#ifdef DEBUG_MEM_PATCH
	ctl->cmsg (CMSG_ERROR, VERB_NORMAL,
		   "purging patches older than %d", last_tune_purged);
#endif
	free_old_instruments (last_tune_purged);
    }
}

int
load_missing_instruments (void)
{
    int     i = MAXBANK, errors = 0;

#ifdef DEBUG_MEM_PATCH
    ctl->cmsg (CMSG_ERROR, VERB_NORMAL,
	       "load missing for song %d (last purged %d)",
	       current_tune_number, last_tune_purged);
#endif
    while (i--) {
	if (check_for_rc ())
	    return errors;
	if (tonebank[i])
	    errors += fill_bank (0, i);
	if (drumset[i])
	    errors += fill_bank (1, i);
    }
    current_tune_number++;
    return errors;
}

void
free_instruments (void)
{
    int     i = MAXBANK;
    while (i--) {
	if (tonebank[i])
	    free_bank (0, i);
	if (drumset[i])
	    free_bank (1, i);
    }
}

