/*
 * sound/sequencer.c
 *
 * The sequencer personality manager.
 */
/*
 * Copyright (C) by Hannu Savolainen 1993-1997
 *
 * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
 * Version 2 (June 1991). See the "COPYING" file distributed with this software
 * for more info.
 */
/*
 * Thomas Sailer   : ioctl code reworked (vmalloc/vfree removed)
 * Alan Cox	   : reformatted and fixed a pair of null pointer bugs
 */
#include <linux/kmod.h>
#include <linux/spinlock.h>
#define SEQUENCER_C
#include "sound_config.h"

#include "midi_ctrl.h"

static int      sequencer_ok;
static struct sound_timer_operations *tmr;
static int      tmr_no = -1;	/* Currently selected timer */
static int      pending_timer = -1;	/* For timer change operation */
extern unsigned long seq_time;

static int      obsolete_api_used;
static DEFINE_SPINLOCK(lock);

/*
 * Local counts for number of synth and MIDI devices. These are initialized
 * by the sequencer_open.
 */
static int      max_mididev;
static int      max_synthdev;

/*
 * The seq_mode gives the operating mode of the sequencer:
 *      1 = level1 (the default)
 *      2 = level2 (extended capabilities)
 */

#define SEQ_1	1
#define SEQ_2	2
static int      seq_mode = SEQ_1;

static DECLARE_WAIT_QUEUE_HEAD(seq_sleeper);
static DECLARE_WAIT_QUEUE_HEAD(midi_sleeper);

static int      midi_opened[MAX_MIDI_DEV];

static int      midi_written[MAX_MIDI_DEV];

static unsigned long prev_input_time;
static int      prev_event_time;

#include "tuning.h"

#define EV_SZ	8
#define IEV_SZ	8

static unsigned char *queue;
static unsigned char *iqueue;

static volatile int qhead, qtail, qlen;
static volatile int iqhead, iqtail, iqlen;
static volatile int seq_playing;
static volatile int sequencer_busy;
static int      output_threshold;
static long     pre_event_timeout;
static unsigned synth_open_mask;

static int      seq_queue(unsigned char *note, char nonblock);
static void     seq_startplay(void);
static int      seq_sync(void);
static void     seq_reset(void);

#if MAX_SYNTH_DEV > 15
#error Too many synthesizer devices enabled.
#endif

int sequencer_read(int dev, struct file *file, char __user *buf, int count)
{
	int c = count, p = 0;
	int ev_len;
	unsigned long flags;

	dev = dev >> 4;

	ev_len = seq_mode == SEQ_1 ? 4 : 8;

	spin_lock_irqsave(&lock,flags);

	if (!iqlen)
	{
		spin_unlock_irqrestore(&lock,flags);
 		if (file->f_flags & O_NONBLOCK) {
  			return -EAGAIN;
  		}

 		interruptible_sleep_on_timeout(&midi_sleeper,
					       pre_event_timeout);
		spin_lock_irqsave(&lock,flags);
		if (!iqlen)
		{
			spin_unlock_irqrestore(&lock,flags);
			return 0;
		}
	}
	while (iqlen && c >= ev_len)
	{
		char *fixit = (char *) &iqueue[iqhead * IEV_SZ];
		spin_unlock_irqrestore(&lock,flags);
		if (copy_to_user(&(buf)[p], fixit, ev_len))
			return count - c;
		p += ev_len;
		c -= ev_len;

		spin_lock_irqsave(&lock,flags);
		iqhead = (iqhead + 1) % SEQ_MAX_QUEUE;
		iqlen--;
	}
	spin_unlock_irqrestore(&lock,flags);
	return count - c;
}

static void sequencer_midi_output(int dev)
{
	/*
	 * Currently NOP
	 */
}

void seq_copy_to_input(unsigned char *event_rec, int len)
{
	unsigned long flags;

	/*
	 * Verify that the len is valid for the current mode.
	 */

	if (len != 4 && len != 8)
		return;
	if ((seq_mode == SEQ_1) != (len == 4))
		return;

	if (iqlen >= (SEQ_MAX_QUEUE - 1))
		return;		/* Overflow */

	spin_lock_irqsave(&lock,flags);
	memcpy(&iqueue[iqtail * IEV_SZ], event_rec, len);
	iqlen++;
	iqtail = (iqtail + 1) % SEQ_MAX_QUEUE;
	wake_up(&midi_sleeper);
	spin_unlock_irqrestore(&lock,flags);
}

static void sequencer_midi_input(int dev, unsigned char data)
{
	unsigned int tstamp;
	unsigned char event_rec[4];

	if (data == 0xfe)	/* Ignore active sensing */
		return;

	tstamp = jiffies - seq_time;

	if (tstamp != prev_input_time)
	{
		tstamp = (tstamp << 8) | SEQ_WAIT;
		seq_copy_to_input((unsigned char *) &tstamp, 4);
		prev_input_time = tstamp;
	}
	event_rec[0] = SEQ_MIDIPUTC;
	event_rec[1] = data;
	event_rec[2] = dev;
	event_rec[3] = 0;

	seq_copy_to_input(event_rec, 4);
}

void seq_input_event(unsigned char *event_rec, int len)
{
	unsigned long this_time;

	if (seq_mode == SEQ_2)
		this_time = tmr->get_time(tmr_no);
	else
		this_time = jiffies - seq_time;

	if (this_time != prev_input_time)
	{
		unsigned char   tmp_event[8];

		tmp_event[0] = EV_TIMING;
		tmp_event[1] = TMR_WAIT_ABS;
		tmp_event[2] = 0;
		tmp_event[3] = 0;
		*(unsigned int *) &tmp_event[4] = this_time;

		seq_copy_to_input(tmp_event, 8);
		prev_input_time = this_time;
	}
	seq_copy_to_input(event_rec, len);
}

int sequencer_write(int dev, struct file *file, const char __user *buf, int count)
{
	unsigned char event_rec[EV_SZ], ev_code;
	int p = 0, c, ev_size;
	int err;
	int mode = translate_mode(file);

	dev = dev >> 4;

	DEB(printk("sequencer_write(dev=%d, count=%d)\n", dev, count));

	if (mode == OPEN_READ)
		return -EIO;

	c = count;

	while (c >= 4)
	{
		if (copy_from_user((char *) event_rec, &(buf)[p], 4))
			goto out;
		ev_code = event_rec[0];

		if (ev_code == SEQ_FULLSIZE)
		{
			int err, fmt;

			dev = *(unsigned short *) &event_rec[2];
			if (dev < 0 || dev >= max_synthdev || synth_devs[dev] == NULL)
				return -ENXIO;

			if (!(synth_open_mask & (1 << dev)))
				return -ENXIO;

			fmt = (*(short *) &event_rec[0]) & 0xffff;
			err = synth_devs[dev]->load_patch(dev, fmt, buf, p + 4, c, 0);
			if (err < 0)
				return err;

			return err;
		}
		if (ev_code >= 128)
		{
			if (seq_mode == SEQ_2 && ev_code == SEQ_EXTENDED)
			{
				printk(KERN_WARNING "Sequencer: Invalid level 2 event %x\n", ev_code);
				return -EINVAL;
			}
			ev_size = 8;

			if (c < ev_size)
			{
				if (!seq_playing)
					seq_startplay();
				return count - c;
			}
			if (copy_from_user((char *)&event_rec[4],
					   &(buf)[p + 4], 4))
				goto out;

		}
		else
		{
			if (seq_mode == SEQ_2)
			{
				printk(KERN_WARNING "Sequencer: 4 byte event in level 2 mode\n");
				return -EINVAL;
			}
			ev_size = 4;

			if (event_rec[0] != SEQ_MIDIPUTC)
				obsolete_api_used = 1;
		}

		if (event_rec[0] == SEQ_MIDIPUTC)
		{
			if (!midi_opened[event_rec[2]])
			{
				int mode;
				int dev = event_rec[2];

				if (dev >= max_mididev || midi_devs[dev]==NULL)
				{
					/*printk("Sequencer Error: Nonexistent MIDI device %d\n", dev);*/
					return -ENXIO;
				}
				mode = translate_mode(file);

				if ((err = midi_devs[dev]->open(dev, mode,
								sequencer_midi_input, sequencer_midi_output)) < 0)
				{
					seq_reset();
					printk(KERN_WARNING "Sequencer Error: Unable to open Midi #%d\n", dev);
					return err;
				}
				midi_opened[dev] = 1;
			}
		}
		if (!seq_queue(event_rec, (file->f_flags & (O_NONBLOCK) ? 1 : 0)))
		{
			int processed = count - c;

			if (!seq_playing)
				seq_startplay();

			if (!processed && (file->f_flags & O_NONBLOCK))
				return -EAGAIN;
			else
				return processed;
		}
		p += ev_size;
		c -= ev_size;
	}

	if (!seq_playing)
		seq_startplay();
out:
	return count;
}

static int seq_queue(unsigned char *note, char nonblock)
{

	/*
	 * Test if there is space in the queue
	 */

	if (qlen >= SEQ_MAX_QUEUE)
		if (!seq_playing)
			seq_startplay();	/*
						 * Give chance to drain the queue
						 */

	if (!nonblock && qlen >= SEQ_MAX_QUEUE && !waitqueue_active(&seq_sleeper)) {
		/*
		 * Sleep until there is enough space on the queue
		 */
		interruptible_sleep_on(&seq_sleeper);
	}
	if (qlen >= SEQ_MAX_QUEUE)
	{
		return 0;	/*
				 * To be sure
				 */
	}
	memcpy(&queue[qtail * EV_SZ], note, EV_SZ);

	qtail = (qtail + 1) % SEQ_MAX_QUEUE;
	qlen++;

	return 1;
}

static int extended_event(unsigned char *q)
{
	int dev = q[2];

	if (dev < 0 || dev >= max_synthdev)
		return -ENXIO;

	if (!(synth_open_mask & (1 << dev)))
		return -ENXIO;

	switch (q[1])
	{
		case SEQ_NOTEOFF:
			synth_devs[dev]->kill_note(dev, q[3], q[4], q[5]);
			break;

		case SEQ_NOTEON:
			if (q[4] > 127 && q[4] != 255)
				return 0;

			if (q[5] == 0)
			{
				synth_devs[dev]->kill_note(dev, q[3], q[4], q[5]);
				break;
			}
			synth_devs[dev]->start_note(dev, q[3], q[4], q[5]);
			break;

		case SEQ_PGMCHANGE:
			synth_devs[dev]->set_instr(dev, q[3], q[4]);
			break;

		case SEQ_AFTERTOUCH:
			synth_devs[dev]->aftertouch(dev, q[3], q[4]);
			break;

		case SEQ_BALANCE:
			synth_devs[dev]->panning(dev, q[3], (char) q[4]);
			break;

		case SEQ_CONTROLLER:
			synth_devs[dev]->controller(dev, q[3], q[4], (short) (q[5] | (q[6] << 8)));
			break;

		case SEQ_VOLMODE:
			if (synth_devs[dev]->volume_method != NULL)
				synth_devs[dev]->volume_method(dev, q[3]);
			break;

		default:
			return -EINVAL;
	}
	return 0;
}

static int find_voice(int dev, int chn, int note)
{
	unsigned short key;
	int i;

	key = (chn << 8) | (note + 1);
	for (i = 0; i < synth_devs[dev]->alloc.max_voice; i++)
		if (synth_devs[dev]->alloc.map[i] == key)
			return i;
	return -1;
}

static int alloc_voice(int dev, int chn, int note)
{
	unsigned short  key;
	int voice;

	key = (chn << 8) | (note + 1);

	voice = synth_devs[dev]->alloc_voice(dev, chn, note,
					     &synth_devs[dev]->alloc);
	synth_devs[dev]->alloc.map[voice] = key;
	synth_devs[dev]->alloc.alloc_times[voice] =
			synth_devs[dev]->alloc.timestamp++;
	return voice;
}

static void seq_chn_voice_event(unsigned char *event_rec)
{
#define dev event_rec[1]
#define cmd event_rec[2]
#define chn event_rec[3]
#define note event_rec[4]
#define parm event_rec[5]

	int voice = -1;

	if ((int) dev > max_synthdev || synth_devs[dev] == NULL)
		return;
	if (!(synth_open_mask & (1 << dev)))
		return;
	if (!synth_devs[dev])
		return;

	if (seq_mode == SEQ_2)
	{
		if (synth_devs[dev]->alloc_voice)
			voice = find_voice(dev, chn, note);

		if (cmd == MIDI_NOTEON && parm == 0)
		{
			cmd = MIDI_NOTEOFF;
			parm = 64;
		}
	}

	switch (cmd)
	{
		case MIDI_NOTEON:
			if (note > 127 && note != 255)	/* Not a seq2 feature */
				return;

			if (voice == -1 && seq_mode == SEQ_2 && synth_devs[dev]->alloc_voice)
			{
				/* Internal synthesizer (FM, GUS, etc) */
				voice = alloc_voice(dev, chn, note);
			}
			if (voice == -1)
				voice = chn;

			if (seq_mode == SEQ_2 && (int) dev < num_synths)
			{
				/*
				 * The MIDI channel 10 is a percussive channel. Use the note
				 * number to select the proper patch (128 to 255) to play.
				 */

				if (chn == 9)
				{
					synth_devs[dev]->set_instr(dev, voice, 128 + note);
					synth_devs[dev]->chn_info[chn].pgm_num = 128 + note;
				}
				synth_devs[dev]->setup_voice(dev, voice, chn);
			}
			synth_devs[dev]->start_note(dev, voice, note, parm);
			break;

		case MIDI_NOTEOFF:
			if (voice == -1)
				voice = chn;
			synth_devs[dev]->kill_note(dev, voice, note, parm);
			break;

		case MIDI_KEY_PRESSURE:
			if (voice == -1)
				voice = chn;
			synth_devs[dev]->aftertouch(dev, voice, parm);
			break;

		default:;
	}
#undef dev
#undef cmd
#undef chn
#undef note
#undef parm
}


static void seq_chn_common_event(unsigned char *event_rec)
{
	unsigned char dev = event_rec[1];
	unsigned char cmd = event_rec[2];
	unsigned char chn = event_rec[3];
	unsigned char p1 = event_rec[4];

	/* unsigned char p2 = event_rec[5]; */
	unsigned short w14 = *(short *) &event_rec[6];

	if ((int) dev > max_synthdev || synth_devs[dev] == NULL)
		return;
	if (!(synth_open_mask & (1 << dev)))
		return;
	if (!synth_devs[dev])
		return;

	switch (cmd)
	{
		case MIDI_PGM_CHANGE:
			if (seq_mode == SEQ_2)
			{
				synth_devs[dev]->chn_info[chn].pgm_num = p1;
				if ((int) dev >= num_synths)
					synth_devs[dev]->set_instr(dev, chn, p1);
			}
			else
				synth_devs[dev]->set_instr(dev, chn, p1);

			break;

		case MIDI_CTL_CHANGE:
			if (seq_mode == SEQ_2)
			{
				if (chn > 15 || p1 > 127)
					break;

				synth_devs[dev]->chn_info[chn].controllers[p1] = w14 & 0x7f;

				if (p1 < 32)	/* Setting MSB should clear LSB to 0 */
					synth_devs[dev]->chn_info[chn].controllers[p1 + 32] = 0;

				if ((int) dev < num_synths)
				{
					int val = w14 & 0x7f;
					int i, key;

					if (p1 < 64)	/* Combine MSB and LSB */
					{
						val = ((synth_devs[dev]->
							chn_info[chn].controllers[p1 & ~32] & 0x7f) << 7)
							| (synth_devs[dev]->
							chn_info[chn].controllers[p1 | 32] & 0x7f);
						p1 &= ~32;
					}
					/* Handle all playing notes on this channel */

					key = ((int) chn << 8);

					for (i = 0; i < synth_devs[dev]->alloc.max_voice; i++)
						if ((synth_devs[dev]->alloc.map[i] & 0xff00) == key)
							synth_devs[dev]->controller(dev, i, p1, val);
				}
				else
					synth_devs[dev]->controller(dev, chn, p1, w14);
			}
			else	/* Mode 1 */
				synth_devs[dev]->controller(dev, chn, p1, w14);
			break;

		case MIDI_PITCH_BEND:
			if (seq_mode == SEQ_2)
			{
				synth_devs[dev]->chn_info[chn].bender_value = w14;

				if ((int) dev < num_synths)
				{
					/* Handle all playing notes on this channel */
					int i, key;

					key = (chn << 8);

					for (i = 0; i < synth_devs[dev]->alloc.max_voice; i++)
						if ((synth_devs[dev]->alloc.map[i] & 0xff00) == key)
							synth_devs[dev]->bender(dev, i, w14);
				}
				else
					synth_devs[dev]->bender(dev, chn, w14);
			}
			else	/* MODE 1 */
				synth_devs[dev]->bender(dev, chn, w14);
			break;

		default:;
	}
}

static int seq_timing_event(unsigned char *event_rec)
{
	unsigned char cmd = event_rec[1];
	unsigned int parm = *(int *) &event_rec[4];

	if (seq_mode == SEQ_2)
	{
		int ret;

		if ((ret = tmr->event(tmr_no, event_rec)) == TIMER_ARMED)
			if ((SEQ_MAX_QUEUE - qlen) >= output_threshold)
				wake_up(&seq_sleeper);
		return ret;
	}
	switch (cmd)
	{
		case TMR_WAIT_REL:
			parm += prev_event_time;

			/*
			 * NOTE!  No break here. Execution of TMR_WAIT_REL continues in the
			 * next case (TMR_WAIT_ABS)
			 */

		case TMR_WAIT_ABS:
			if (parm > 0)
			{
				long time;

				time = parm;
				prev_event_time = time;

				seq_playing = 1;
				request_sound_timer(time);

				if ((SEQ_MAX_QUEUE - qlen) >= output_threshold)
					wake_up(&seq_sleeper);
				return TIMER_ARMED;
			}
			break;

		case TMR_START:
			seq_time = jiffies;
			prev_input_time = 0;
			prev_event_time = 0;
			break;

		case TMR_STOP:
			break;

		case TMR_CONTINUE:
			break;

		case TMR_TEMPO:
			break;

		case TMR_ECHO:
			if (seq_mode == SEQ_2)
				seq_copy_to_input(event_rec, 8);
			else
			{
				parm = (parm << 8 | SEQ_ECHO);
				seq_copy_to_input((unsigned char *) &parm, 4);
			}
			break;

		default:;
	}

	return TIMER_NOT_ARMED;
}

static void seq_local_event(unsigned char *event_rec)
{
	unsigned char   cmd = event_rec[1];
	unsigned int    parm = *((unsigned int *) &event_rec[4]);

	switch (cmd)
	{
		case LOCL_STARTAUDIO:
			DMAbuf_start_devices(parm);
			break;

		default:;
	}
}

static void seq_sysex_message(unsigned char *event_rec)
{
	unsigned int dev = event_rec[1];
	int i, l = 0;
	unsigned char  *buf = &event_rec[2];

	if (dev > max_synthdev)
		return;
	if (!(synth_open_mask & (1 << dev)))
		return;
	if (!synth_devs[dev])
		return;

	l = 0;
	for (i = 0; i < 6 && buf[i] != 0xff; i++)
		l = i + 1;

	if (!synth_devs[dev]->send_sysex)
		return;
	if (l > 0)
		synth_devs[dev]->send_sysex(dev, buf, l);
}

static int play_event(unsigned char *q)
{
	/*
	 * NOTE! This routine returns
	 *   0 = normal event played.
	 *   1 = Timer armed. Suspend playback until timer callback.
	 *   2 = MIDI output buffer full. Restore queue and suspend until timer
	 */
	unsigned int *delay;

	switch (q[0])
	{
		case SEQ_NOTEOFF:
			if (synth_open_mask & (1 << 0))
				if (synth_devs[0])
					synth_devs[0]->kill_note(0, q[1], 255, q[3]);
			break;

		case SEQ_NOTEON:
			if (q[4] < 128 || q[4] == 255)
				if (synth_open_mask & (1 << 0))
					if (synth_devs[0])
						synth_devs[0]->start_note(0, q[1], q[2], q[3]);
			break;

		case SEQ_WAIT:
			delay = (unsigned int *) q;	/*
							 * Bytes 1 to 3 are containing the *
							 * delay in 'ticks'
							 */
			*delay = (*delay >> 8) & 0xffffff;

			if (*delay > 0)
			{
				long time;

				seq_playing = 1;
				time = *delay;
				prev_event_time = time;

				request_sound_timer(time);

				if ((SEQ_MAX_QUEUE - qlen) >= output_threshold)
					wake_up(&seq_sleeper);
				/*
				 * The timer is now active and will reinvoke this function
				 * after the timer expires. Return to the caller now.
				 */
				return 1;
			}
			break;

		case SEQ_PGMCHANGE:
			if (synth_open_mask & (1 << 0))
				if (synth_devs[0])
					synth_devs[0]->set_instr(0, q[1], q[2]);
			break;

		case SEQ_SYNCTIMER: 	/*
					 * Reset timer
					 */
			seq_time = jiffies;
			prev_input_time = 0;
			prev_event_time = 0;
			break;

		case SEQ_MIDIPUTC:	/*
					 * Put a midi character
					 */
			if (midi_opened[q[2]])
			{
				int dev;

				dev = q[2];

				if (dev < 0 || dev >= num_midis || midi_devs[dev] == NULL)
					break;

				if (!midi_devs[dev]->outputc(dev, q[1]))
				{
					/*
					 * Output FIFO is full. Wait one timer cycle and try again.
					 */

					seq_playing = 1;
					request_sound_timer(-1);
					return 2;
				}
				else
					midi_written[dev] = 1;
			}
			break;

		case SEQ_ECHO:
			seq_copy_to_input(q, 4);	/*
							 * Echo back to the process
							 */
			break;

		case SEQ_PRIVATE:
			if ((int) q[1] < max_synthdev)
				synth_devs[q[1]]->hw_control(q[1], q);
			break;

		case SEQ_EXTENDED:
			extended_event(q);
			break;

		case EV_CHN_VOICE:
			seq_chn_voice_event(q);
			break;

		case EV_CHN_COMMON:
			seq_chn_common_event(q);
			break;

		case EV_TIMING:
			if (seq_timing_event(q) == TIMER_ARMED)
			{
				return 1;
			}
			break;

		case EV_SEQ_LOCAL:
			seq_local_event(q);
			break;

		case EV_SYSEX:
			seq_sysex_message(q);
			break;

		default:;
	}
	return 0;
}

/* called also as timer in irq context */
static void seq_startplay(void)
{
	int this_one, action;
	unsigned long flags;

	while (qlen > 0)
	{

		spin_lock_irqsave(&lock,flags);
		qhead = ((this_one = qhead) + 1) % SEQ_MAX_QUEUE;
		qlen--;
		spin_unlock_irqrestore(&lock,flags);

		seq_playing = 1;

		if ((action = play_event(&queue[this_one * EV_SZ])))
		{		/* Suspend playback. Next timer routine invokes this routine again */
			if (action == 2)
			{
				qlen++;
				qhead = this_one;
			}
			return;
		}
	}

	seq_playing = 0;

	if ((SEQ_MAX_QUEUE - qlen) >= output_threshold)
		wake_up(&seq_sleeper);
}

static void reset_controllers(int dev, unsigned char *controller, int update_dev)
{
	int i;
	for (i = 0; i < 128; i++)
		controller[i] = ctrl_def_values[i];
}

static void setup_mode2(void)
{
	int dev;

	max_synthdev = num_synths;

	for (dev = 0; dev < num_midis; dev++)
	{
		if (midi_devs[dev] && midi_devs[dev]->converter != NULL)
		{
			synth_devs[max_synthdev++] = midi_devs[dev]->converter;
		}
	}

	for (dev = 0; dev < max_synthdev; dev++)
	{
		int chn;

		synth_devs[dev]->sysex_ptr = 0;
		synth_devs[dev]->emulation = 0;

		for (chn = 0; chn < 16; chn++)
		{
			synth_devs[dev]->chn_info[chn].pgm_num = 0;
			reset_controllers(dev,
				synth_devs[dev]->chn_info[chn].controllers,0);
			synth_devs[dev]->chn_info[chn].bender_value = (1 << 7);	/* Neutral */
			synth_devs[dev]->chn_info[chn].bender_range = 200;
		}
	}
	max_mididev = 0;
	seq_mode = SEQ_2;
}

int sequencer_open(int dev, struct file *file)
{
	int retval, mode, i;
	int level, tmp;

	if (!sequencer_ok)
		sequencer_init();

	level = ((dev & 0x0f) == SND_DEV_SEQ2) ? 2 : 1;

	dev = dev >> 4;
	mode = translate_mode(file);

	DEB(printk("sequencer_open(dev=%d)\n", dev));

	if (!sequencer_ok)
	{
/*		printk("Sound card: sequencer not initialized\n");*/
		return -ENXIO;
	}
	if (dev)		/* Patch manager device (obsolete) */
		return -ENXIO;

	if(synth_devs[dev] == NULL)
		request_module("synth0");

	if (mode == OPEN_READ)
	{
		if (!num_midis)
		{
			/*printk("Sequencer: No MIDI devices. Input not possible\n");*/
			sequencer_busy = 0;
			return -ENXIO;
		}
	}
	if (sequencer_busy)
	{
		return -EBUSY;
	}
	sequencer_busy = 1;
	obsolete_api_used = 0;

	max_mididev = num_midis;
	max_synthdev = num_synths;
	pre_event_timeout = MAX_SCHEDULE_TIMEOUT;
	seq_mode = SEQ_1;

	if (pending_timer != -1)
	{
		tmr_no = pending_timer;
		pending_timer = -1;
	}
	if (tmr_no == -1)	/* Not selected yet */
	{
		int i, best;

		best = -1;
		for (i = 0; i < num_sound_timers; i++)
			if (sound_timer_devs[i] && sound_timer_devs[i]->priority > best)
			{
				tmr_no = i;
				best = sound_timer_devs[i]->priority;
			}
		if (tmr_no == -1)	/* Should not be */
			tmr_no = 0;
	}
	tmr = sound_timer_devs[tmr_no];

	if (level == 2)
	{
		if (tmr == NULL)
		{
			/*printk("sequencer: No timer for level 2\n");*/
			sequencer_busy = 0;
			return -ENXIO;
		}
		setup_mode2();
	}
	if (!max_synthdev && !max_mididev)
	{
		sequencer_busy=0;
		return -ENXIO;
	}

	synth_open_mask = 0;

	for (i = 0; i < max_mididev; i++)
	{
		midi_opened[i] = 0;
		midi_written[i] = 0;
	}

	for (i = 0; i < max_synthdev; i++)
	{
		if (synth_devs[i]==NULL)
			continue;

		if (!try_module_get(synth_devs[i]->owner))
			continue;

		if ((tmp = synth_devs[i]->open(i, mode)) < 0)
		{
			printk(KERN_WARNING "Sequencer: Warning! Cannot open synth device #%d (%d)\n", i, tmp);
			if (synth_devs[i]->midi_dev)
				printk(KERN_WARNING "(Maps to MIDI dev #%d)\n", synth_devs[i]->midi_dev);
		}
		else
		{
			synth_open_mask |= (1 << i);
			if (synth_devs[i]->midi_dev)
				midi_opened[synth_devs[i]->midi_dev] = 1;
		}
	}

	seq_time = jiffies;

	prev_input_time = 0;
	prev_event_time = 0;

	if (seq_mode == SEQ_1 && (mode == OPEN_READ || mode == OPEN_READWRITE))
	{
		/*
		 * Initialize midi input devices
		 */

		for (i = 0; i < max_mididev; i++)
			if (!midi_opened[i] && midi_devs[i])
			{
				if (!try_module_get(midi_devs[i]->owner))
					continue;
	
				if ((retval = midi_devs[i]->open(i, mode,
					sequencer_midi_input, sequencer_midi_output)) >= 0)
				{
					midi_opened[i] = 1;
				}
			}
	}

	if (seq_mode == SEQ_2) {
		if (try_module_get(tmr->owner))
			tmr->open(tmr_no, seq_mode);
	}

 	init_waitqueue_head(&seq_sleeper);
 	init_waitqueue_head(&midi_sleeper);
	output_threshold = SEQ_MAX_QUEUE / 2;

	return 0;
}

static void seq_drain_midi_queues(void)
{
	int i, n;

	/*
	 * Give the Midi drivers time to drain their output queues
	 */

	n = 1;

	while (!signal_pending(current) && n)
	{
		n = 0;

		for (i = 0; i < max_mididev; i++)
			if (midi_opened[i] && midi_written[i])
				if (midi_devs[i]->buffer_status != NULL)
					if (midi_devs[i]->buffer_status(i))
						n++;

		/*
		 * Let's have a delay
		 */

 		if (n)
 			interruptible_sleep_on_timeout(&seq_sleeper,
						       HZ/10);
	}
}

void sequencer_release(int dev, struct file *file)
{
	int i;
	int mode = translate_mode(file);

	dev = dev >> 4;

	DEB(printk("sequencer_release(dev=%d)\n", dev));

	/*
	 * Wait until the queue is empty (if we don't have nonblock)
	 */

	if (mode != OPEN_READ && !(file->f_flags & O_NONBLOCK))
	{
		while (!signal_pending(current) && qlen > 0)
		{
  			seq_sync();
 			interruptible_sleep_on_timeout(&seq_sleeper,
						       3*HZ);
 			/* Extra delay */
		}
	}

	if (mode != OPEN_READ)
		seq_drain_midi_queues();	/*
						 * Ensure the output queues are empty
						 */
	seq_reset();
	if (mode != OPEN_READ)
		seq_drain_midi_queues();	/*
						 * Flush the all notes off messages
						 */

	for (i = 0; i < max_synthdev; i++)
	{
		if (synth_open_mask & (1 << i))	/*
						 * Actually opened
						 */
			if (synth_devs[i])
			{
				synth_devs[i]->close(i);

				module_put(synth_devs[i]->owner);

				if (synth_devs[i]->midi_dev)
					midi_opened[synth_devs[i]->midi_dev] = 0;
			}
	}

	for (i = 0; i < max_mididev; i++)
	{
		if (midi_opened[i]) {
			midi_devs[i]->close(i);
			module_put(midi_devs[i]->owner);
		}
	}

	if (seq_mode == SEQ_2) {
		tmr->close(tmr_no);
		module_put(tmr->owner);
	}

	if (obsolete_api_used)
		printk(KERN_WARNING "/dev/music: Obsolete (4 byte) API was used by %s\n", current->comm);
	sequencer_busy = 0;
}

static int seq_sync(void)
{
	if (qlen && !seq_playing && !signal_pending(current))
		seq_startplay();

 	if (qlen > 0)
 		interruptible_sleep_on_timeout(&seq_sleeper, HZ);
	return qlen;
}

static void midi_outc(int dev, unsigned char data)
{
	/*
	 * NOTE! Calls sleep(). Don't call this from interrupt.
	 */

	int n;
	unsigned long flags;

	/*
	 * This routine sends one byte to the Midi channel.
	 * If the output FIFO is full, it waits until there
	 * is space in the queue
	 */

	n = 3 * HZ;		/* Timeout */

	spin_lock_irqsave(&lock,flags);
 	while (n && !midi_devs[dev]->outputc(dev, data)) {
 		interruptible_sleep_on_timeout(&seq_sleeper, HZ/25);
  		n--;
  	}
	spin_unlock_irqrestore(&lock,flags);
}

static void seq_reset(void)
{
	/*
	 * NOTE! Calls sleep(). Don't call this from interrupt.
	 */

	int i;
	int chn;
	unsigned long flags;

	sound_stop_timer();

	seq_time = jiffies;
	prev_input_time = 0;
	prev_event_time = 0;

	qlen = qhead = qtail = 0;
	iqlen = iqhead = iqtail = 0;

	for (i = 0; i < max_synthdev; i++)
		if (synth_open_mask & (1 << i))
			if (synth_devs[i])
				synth_devs[i]->reset(i);

	if (seq_mode == SEQ_2)
	{
		for (chn = 0; chn < 16; chn++)
			for (i = 0; i < max_synthdev; i++)
				if (synth_open_mask & (1 << i))
					if (synth_devs[i])
					{
						synth_devs[i]->controller(i, chn, 123, 0);	/* All notes off */
						synth_devs[i]->controller(i, chn, 121, 0);	/* Reset all ctl */
						synth_devs[i]->bender(i, chn, 1 << 13);	/* Bender off */
					}
	}
	else	/* seq_mode == SEQ_1 */
	{
		for (i = 0; i < max_mididev; i++)
			if (midi_written[i])	/*
						 * Midi used. Some notes may still be playing
						 */
			{
				/*
				 *      Sending just a ACTIVE SENSING message should be enough to stop all
				 *      playing notes. Since there are devices not recognizing the
				 *      active sensing, we have to send some all notes off messages also.
				 */
				midi_outc(i, 0xfe);

				for (chn = 0; chn < 16; chn++)
				{
					midi_outc(i, (unsigned char) (0xb0 + (chn & 0x0f)));		/* control change */
					midi_outc(i, 0x7b);	/* All notes off */
					midi_outc(i, 0);	/* Dummy parameter */
				}

				midi_devs[i]->close(i);

				midi_written[i] = 0;
				midi_opened[i] = 0;
			}
	}

	seq_playing = 0;

	spin_lock_irqsave(&lock,flags);

	if (waitqueue_active(&seq_sleeper)) {
		/*      printk( "Sequencer Warning: Unexpected sleeping process - Waking up\n"); */
		wake_up(&seq_sleeper);
	}
	spin_unlock_irqrestore(&lock,flags);
}

static void seq_panic(void)
{
	/*
	 * This routine is called by the application in case the user
	 * wants to reset the system to the default state.
	 */

	seq_reset();

	/*
	 * Since some of the devices don't recognize the active sensing and
	 * all notes off messages, we have to shut all notes manually.
	 *
	 *      TO BE IMPLEMENTED LATER
	 */

	/*
	 * Also return the controllers to their default states
	 */
}

int sequencer_ioctl(int dev, struct file *file, unsigned int cmd, void __user *arg)
{
	int midi_dev, orig_dev, val, err;
	int mode = translate_mode(file);
	struct synth_info inf;
	struct seq_event_rec event_rec;
	unsigned long flags;
	int __user *p = arg;

	orig_dev = dev = dev >> 4;

	switch (cmd)
	{
		case SNDCTL_TMR_TIMEBASE:
		case SNDCTL_TMR_TEMPO:
		case SNDCTL_TMR_START:
		case SNDCTL_TMR_STOP:
		case SNDCTL_TMR_CONTINUE:
		case SNDCTL_TMR_METRONOME:
		case SNDCTL_TMR_SOURCE:
			if (seq_mode != SEQ_2)
				return -EINVAL;
			return tmr->ioctl(tmr_no, cmd, arg);

		case SNDCTL_TMR_SELECT:
			if (seq_mode != SEQ_2)
				return -EINVAL;
			if (get_user(pending_timer, p))
				return -EFAULT;
			if (pending_timer < 0 || pending_timer >= num_sound_timers || sound_timer_devs[pending_timer] == NULL)
			{
				pending_timer = -1;
				return -EINVAL;
			}
			val = pending_timer;
			break;

		case SNDCTL_SEQ_PANIC:
			seq_panic();
			return -EINVAL;

		case SNDCTL_SEQ_SYNC:
			if (mode == OPEN_READ)
				return 0;
			while (qlen > 0 && !signal_pending(current))
				seq_sync();
			return qlen ? -EINTR : 0;

		case SNDCTL_SEQ_RESET:
			seq_reset();
			return 0;

		case SNDCTL_SEQ_TESTMIDI:
			if (__get_user(midi_dev, p))
				return -EFAULT;
			if (midi_dev < 0 || midi_dev >= max_mididev || !midi_devs[midi_dev])
				return -ENXIO;

			if (!midi_opened[midi_dev] &&
				(err = midi_devs[midi_dev]->open(midi_dev, mode, sequencer_midi_input,
						     sequencer_midi_output)) < 0)
				return err;
			midi_opened[midi_dev] = 1;
			return 0;

		case SNDCTL_SEQ_GETINCOUNT:
			if (mode == OPEN_WRITE)
				return 0;
			val = iqlen;
			break;

		case SNDCTL_SEQ_GETOUTCOUNT:
			if (mode == OPEN_READ)
				return 0;
			val = SEQ_MAX_QUEUE - qlen;
			break;

		case SNDCTL_SEQ_GETTIME:
			if (seq_mode == SEQ_2)
				return tmr->ioctl(tmr_no, cmd, arg);
			val = jiffies - seq_time;
			break;

		case SNDCTL_SEQ_CTRLRATE:
			/*
			 * If *arg == 0, just return the current rate
			 */
			if (seq_mode == SEQ_2)
				return tmr->ioctl(tmr_no, cmd, arg);

			if (get_user(val, p))
				return -EFAULT;
			if (val != 0)
				return -EINVAL;
			val = HZ;
			break;

		case SNDCTL_SEQ_RESETSAMPLES:
		case SNDCTL_SYNTH_REMOVESAMPLE:
		case SNDCTL_SYNTH_CONTROL:
			if (get_user(dev, p))
				return -EFAULT;
			if (dev < 0 || dev >= num_synths || synth_devs[dev] == NULL)
				return -ENXIO;
			if (!(synth_open_mask & (1 << dev)) && !orig_dev)
				return -EBUSY;
			return synth_devs[dev]->ioctl(dev, cmd, arg);

		case SNDCTL_SEQ_NRSYNTHS:
			val = max_synthdev;
			break;

		case SNDCTL_SEQ_NRMIDIS:
			val = max_mididev;
			break;

		case SNDCTL_SYNTH_MEMAVL:
			if (get_user(dev, p))
				return -EFAULT;
			if (dev < 0 || dev >= num_synths || synth_devs[dev] == NULL)
				return -ENXIO;
			if (!(synth_open_mask & (1 << dev)) && !orig_dev)
				return -EBUSY;
			val = synth_devs[dev]->ioctl(dev, cmd, arg);
			break;

		case SNDCTL_FM_4OP_ENABLE:
			if (get_user(dev, p))
				return -EFAULT;
			if (dev < 0 || dev >= num_synths || synth_devs[dev] == NULL)
				return -ENXIO;
			if (!(synth_open_mask & (1 << dev)))
				return -ENXIO;
			synth_devs[dev]->ioctl(dev, cmd, arg);
			return 0;

		case SNDCTL_SYNTH_INFO:
			if (get_user(dev, &((struct synth_info __user *)arg)->device))
				return -EFAULT;
			if (dev < 0 || dev >= max_synthdev)
				return -ENXIO;
			if (!(synth_open_mask & (1 << dev)) && !orig_dev)
				return -EBUSY;
			return synth_devs[dev]->ioctl(dev, cmd, arg);

		/* Like SYNTH_INFO but returns ID in the name field */
		case SNDCTL_SYNTH_ID:
			if (get_user(dev, &((struct synth_info __user *)arg)->device))
				return -EFAULT;
			if (dev < 0 || dev >= max_synthdev)
				return -ENXIO;
			if (!(synth_open_mask & (1 << dev)) && !orig_dev)
				return -EBUSY;
			memcpy(&inf, synth_devs[dev]->info, sizeof(inf));
			strlcpy(inf.name, synth_devs[dev]->id, sizeof(inf.name));
			inf.device = dev;
			return copy_to_user(arg, &inf, sizeof(inf))?-EFAULT:0;

		case SNDCTL_SEQ_OUTOFBAND:
			if (copy_from_user(&event_rec, arg, sizeof(event_rec)))
				return -EFAULT;
			spin_lock_irqsave(&lock,flags);
			play_event(event_rec.arr);
			spin_unlock_irqrestore(&lock,flags);
			return 0;

		case SNDCTL_MIDI_INFO:
			if (get_user(dev, &((struct midi_info __user *)arg)->device))
				return -EFAULT;
			if (dev < 0 || dev >= max_mididev || !midi_devs[dev])
				return -ENXIO;
			midi_devs[dev]->info.device = dev;
			return copy_to_user(arg, &midi_devs[dev]->info, sizeof(struct midi_info))?-EFAULT:0;

		case SNDCTL_SEQ_THRESHOLD:
			if (get_user(val, p))
				return -EFAULT;
			if (val < 1)
				val = 1;
			if (val >= SEQ_MAX_QUEUE)
				val = SEQ_MAX_QUEUE - 1;
			output_threshold = val;
			return 0;

		case SNDCTL_MIDI_PRETIME:
			if (get_user(val, p))
				return -EFAULT;
			if (val < 0)
				val = 0;
			val = (HZ * val) / 10;
			pre_event_timeout = val;
			break;

		default:
			if (mode == OPEN_READ)
				return -EIO;
			if (!synth_devs[0])
				return -ENXIO;
			if (!(synth_open_mask & (1 << 0)))
				return -ENXIO;
			if (!synth_devs[0]->ioctl)
				return -EINVAL;
			return synth_devs[0]->ioctl(0, cmd, arg);
	}
	return put_user(val, p);
}

/* No kernel lock - we're using the global irq lock here */
unsigned int sequencer_poll(int dev, struct file *file, poll_table * wait)
{
	unsigned long flags;
	unsigned int mask = 0;

	dev = dev >> 4;

	spin_lock_irqsave(&lock,flags);
	/* input */
	poll_wait(file, &midi_sleeper, wait);
	if (iqlen)
		mask |= POLLIN | POLLRDNORM;

	/* output */
	poll_wait(file, &seq_sleeper, wait);
	if ((SEQ_MAX_QUEUE - qlen) >= output_threshold)
		mask |= POLLOUT | POLLWRNORM;
	spin_unlock_irqrestore(&lock,flags);
	return mask;
}


void sequencer_timer(unsigned long dummy)
{
	seq_startplay();
}

int note_to_freq(int note_num)
{

	/*
	 * This routine converts a midi note to a frequency (multiplied by 1000)
	 */

	int note, octave, note_freq;
	static int notes[] =
	{
		261632, 277189, 293671, 311132, 329632, 349232,
		369998, 391998, 415306, 440000, 466162, 493880
	};

#define BASE_OCTAVE	5

	octave = note_num / 12;
	note = note_num % 12;

	note_freq = notes[note];

	if (octave < BASE_OCTAVE)
		note_freq >>= (BASE_OCTAVE - octave);
	else if (octave > BASE_OCTAVE)
		note_freq <<= (octave - BASE_OCTAVE);

	/*
	 * note_freq >>= 1;
	 */

	return note_freq;
}

unsigned long compute_finetune(unsigned long base_freq, int bend, int range,
		 int vibrato_cents)
{
	unsigned long amount;
	int negative, semitones, cents, multiplier = 1;

	if (!bend)
		return base_freq;
	if (!range)
		return base_freq;

	if (!base_freq)
		return base_freq;

	if (range >= 8192)
		range = 8192;

	bend = bend * range / 8192;	/* Convert to cents */
	bend += vibrato_cents;

	if (!bend)
		return base_freq;

	negative = bend < 0 ? 1 : 0;

	if (bend < 0)
		bend *= -1;
	if (bend > range)
		bend = range;

	/*
	   if (bend > 2399)
	   bend = 2399;
	 */
	while (bend > 2399)
	{
		multiplier *= 4;
		bend -= 2400;
	}

	semitones = bend / 100;
	if (semitones > 99)
		semitones = 99;
	cents = bend % 100;

	amount = (int) (semitone_tuning[semitones] * multiplier * cent_tuning[cents]) / 10000;

	if (negative)
		return (base_freq * 10000) / amount;	/* Bend down */
	else
		return (base_freq * amount) / 10000;	/* Bend up */
}


void sequencer_init(void)
{
	/* drag in sequencer_syms.o */
	{
		extern char sequencer_syms_symbol;
		sequencer_syms_symbol = 0;
	}

	if (sequencer_ok)
		return;
	MIDIbuf_init();
	queue = (unsigned char *)vmalloc(SEQ_MAX_QUEUE * EV_SZ);
	if (queue == NULL)
	{
		printk(KERN_ERR "sequencer: Can't allocate memory for sequencer output queue\n");
		return;
	}
	iqueue = (unsigned char *)vmalloc(SEQ_MAX_QUEUE * IEV_SZ);
	if (iqueue == NULL)
	{
		printk(KERN_ERR "sequencer: Can't allocate memory for sequencer input queue\n");
		vfree(queue);
		return;
	}
	sequencer_ok = 1;
}

void sequencer_unload(void)
{
	if(queue)
	{
		vfree(queue);
		queue=NULL;
	}
	if(iqueue)
	{
		vfree(iqueue);
		iqueue=NULL;
	}
}
