/***************************************************************************
*       NAME:  PICK.C $Revision: 1.7 $
**      COPYRIGHT:
**      "Copyright (c) 1994,1995 by e-Tek Labs"
**
**       "This software is furnished under a license and may be used,
**       copied, or disclosed only in accordance with the terms of such
**       license and with the inclusion of the above copyright notice.
**       This software or any other copies thereof may not be provided or
**       otherwise made available to any other person. No title to and
**       ownership of the software is hereby transfered."
****************************************************************************/
#include "sbosdata.h"
#include "sbosdefs.h"
#include "shared.h"
#include "fm.h"
#include "synproto.h"
#include "picktbl.h"

extern SHARED shared;
extern unsigned int fm_chan;         /** fm channel number                   **/
extern unsigned int fm_voice;        /** IW channel number                   **/
extern unsigned int car_voice;
extern unsigned int mod_voice;
extern unsigned char csm_sel_reg;    /** Register 8                          **/
extern unsigned char rhythm_reg;     /** Register BD                         **/
extern FM_CHANNEL * chan_ptr;        /** Ptr to channel if applicable        **/
extern FM_OPERATOR * voice_ptr;      /** Ptr to voice if applicable (c or m) **/
extern FM_OPERATOR * car_ptr;        /** Channel's carrier if applicable     **/
extern FM_OPERATOR * mod_ptr;        /** Channel's modulator if applicable   **/
extern void asm_fm_picker(void);
extern void check_for_effect(void);

#ifdef DEBUG
#include "debug.h"
extern int cur_instrument[];
extern int cur_bank[];
extern int force_instrument[];
extern unsigned char pick_list[9][PICK_LIST_SIZE];
extern int nmi_count;
#endif

char best_inst=0;

/****************************************************************************

FUNCTION DEFINITION:
fm_picker - Determines the best GM instrument to match the current FM
  paremeters.

SEE ALSO:
  asm_fm_picker

*/
void fm_picker(void)
{
#ifdef DEBUG
    int j;
#endif

#ifdef DEBUG
    if(force_instrument[fm_chan])
        {
        /** force the instrument and leave **/
        syn_set_instrument(car_voice,cur_bank[fm_chan],
            cur_instrument[fm_chan]);
        return;
        }
    else
        {
        /** clear the pick list **/
        for(j = 0; j < PICK_LIST_SIZE; j++)
            pick_list[fm_chan][j] = 0xff;
        }
#endif

    asm_fm_picker(); /** returns new instrument choice in best_inst **/

    check_for_effect(); /** see if there is noise to play **/

    /** Set the instrument based on high bit **/
    if((best_inst & 0x80) == 0) /** high bit off for melodics **/
        {
#ifdef DEBUG
        cur_instrument[fm_chan] = best_inst;
        cur_bank[fm_chan] = TYPE_MELODIC;
#endif
                syn_set_instrument(car_voice,TYPE_MELODIC,best_inst);
        }
    else /** PERCUSSION **/
        {
#ifdef DEBUG
        cur_instrument[fm_chan] = (best_inst & 0x7f);
        cur_bank[fm_chan] = TYPE_PERC;
#endif
                syn_set_instrument(car_voice,TYPE_PERC,best_inst&0x7f);
        }
}

/****************************************************************************

FUNCTION DEFINITION:
sine_picker - Sets up to play an equivalent FM sine wave

DESCRIPTION:
  The 4 sine waves an adlib can play are directly mapped to a bank in
  soundcard memory.  This sets up the card to play one of those four.

*/
void sine_picker(void)
{
    /** For now, this is it for the Sine wave patch picker **/
#ifdef DEBUG
    cur_instrument[fm_chan] = car_ptr->wave;
    cur_bank[fm_chan] = TYPE_BASIC;
#endif

    /**
     ** Set it if it was changed because of noise or effect
     **/
    if (mod_ptr->param & 0x20)
        syn_set_sustain(mod_voice,TRUE);
    else
        syn_set_sustain(mod_voice,FALSE);

    syn_set_instrument(car_voice,TYPE_BASIC,car_ptr->wave);
    syn_set_instrument(mod_voice,TYPE_BASIC,mod_ptr->wave);
}
