patch-2.1.28 linux/drivers/sound/sequencer.c
Next file: linux/drivers/sound/sound_calls.h
Previous file: linux/drivers/sound/sb_mixer.h
Back to the patch index
Back to the overall index
- Lines: 580
- Date:
Wed Feb 26 02:35:31 1997
- Orig file:
v2.1.27/linux/drivers/sound/sequencer.c
- Orig date:
Tue Jan 28 00:02:45 1997
diff -u --recursive --new-file v2.1.27/linux/drivers/sound/sequencer.c linux/drivers/sound/sequencer.c
@@ -4,14 +4,13 @@
* The sequencer personality manager.
*/
/*
- * Copyright (C) by Hannu Savolainen 1993-1996
+ * 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.
*/
#include <linux/config.h>
-#include <linux/poll.h>
#define SEQUENCER_C
@@ -200,6 +199,7 @@
return;
tstamp = jiffies - seq_time;
+
if (tstamp != prev_input_time)
{
tstamp = (tstamp << 8) | SEQ_WAIT;
@@ -267,7 +267,7 @@
if (ev_code == SEQ_FULLSIZE)
{
- int err;
+ int err, fmt;
dev = *(unsigned short *) &event_rec[2];
if (dev < 0 || dev >= max_synthdev)
@@ -276,7 +276,8 @@
if (!(synth_open_mask & (1 << dev)))
return -ENXIO;
- err = synth_devs[dev]->load_patch (dev, *(short *) &event_rec[0], buf, p + 4, c, 0);
+ fmt = (*(short *) &event_rec[0]) & 0xffff;
+ err = synth_devs[dev]->load_patch (dev, fmt, buf, p + 4, c, 0);
if (err < 0)
return err;
@@ -364,9 +365,7 @@
if (!seq_playing)
seq_startplay ();
- return count; /* This will "eat" chunks shorter than 4 bytes (if written
- * alone) Should we really do that ?
- */
+ return count;
}
static int
@@ -429,6 +428,11 @@
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;
@@ -545,13 +549,7 @@
{
synth_devs[dev]->set_instr (dev, voice, 128 + note);
synth_devs[dev]->chn_info[chn].pgm_num = 128 + note;
- note = 60; /* Middle C */
-
}
- }
-
- if (seq_mode == SEQ_2)
- {
synth_devs[dev]->setup_voice (dev, voice, chn);
}
@@ -574,6 +572,7 @@
}
}
+
static void
seq_chn_common_event (unsigned char *event_rec)
{
@@ -806,13 +805,13 @@
return;
if (!synth_devs[dev])
return;
- if (!synth_devs[dev]->send_sysex)
- 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);
}
@@ -890,7 +889,7 @@
break;
case SEQ_SYNCTIMER: /*
- * Reset timer
+ * Reset timer
*/
seq_time = jiffies;
prev_input_time = 0;
@@ -1044,6 +1043,9 @@
{
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;
@@ -1051,6 +1053,7 @@
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;
}
}
@@ -1065,6 +1068,9 @@
int level, tmp;
unsigned long flags;
+ if (!sequencer_ok)
+ sequencer_init ();
+
level = ((dev & 0x0f) == SND_DEV_SEQ2) ? 2 : 1;
dev = dev >> 4;
@@ -1083,6 +1089,14 @@
return -ENXIO;
}
+ if (mode == OPEN_READ)
+ if (!num_midis)
+ {
+ printk ("Sequencer: No MIDI devices. Input not possible\n");
+ sequencer_busy = 0;
+ return -ENXIO;
+ }
+
save_flags (flags);
cli ();
if (sequencer_busy)
@@ -1133,14 +1147,6 @@
setup_mode2 ();
}
- if (seq_mode == SEQ_1 && mode == OPEN_READ)
- if (!max_mididev)
- {
- printk ("Sequencer: No Midi devices. Input not possible\n");
- sequencer_busy = 0;
- return -ENXIO;
- }
-
if (!max_synthdev && !max_mididev)
return -ENXIO;
@@ -1152,28 +1158,24 @@
midi_written[i] = 0;
}
- /*
- * if (mode == OPEN_WRITE || mode == OPEN_READWRITE)
- */
- for (i = 0; i < max_synthdev; i++) /*
- * Open synth devices
- */
- if ((tmp = synth_devs[i]->open (i, mode)) < 0)
- {
- printk ("Sequencer: Warning! Cannot open synth device #%d (%d)\n", i, tmp);
- if (synth_devs[i]->midi_dev)
- printk ("(Maps to MIDI dev #%d)\n", synth_devs[i]->midi_dev);
- }
- else
- {
- synth_open_mask |= (1 << i);
- if (synth_devs[i]->midi_dev) /*
- * Is a midi interface
- */
- midi_opened[synth_devs[i]->midi_dev] = 1;
- }
+ for (i = 0; i < max_synthdev; i++)
+ {
+ if ((tmp = synth_devs[i]->open (i, mode)) < 0)
+ {
+ printk ("Sequencer: Warning! Cannot open synth device #%d (%d)\n", i, tmp);
+ if (synth_devs[i]->midi_dev)
+ printk ("(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;
@@ -1260,7 +1262,7 @@
DEB (printk ("sequencer_release(dev=%d)\n", dev));
/*
- * * Wait until the queue is empty (if we don't have nonblock)
+ * Wait until the queue is empty (if we don't have nonblock)
*/
if (mode != OPEN_READ && !(file->flags & (O_NONBLOCK) ?
@@ -1268,6 +1270,23 @@
while (!(current->signal & ~current->blocked) && qlen > 0)
{
seq_sync ();
+
+ {
+ unsigned long tlimit;
+
+ if (3 * HZ)
+ current->timeout = tlimit = jiffies + (3 * HZ);
+ else
+ tlimit = (unsigned long) -1;
+ seq_sleep_flag.opts = WK_SLEEP;
+ interruptible_sleep_on (&seq_sleeper);
+ if (!(seq_sleep_flag.opts & WK_WAKEUP))
+ {
+ if (jiffies >= tlimit)
+ seq_sleep_flag.opts |= WK_TIMEOUT;
+ }
+ seq_sleep_flag.opts &= ~WK_SLEEP;
+ }; /* Extra delay */
}
if (mode != OPEN_READ)
@@ -1397,6 +1416,7 @@
unsigned long flags;
sound_stop_timer ();
+
seq_time = jiffies;
prev_input_time = 0;
prev_event_time = 0;
@@ -1519,7 +1539,7 @@
if (seq_mode != SEQ_2)
return -EINVAL;
- get_user (pending_timer, (int *) arg);
+ pending_timer = *(int *) arg;
if (pending_timer < 0 || pending_timer >= num_sound_timers)
{
@@ -1527,7 +1547,7 @@
return -EINVAL;
}
- return ioctl_out (arg, pending_timer);
+ return (*(int *) arg = pending_timer);
break;
case SNDCTL_SEQ_PANIC:
@@ -1553,7 +1573,7 @@
break;
case SNDCTL_SEQ_TESTMIDI:
- get_user (midi_dev, (int *) arg);
+ midi_dev = *(int *) arg;
if (midi_dev < 0 || midi_dev >= max_mididev)
return -ENXIO;
@@ -1576,21 +1596,21 @@
case SNDCTL_SEQ_GETINCOUNT:
if (mode == OPEN_WRITE)
return 0;
- return ioctl_out (arg, iqlen);
+ return (*(int *) arg = iqlen);
break;
case SNDCTL_SEQ_GETOUTCOUNT:
if (mode == OPEN_READ)
return 0;
- return ioctl_out (arg, SEQ_MAX_QUEUE - qlen);
+ return (*(int *) arg = SEQ_MAX_QUEUE - qlen);
break;
case SNDCTL_SEQ_GETTIME:
if (seq_mode == SEQ_2)
return tmr->ioctl (tmr_no, cmd, arg);
- return ioctl_out (arg, jiffies - seq_time);
+ return (*(int *) arg = jiffies - seq_time);
break;
case SNDCTL_SEQ_CTRLRATE:
@@ -1600,18 +1620,18 @@
if (seq_mode == SEQ_2)
return tmr->ioctl (tmr_no, cmd, arg);
- get_user (val, (int *) arg);
+ val = *(int *) arg;
if (val != 0)
return -EINVAL;
- return ioctl_out (arg, HZ);
+ return (*(int *) arg = HZ);
break;
case SNDCTL_SEQ_RESETSAMPLES:
{
int err;
- get_user (dev, (int *) arg);
+ dev = *(int *) arg;
if (dev < 0 || dev >= num_synths)
{
return -ENXIO;
@@ -1628,18 +1648,18 @@
break;
case SNDCTL_SEQ_NRSYNTHS:
- return ioctl_out (arg, max_synthdev);
+ return (*(int *) arg = max_synthdev);
break;
case SNDCTL_SEQ_NRMIDIS:
- return ioctl_out (arg, max_mididev);
+ return (*(int *) arg = max_mididev);
break;
case SNDCTL_SYNTH_MEMAVL:
{
int dev;
- get_user (dev, (int *) arg);
+ dev = *(int *) arg;
if (dev < 0 || dev >= num_synths)
return -ENXIO;
@@ -1647,7 +1667,7 @@
if (!(synth_open_mask & (1 << dev)) && !orig_dev)
return -EBUSY;
- return ioctl_out (arg, synth_devs[dev]->ioctl (dev, cmd, arg));
+ return (*(int *) arg = synth_devs[dev]->ioctl (dev, cmd, arg));
}
break;
@@ -1655,7 +1675,7 @@
{
int dev;
- get_user (dev, (int *) arg);
+ dev = *(int *) arg;
if (dev < 0 || dev >= num_synths)
return -ENXIO;
@@ -1673,7 +1693,7 @@
struct synth_info inf;
int dev;
- copy_from_user ((char *) &inf, &((char *) arg)[0], sizeof (inf));
+ memcpy ((char *) &inf, (&((char *) arg)[0]), sizeof (inf));
dev = inf.device;
if (dev < 0 || dev >= max_synthdev)
@@ -1686,12 +1706,35 @@
}
break;
+
+ /* Like SYNTH_INFO but returns ID in the name field */
+ case SNDCTL_SYNTH_ID:
+ {
+ struct synth_info inf;
+ int dev;
+
+ memcpy ((char *) &inf, (&((char *) arg)[0]), sizeof (inf));
+ dev = inf.device;
+
+ if (dev < 0 || dev >= max_synthdev)
+ return -ENXIO;
+
+ if (!(synth_open_mask & (1 << dev)) && !orig_dev)
+ return -EBUSY;
+
+ memcpy ((char *) &inf, (char *) synth_devs[dev]->info, sizeof (inf));
+ strcpy (inf.name, synth_devs[dev]->id);
+ memcpy ((&((char *) arg)[0]), (char *) &inf, sizeof (inf));
+ return 0;
+ }
+ break;
+
case SNDCTL_SEQ_OUTOFBAND:
{
struct seq_event_rec event_rec;
unsigned long flags;
- copy_from_user ((char *) &event_rec, &((char *) arg)[0], sizeof (event_rec));
+ memcpy ((char *) &event_rec, (&((char *) arg)[0]), sizeof (event_rec));
save_flags (flags);
cli ();
@@ -1708,18 +1751,14 @@
int dev;
char *pp;
- copy_from_user ((char *) &inf, &((char *) arg)[0], sizeof (inf));
+ memcpy ((char *) &inf, (&((char *) arg)[0]), sizeof (inf));
dev = inf.device;
if (dev < 0 || dev >= max_mididev)
return -ENXIO;
pp = (char *) &midi_devs[dev]->info;
- {
- char *fixit = pp;
-
- copy_to_user (&((char *) arg)[0], fixit, sizeof (inf));
- };
+ memcpy ((&((char *) arg)[0]), pp, sizeof (inf));
return 0;
}
break;
@@ -1728,7 +1767,7 @@
{
int tmp;
- get_user (tmp, (int *) arg);
+ tmp = *(int *) arg;
if (tmp < 1)
tmp = 1;
@@ -1743,14 +1782,14 @@
{
int val;
- get_user (val, (int *) arg);
+ val = *(int *) arg;
if (val < 0)
val = 0;
val = (HZ * val) / 10;
pre_event_timeout = val;
- return ioctl_out (arg, val);
+ return (*(int *) arg = val);
}
break;
@@ -1769,28 +1808,50 @@
return -EINVAL;
}
-unsigned int
-sequencer_poll (kdev_t dev, struct fileinfo *file, poll_table * wait)
+int
+sequencer_select (int dev, struct fileinfo *file, int sel_type, poll_table * wait)
{
- unsigned int mask = 0;
unsigned long flags;
- save_flags (flags);
- cli ();
+ dev = dev >> 4;
- midi_sleep_flag.opts = WK_SLEEP;
- poll_wait (&midi_sleeper, wait);
- seq_sleep_flag.opts = WK_SLEEP;
- poll_wait (&seq_sleeper, wait);
+ switch (sel_type)
+ {
+ case SEL_IN:
+ save_flags (flags);
+ cli ();
+ if (!iqlen)
+ {
- restore_flags (flags);
+ midi_sleep_flag.opts = WK_SLEEP;
+ poll_wait (&midi_sleeper, wait);
+ restore_flags (flags);
+ return 0;
+ }
+ restore_flags (flags);
+ return 1;
+ break;
- if (iqlen)
- mask |= POLLIN | POLLRDNORM;
- if ((SEQ_MAX_QUEUE - qlen) >= output_threshold)
- mask |= POLLOUT | POLLWRNORM;
+ case SEL_OUT:
+ save_flags (flags);
+ cli ();
+ if ((SEQ_MAX_QUEUE - qlen) < output_threshold)
+ {
- return mask;
+ seq_sleep_flag.opts = WK_SLEEP;
+ poll_wait (&seq_sleeper, wait);
+ restore_flags (flags);
+ return 0;
+ }
+ restore_flags (flags);
+ return 1;
+ break;
+
+ case SEL_EX:
+ return 0;
+ }
+
+ return 0;
}
@@ -1835,7 +1896,8 @@
}
unsigned long
-compute_finetune (unsigned long base_freq, int bend, int range)
+compute_finetune (unsigned long base_freq, int bend, int range,
+ int vibrato_cents)
{
unsigned long amount;
int negative, semitones, cents, multiplier = 1;
@@ -1851,7 +1913,9 @@
if (range >= 8192)
range = 8192;
- bend = bend * range / 8192;
+ bend = bend * range / 8192; /* Convert to cents */
+ bend += vibrato_cents;
+
if (!bend)
return base_freq;
@@ -1888,9 +1952,12 @@
void
sequencer_init (void)
{
+ if (sequencer_ok)
+ return;
queue = (unsigned char *) (sound_mem_blocks[sound_nblocks] = vmalloc (SEQ_MAX_QUEUE * EV_SZ));
+ sound_mem_sizes[sound_nblocks] = SEQ_MAX_QUEUE * EV_SZ;
if (sound_nblocks < 1024)
sound_nblocks++;;
if (queue == NULL)
@@ -1901,6 +1968,7 @@
iqueue = (unsigned char *) (sound_mem_blocks[sound_nblocks] = vmalloc (SEQ_MAX_QUEUE * IEV_SZ));
+ sound_mem_sizes[sound_nblocks] = SEQ_MAX_QUEUE * IEV_SZ;
if (sound_nblocks < 1024)
sound_nblocks++;;
if (queue == NULL)
@@ -1908,6 +1976,7 @@
printk ("Sound: Can't allocate memory for sequencer input queue\n");
return;
}
+
sequencer_ok = 1;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov