📄 midi_alsaseq.c
字号:
/*================================================================== * midi_alsaseq.c - ALSA sequencer MIDI thru driver * currently just a subscription between two ALSA client:ports * * Smurf Sound Font Editor * Copyright (C) 1999-2001 Josh Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. * * To contact the author of this program: * Email: Josh Green <jgreen@users.sourceforge.net> * Smurf homepage: http://smurf.sourceforge.net *==================================================================*/#include "config.h"#ifdef ALSA_SUPPORT#include <stdio.h>#include <unistd.h>#include <stdlib.h>#include <fcntl.h>#include <errno.h>#include <string.h>#include <glib.h>#include "midi.h"#include "alsa.h"#include "seq_alsa.h"#include "smurfcfg.h"#include "util.h"#include "i18n.h"#include <sys/asoundlib.h>gboolean midi_alsaseq_active = FALSE;static gint midi_alsa_inclient = 0;static gint midi_alsa_inport = 0;static gint midi_alsa_outclient = 0;static gint midi_alsa_outport = 0;/* get the configuration file values for MIDI thru clients/ports */voidmidi_alsaseq_load_config (void){ if (strcmp (smurfcfg_get_val (SMURFCFG_MIDI_DRIVER)->v_string, "AUTO") != 0) { midi_alsa_inclient = smurfcfg_get_val (SMURFCFG_MIDI_ALSA_INCLIENT)->v_int; midi_alsa_inport = smurfcfg_get_val (SMURFCFG_MIDI_ALSA_INPORT)->v_int; midi_alsa_outclient = smurfcfg_get_val (SMURFCFG_MIDI_ALSA_OUTCLIENT)->v_int; midi_alsa_outport = smurfcfg_get_val (SMURFCFG_MIDI_ALSA_OUTPORT)->v_int; } else { /* force "AUTO" detection */ midi_alsa_inclient = 0; midi_alsa_outclient = 0; } /* if virtual keyboard is active and MIDI thru out client auto detect, then use virtual keyboard client:port */ if (seq_alsa_vkeyb_active && midi_alsa_outclient == 0) { midi_alsa_outclient = seq_alsa_vkeyb_conn_client; midi_alsa_outport = seq_alsa_vkeyb_conn_port; }}/* init for ALSA connect driver */gintmidi_alsaseq_init (void){ snd_seq_port_subscribe_t *subs; snd_seq_addr_t sender, dest; gint i; gchar *inclient_substrs[] = { "External MIDI", /* Find client with "External MIDI" in name */ "MIDI", /* Find client with "MIDI" in name */ }; gchar *outclient_substrs[] = { "WaveTable", /* Find client with "WaveTable" in name */ }; if (!seq_alsa_init ()) return (FAIL); if (midi_alsa_inclient != 0 && midi_alsa_inclient == midi_alsa_outclient && midi_alsa_inport == midi_alsa_outport) midi_alsa_inclient = 0; /* Do an auto search if in/out is the same */ i = 0; /* if inclient == 0 then search for MIDI input port */ while (midi_alsa_inclient == 0 && i < sizeof(inclient_substrs) / sizeof(inclient_substrs[0])) { seq_alsa_find_port (inclient_substrs[i], SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ, SND_SEQ_PORT_TYPE_MIDI_GENERIC, &midi_alsa_inclient, &midi_alsa_inport); /* if it found the same port selected for output, then skip */ if (midi_alsa_inclient != 0 && midi_alsa_outclient == midi_alsa_inclient && midi_alsa_outport == midi_alsa_inport) midi_alsa_inclient = 0; i++; } i = 0; /* if outclient == 0 then search for MIDI output port */ while (midi_alsa_outclient == 0 && i < sizeof(outclient_substrs) / sizeof(outclient_substrs[0])) { seq_alsa_find_port (outclient_substrs[i], SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE, SND_SEQ_PORT_TYPE_MIDI_GENERIC, &midi_alsa_outclient, &midi_alsa_outport); /* if it found the same port selected for input, then skip */ if (midi_alsa_outclient != 0 && midi_alsa_outclient == midi_alsa_inclient && midi_alsa_outport == midi_alsa_inport) midi_alsa_outclient = 0; i++; } if (midi_alsa_inclient == 0) { seq_alsa_close (); return (logit (LogWarn, _("Failed to guess ALSA input MIDI thru" " client:port"))); } if (midi_alsa_outclient == 0) { seq_alsa_close (); return (logit (LogWarn, _("Failed to guess ALSA output MIDI thru" " client:port"))); } /* source ALSA client/port for MIDI thru subscription */ sender.client = midi_alsa_inclient; sender.port = midi_alsa_inport; /* destination client/port */ dest.client = midi_alsa_outclient; dest.port = midi_alsa_outport; log_message (_("Subscribing %d:%d to %d:%d for ALSA MIDI thru"), midi_alsa_inclient, midi_alsa_inport, midi_alsa_outclient, midi_alsa_outport); /* check if these ALSA clients:ports are already connected */ if (seq_alsa_is_subscribed (&sender, &dest)) { seq_alsa_close (); logit (LogWarn, _("ALSA MIDI thru ports are already connected")); return (OK); } /* set up the port subscription structure for MIDI thru */#ifdef NEW_ALSA_SEQ snd_seq_port_subscribe_alloca (&subs); snd_seq_port_subscribe_set_sender (subs, &sender); snd_seq_port_subscribe_set_dest (subs, &dest);#else /* old 0.5.x or < 0.9.0beta6 ALSA */ subs = calloc (1, sizeof (subs)); subs->sender = sender; subs->dest = dest;#endif /* subscribe the ports for MIDI thru */ if (snd_seq_subscribe_port (seq_alsa_handle, subs) < 0) {#ifndef NEW_ALSA_SEQ free (subs);#endif seq_alsa_close (); return (logit (LogWarn, _("ALSA MIDI thru connect failed: %s"), snd_strerror(errno))); }#ifndef NEW_ALSA_SEQ free (subs);#endif midi_alsaseq_active = TRUE; return (OK);}voidmidi_alsaseq_close (void){ snd_seq_port_subscribe_t *subs; snd_seq_addr_t sender, dest; if (!midi_alsaseq_active) return; /* source ALSA client/port for MIDI thru subscription */ sender.client = midi_alsa_inclient; sender.port = midi_alsa_inport; /* destination client/port */ dest.client = midi_alsa_outclient; dest.port = midi_alsa_outport; /* set up the port subscription structure for MIDI thru */#ifdef NEW_ALSA_SEQ snd_seq_port_subscribe_alloca (&subs); snd_seq_port_subscribe_set_sender (subs, &sender); snd_seq_port_subscribe_set_dest (subs, &dest);#else subs = calloc (1, sizeof (subs)); subs->sender = sender; subs->dest = dest;#endif if (snd_seq_unsubscribe_port (seq_alsa_handle, subs) < 0) logit (LogWarn, _("Failed to unsubscribe ALSA MIDI thru ports"));#ifndef NEW_ALSA_SEQ free (subs);#endif seq_alsa_close (); midi_alsaseq_active = FALSE;}#endif /* #ifdef ALSA_SUPPORT */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -