/*
 * Midi port and channel structures
 */

#ifndef __EMU8000_PORT_H
#define __EMU8000_PORT_H

#include "../../include/emu8000.h"
#include "../../include/seq_midi_emul.h"
#include "emu8000_legacy.h"
#include "../../include/soundfont.h"
#ifdef CONFIG_SND_OSSEMUL
#include "../../include/seq_oss.h"
#endif


/*
 * effect table
 */
typedef struct emu8000_effect_table_t {
	/* Emu8000 specific effects */
	short val[EMU8000_NUM_EFFECTS];
	unsigned char flag[EMU8000_NUM_EFFECTS];
} emu8000_effect_table_t;

/*
 * sequencer port information
 */
typedef struct emu8000_port_t {

	snd_midi_channel_set_t chset;

	emu8000_t *emu;

	char port_mode;	/* operation mode */
	
	/* volume attenuation */
	int volume_atten;	/* emu8000 raw attenuation */

	/* drum bitmaps */
	unsigned long drum_flags;

	/* control parameters */
	int ctrls[EMU8000_MD_END];

	emu8000_effect_table_t *effect;

#ifdef CONFIG_SND_OSSEMUL
	snd_seq_oss_arg_t *oss_arg;
#endif

} emu8000_port_t;

/* port_mode */
#define PORT_MODE_MIDI		0	/* normal MIDI port */
#define PORT_MODE_OSS_SYNTH	1	/* OSS synth port */
#define PORT_MODE_OSS_MIDI	2	/* OSS multi channel synth port */


/* prototypes for emu8000.c */
void snd_emu8000_poke(emu8000_t *emu, unsigned int port, unsigned int reg,
		      unsigned int val);
unsigned short snd_emu8000_peek(emu8000_t *emu, unsigned int port,
				unsigned int reg);
void snd_emu8000_poke_dw(emu8000_t *emu, unsigned int port, unsigned int reg,
			 unsigned int val);
unsigned int snd_emu8000_peek_dw(emu8000_t *emu, unsigned int port,
				 unsigned int reg);

void snd_emu8000_dma_chan(emu8000_t *emu, int ch, int write);
int snd_emu8000_open_dma(emu8000_t *emu, int write);
void snd_emu8000_close_dma(emu8000_t *emu);
void snd_emu8000_read_wait(emu8000_t *emu);
void snd_emu8000_write_wait(emu8000_t *emu);
void snd_emu8000_wait(emu8000_t *emu, unsigned short delay);

/* Prototypes for emu8000_init.c */
void snd_emu8000_init(emu8000_t *emu);
void snd_emu8000_init_fm(emu8000_t *emu);
void snd_emu8000_tweak_voice(emu8000_t *emu, int i);

/* Prototypes for emu8000_patch.c */
int snd_emu8000_sample_write(void *private, snd_sf_sample_t *sp, const void *data, long count);
int snd_emu8000_patch(emu8000_t *emu, const void *data, long count);

/* Prototypes for emu8000_proc.c */
void snd_emu8000_proc_init(emu8000_t *emu);
void snd_emu8000_proc_free(snd_info_entry_t *ip);

/* Prototypes for emu8000_seq.c */
int snd_emu8000_init_seq(emu8000_t *emu);
void snd_emu8000_detach_seq(emu8000_t *emu);
emu8000_port_t *snd_emu8000_create_port(emu8000_t *emu, char *name, int max_channels, int type, snd_seq_port_callback_t *callback);
void snd_emu8000_reset_port(emu8000_port_t *port);
int snd_emu8000_event_input(snd_seq_event_t *ev, int direct, void *private, int atomic, int hop);
void snd_emu8000_inc_count(emu8000_t *emu);
void snd_emu8000_dec_count(emu8000_t *emu);

/* Prototypes for emu8000_synth.c */
void snd_emu8000_note_on(void *p, int note, int vel, struct snd_midi_channel *chan);
void snd_emu8000_note_off(void *p, int note, int vel, struct snd_midi_channel *chan);
void snd_emu8000_key_press(void *p, int note, int vel, struct snd_midi_channel *chan);
void snd_emu8000_update_channel(emu8000_t *emu, snd_midi_channel_t *chan, int update);
void snd_emu8000_update_port(emu8000_t *emu, emu8000_port_t *port, int update);

void snd_emu8000_note_terminate(void *p, int note, snd_midi_channel_t *chan);
void snd_emu8000_terminate_all(emu8000_t *emu);
void snd_emu8000_sounds_off_all(emu8000_t *emu, emu8000_port_t *port);

void snd_emu8000_control(void *p, int type, struct snd_midi_channel *chan);
void snd_emu8000_send_effect_oss(emu8000_t *emu, snd_midi_channel_t *chan, int type, int val);
void snd_emu8000_send_effect(emu8000_t *emu, snd_midi_channel_t *chan, int type, int val, int mode);

/* emu8000_nrpn.c */
void snd_emu8000_sysex(void *private, unsigned char *buf, int len, int parsed, snd_midi_channel_set_t *chset);
int snd_emu8000_xg_control(emu8000_t *emu, emu8000_port_t *port,
			   snd_midi_channel_t *chan, int param);
void snd_emu8000_nrpn(void *private, snd_midi_channel_t *chan, snd_midi_channel_set_t *chset);

/* emu8000_oss.c */
void snd_emu8000_init_seq_oss(emu8000_t *emu);
void snd_emu8000_free_seq_oss(emu8000_t *emu);

#endif
