/*
 * $Id: midipatch.h,v 1.7 1998/05/27 19:25:15 keithp Exp $
 *
 * Copyright © 1998 Keith Packard
 *
 * Permission to use, copy, modify, distribute, and sell this software and its
 * documentation for any purpose is hereby granted without fee, provided that
 * the above copyright notice appear in all copies and that both that
 * copyright notice and this permission notice appear in supporting
 * documentation, and that the name of Keith Packard not be used in
 * advertising or publicity pertaining to distribution of the software without
 * specific, written prior permission.  Keith Packard makes no
 * representations about the suitability of this software for any purpose.  It
 * is provided "as is" without express or implied warranty.
 *
 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 */

#include <gsi/whs_types.h>

#define INSTRUMENT_FIXED_FREQUENCY  1
#define INSTRUMENT_FIXED_VELOCITY   2
#define INSTRUMENT_RELEASE_LOOP	    4
#define INSTRUMENT_CHORUS	    8
#define INSTRUMENT_AUTO_PAN	    16

typedef struct _envelopeElement {
    int32	rate;
    int32	noteRate;
    int32	target;
} EnvelopeElement;


/*
 * Here's the disk structure:
 *
 *  Instrument
 *  SampleElement[0]
 *  SampleElement[1]
 *  ...
 *  SampleElement[n-1]
 *  EnvelopeElement[0][0]
 *  EnvelopeElement[0][1]
 *  ...
 *  EnvelopeElement[n-1][m-1]
 *  data[0][0]
 *  ...
 *  data[n-1][l-1]
 *
 *  Build an in-memory representation with a header containing
 *  the pointers and structures containing only offsets
 */

typedef struct _SampleElement {
    int32		    loop_start;
    int32		    loop_end;
    int32		    data_length;
    int32		    sample_rate;
    int32		    low_freq;
    int32		    high_freq;
    int32		    root_freq;
    int32		    nenvelope;
    int32		    release;
    int32		    envelope;	    /* offset from file data start */
    int32		    data;	    /* offset from file data start */
} SampleElement;

#define BINARY_MAGIC	"MidiPatchBin"

typedef struct _Instrument {
    char		magic[16];
    int32		flags;
    int32		nsamples;
    int32		envelopeTotal;
    int32		dataTotal;
    int32		tremelo_frequency;
    double		tremelo_scale;
    int32		vibrato_frequency;
    double		vibrato_scale;
} Instrument;

/*
 * This structure occurs only in memory
 */
typedef struct _MidiPatch {
    const char		    *name;
    const Instrument	    *instrument;
    const SampleElement	    *samples;
    const EnvelopeElement   *envelopes;
    const float		    *data;
    void		    (*free) (const struct _MidiPatch *);
    void		    *closure;
} MidiPatch;

#define MSEnvelope(p,s)	    ((p)->envelopes + (s)->envelope)
#define MSData(p,s)	    ((p)->data + (s)->data)

/*
 * This maps from instrument names to file names
 */
typedef struct _MidiMapElement {
    const char		*name;
    const char		*file;
    const MidiPatch	*patch;
} MidiMapElement;

typedef struct _MidiMap {
    MidiMapElement  *map;
    int		    nmap;
    char	    *dir;
} MidiMap;


const MidiMap	*GetPatchMap (char *mapFile);
void		FreePatchMap (const MidiMap *map);
const MidiPatch	*LoadPatchFile (const char *fname);
const MidiPatch	*LoadPatch (const MidiMap *map, const char *name);

#define MIDI_PATCH_TEXT	    ".ma"
#define MIDI_PATCH_BINARY   ".mb"
#define MIDI_PATCH_MAP	    ".mp"
#define MIDI_PATCH_GUS	    ".pat"
