📄 wavefront_midi.c
字号:
if ((midi = get_wavefront_midi (substream)) == NULL) return -EIO; spin_lock_irqsave (&midi->open, flags); midi->mode[mpu] &= ~MPU401_MODE_INPUT; spin_unlock_irqrestore (&midi->open, flags); return 0;}static int snd_wavefront_midi_output_close(snd_rawmidi_substream_t * substream){ unsigned long flags; snd_wavefront_midi_t *midi; snd_wavefront_mpu_id mpu; snd_assert(substream != NULL && substream->rmidi != NULL, return -EIO); snd_assert(substream->rmidi->private_data != NULL, return -EIO); mpu = *((snd_wavefront_mpu_id *) substream->rmidi->private_data); if ((midi = get_wavefront_midi (substream)) == NULL) return -EIO; spin_lock_irqsave (&midi->open, flags); midi->mode[mpu] &= ~MPU401_MODE_OUTPUT; spin_unlock_irqrestore (&midi->open, flags); return 0;}static void snd_wavefront_midi_input_trigger(snd_rawmidi_substream_t * substream, int up){ unsigned long flags; snd_wavefront_midi_t *midi; snd_wavefront_mpu_id mpu; if (substream == NULL || substream->rmidi == NULL) return; if (substream->rmidi->private_data == NULL) return; mpu = *((snd_wavefront_mpu_id *) substream->rmidi->private_data); if ((midi = get_wavefront_midi (substream)) == NULL) { return; } spin_lock_irqsave (&midi->virtual, flags); if (up) { midi->mode[mpu] |= MPU401_MODE_INPUT_TRIGGER; } else { midi->mode[mpu] &= ~MPU401_MODE_INPUT_TRIGGER; } spin_unlock_irqrestore (&midi->virtual, flags);}static void snd_wavefront_midi_output_timer(unsigned long data){ snd_wavefront_card_t *card = (snd_wavefront_card_t *)data; snd_wavefront_midi_t *midi = &card->wavefront.midi; unsigned long flags; spin_lock_irqsave (&midi->virtual, flags); midi->timer.expires = 1 + jiffies; add_timer(&midi->timer); spin_unlock_irqrestore (&midi->virtual, flags); snd_wavefront_midi_output_write(card);}static void snd_wavefront_midi_output_trigger(snd_rawmidi_substream_t * substream, int up){ unsigned long flags; snd_wavefront_midi_t *midi; snd_wavefront_mpu_id mpu; if (substream == NULL || substream->rmidi == NULL) return; if (substream->rmidi->private_data == NULL) return; mpu = *((snd_wavefront_mpu_id *) substream->rmidi->private_data); if ((midi = get_wavefront_midi (substream)) == NULL) { return; } spin_lock_irqsave (&midi->virtual, flags); if (up) { if ((midi->mode[mpu] & MPU401_MODE_OUTPUT_TRIGGER) == 0) { if (!midi->istimer) { init_timer(&midi->timer); midi->timer.function = snd_wavefront_midi_output_timer; midi->timer.data = (unsigned long) substream->rmidi->card->private_data; midi->timer.expires = 1 + jiffies; add_timer(&midi->timer); } midi->istimer++; midi->mode[mpu] |= MPU401_MODE_OUTPUT_TRIGGER; } } else { midi->mode[mpu] &= ~MPU401_MODE_OUTPUT_TRIGGER; } spin_unlock_irqrestore (&midi->virtual, flags); if (up) snd_wavefront_midi_output_write((snd_wavefront_card_t *)substream->rmidi->card->private_data);}voidsnd_wavefront_midi_interrupt (snd_wavefront_card_t *card){ unsigned long flags; snd_wavefront_midi_t *midi; static snd_rawmidi_substream_t *substream = NULL; static int mpu = external_mpu; int max = 128; unsigned char byte; midi = &card->wavefront.midi; if (!input_avail (midi)) { /* not for us */ snd_wavefront_midi_output_write(card); return; } spin_lock_irqsave (&midi->virtual, flags); while (--max) { if (input_avail (midi)) { byte = read_data (midi); if (midi->isvirtual) { if (byte == WF_EXTERNAL_SWITCH) { substream = midi->substream_input[external_mpu]; mpu = external_mpu; } else if (byte == WF_INTERNAL_SWITCH) { substream = midi->substream_output[internal_mpu]; mpu = internal_mpu; } /* else just leave it as it is */ } else { substream = midi->substream_input[internal_mpu]; mpu = internal_mpu; } if (substream == NULL) { continue; } if (midi->mode[mpu] & MPU401_MODE_INPUT_TRIGGER) { snd_rawmidi_receive(substream, &byte, 1); } } else { break; } } spin_unlock_irqrestore (&midi->virtual, flags); snd_wavefront_midi_output_write(card);}voidsnd_wavefront_midi_enable_virtual (snd_wavefront_card_t *card){ unsigned long flags; spin_lock_irqsave (&card->wavefront.midi.virtual, flags); card->wavefront.midi.isvirtual = 1; card->wavefront.midi.output_mpu = internal_mpu; card->wavefront.midi.input_mpu = internal_mpu; spin_unlock_irqrestore (&card->wavefront.midi.virtual, flags);}voidsnd_wavefront_midi_disable_virtual (snd_wavefront_card_t *card){ unsigned long flags; spin_lock_irqsave (&card->wavefront.midi.virtual, flags); // snd_wavefront_midi_input_close (card->ics2115_external_rmidi); // snd_wavefront_midi_output_close (card->ics2115_external_rmidi); card->wavefront.midi.isvirtual = 0; spin_unlock_irqrestore (&card->wavefront.midi.virtual, flags);}int __initsnd_wavefront_midi_start (snd_wavefront_card_t *card){ int ok, i; unsigned char rbuf[4], wbuf[4]; snd_wavefront_t *dev; snd_wavefront_midi_t *midi; dev = &card->wavefront; midi = &dev->midi; /* The ICS2115 MPU-401 interface doesn't do anything until its set into UART mode. */ /* XXX fix me - no hard timing loops allowed! */ for (i = 0; i < 30000 && !output_ready (midi); i++); if (!output_ready (midi)) { snd_printk ("MIDI interface not ready for command\n"); return -1; } /* Any interrupts received from now on are owned by the MIDI side of things. */ dev->interrupts_are_midi = 1; outb (UART_MODE_ON, midi->mpu_command_port); for (ok = 0, i = 50000; i > 0 && !ok; i--) { if (input_avail (midi)) { if (read_data (midi) == MPU_ACK) { ok = 1; break; } } } if (!ok) { snd_printk ("cannot set UART mode for MIDI interface"); dev->interrupts_are_midi = 0; return -1; } /* Route external MIDI to WaveFront synth (by default) */ if (snd_wavefront_cmd (dev, WFC_MISYNTH_ON, rbuf, wbuf)) { snd_printk ("can't enable MIDI-IN-2-synth routing.\n"); /* XXX error ? */ } /* Turn on Virtual MIDI, but first *always* turn it off, since otherwise consectutive reloads of the driver will never cause the hardware to generate the initial "internal" or "external" source bytes in the MIDI data stream. This is pretty important, since the internal hardware generally will be used to generate none or very little MIDI output, and thus the only source of MIDI data is actually external. Without the switch bytes, the driver will think it all comes from the internal interface. Duh. */ if (snd_wavefront_cmd (dev, WFC_VMIDI_OFF, rbuf, wbuf)) { snd_printk ("virtual MIDI mode not disabled\n"); return 0; /* We're OK, but missing the external MIDI dev */ } snd_wavefront_midi_enable_virtual (card); if (snd_wavefront_cmd (dev, WFC_VMIDI_ON, rbuf, wbuf)) { snd_printk ("cannot enable virtual MIDI mode.\n"); snd_wavefront_midi_disable_virtual (card); } return 0;}snd_rawmidi_ops_t snd_wavefront_midi_output ={ .open = snd_wavefront_midi_output_open, .close = snd_wavefront_midi_output_close, .trigger = snd_wavefront_midi_output_trigger,};snd_rawmidi_ops_t snd_wavefront_midi_input ={ .open = snd_wavefront_midi_input_open, .close = snd_wavefront_midi_input_close, .trigger = snd_wavefront_midi_input_trigger,};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -