summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim E. Real <termtech@rogers.com>2012-11-13 08:36:20 +0000
committerTim E. Real <termtech@rogers.com>2012-11-13 08:36:20 +0000
commita247e60904516800a3874688e368979b9b1e7bf8 (patch)
tree0df00fdfbc69e919234a4ad65369c4787c934d9c
parent33250e6a085d51efab1b061e13bd635c804209d0 (diff)
Added aftertouch controller to fluidsynth, and aftertouch/poly-aftertouch to DSSI.
-rw-r--r--muse2/ChangeLog1
-rw-r--r--muse2/muse/dssihost.cpp62
-rw-r--r--muse2/muse/midiport.cpp4
-rw-r--r--muse2/synti/fluidsynth/fluidsynti.cpp22
-rw-r--r--muse2/synti/libsynti/mess.cpp4
5 files changed, 83 insertions, 10 deletions
diff --git a/muse2/ChangeLog b/muse2/ChangeLog
index 63ef9713..0eb4c473 100644
--- a/muse2/ChangeLog
+++ b/muse2/ChangeLog
@@ -1,5 +1,6 @@
12.11.2012:
- Added aftertouch controllers to all relevant remaining instrument files. (Tim)
+ - Synths: Added aftertouch controller to fluidsynth, and aftertouch/poly-aftertouch to DSSI. (Tim)
11.11.2012:
- Finished Aftertouch controllers: Removed PAfter and CAfter Event types. Quietly convert such
events in old songs into the new controllers. Converted midi input (hopefully). (Tim)
diff --git a/muse2/muse/dssihost.cpp b/muse2/muse/dssihost.cpp
index c76631e4..70db2a47 100644
--- a/muse2/muse/dssihost.cpp
+++ b/muse2/muse/dssihost.cpp
@@ -1112,6 +1112,32 @@ bool DssiSynthIF::processEvent(const MusECore::MidiPlayEvent& e, snd_seq_event_t
return true;
}
+ if(a == MusECore::CTRL_AFTERTOUCH)
+ {
+ #ifdef DSSI_DEBUG
+ fprintf(stderr, "DssiSynthIF::processEvent midi event is MusECore::ME_CONTROLLER, dataA is MusECore::CTRL_AFTERTOUCH\n");
+ #endif
+
+ snd_seq_ev_clear(event);
+ event->queue = SND_SEQ_QUEUE_DIRECT;
+ snd_seq_ev_set_chanpress(event, chn, b);
+ // Event pointer filled. Return true.
+ return true;
+ }
+
+ if((a | 0xff) == MusECore::CTRL_POLYAFTER)
+ {
+ #ifdef DSSI_DEBUG
+ fprintf(stderr, "DssiSynthIF::processEvent midi event is MusECore::ME_CONTROLLER, dataA is MusECore::CTRL_POLYAFTER\n");
+ #endif
+
+ snd_seq_ev_clear(event);
+ event->queue = SND_SEQ_QUEUE_DIRECT;
+ snd_seq_ev_set_keypress(event, chn, a & 0x7f, b & 0x7f);
+ // Event pointer filled. Return true.
+ return true;
+ }
+
const LADSPA_Descriptor* ld = dssi->LADSPA_Plugin;
MusECore::ciMidiCtl2LadspaPort ip = synth->midiCtl2PortMap.find(a);
@@ -1219,6 +1245,11 @@ bool DssiSynthIF::processEvent(const MusECore::MidiPlayEvent& e, snd_seq_event_t
event->queue = SND_SEQ_QUEUE_DIRECT;
snd_seq_ev_set_chanpress(event, chn, a);
break;
+ case MusECore::ME_POLYAFTER:
+ snd_seq_ev_clear(event);
+ event->queue = SND_SEQ_QUEUE_DIRECT;
+ snd_seq_ev_set_keypress(event, chn, a & 0x7f, b & 0x7f);
+ break;
case MusECore::ME_SYSEX:
{
#ifdef DSSI_DEBUG
@@ -1615,6 +1646,19 @@ MusECore::iMPEvent DssiSynthIF::getData(MusECore::MidiPort* /*mp*/, MusECore::MP
if(!mp->setHwCtrlState(start_event->channel(), MusECore::CTRL_PITCH, da))
continue;
}
+ else if(start_event->type() == MusECore::ME_AFTERTOUCH)
+ {
+ int da = mp->limitValToInstrCtlRange(MusECore::CTRL_AFTERTOUCH, start_event->dataA());
+ if(!mp->setHwCtrlState(start_event->channel(), MusECore::CTRL_AFTERTOUCH, da))
+ continue;
+ }
+ else if(start_event->type() == MusECore::ME_POLYAFTER)
+ {
+ int ctl = (MusECore::CTRL_POLYAFTER & ~0xff) | (start_event->dataA() & 0x7f);
+ int db = mp->limitValToInstrCtlRange(ctl, start_event->dataB());
+ if(!mp->setHwCtrlState(start_event->channel(), ctl , db))
+ continue;
+ }
else if(start_event->type() == MusECore::ME_PROGRAM)
{
if(!mp->setHwCtrlState(start_event->channel(), MusECore::CTRL_PROGRAM, start_event->dataA()))
@@ -2160,7 +2204,23 @@ void DssiSynthIF::populatePatchPopup(MusEGui::PopupMenu* menu, int /*ch*/, bool
int DssiSynthIF::getControllerInfo(int id, const char** name, int* ctrl, int* min, int* max, int* initval)
{
int controlPorts = synth->_controlInPorts;
- if(id >= controlPorts)
+ if(id == controlPorts || id == controlPorts + 1)
+ {
+ //
+ // It is unknown at this point whether or not a synth recognizes aftertouch and poly aftertouch
+ // (channel and key pressure) midi messages, so add support for them now (as controllers).
+ //
+ if(id == controlPorts)
+ *ctrl = MusECore::CTRL_POLYAFTER;
+ else if(id == controlPorts + 1)
+ *ctrl = MusECore::CTRL_AFTERTOUCH;
+ *min = 0;
+ *max = 127;
+ *initval = MusECore::CTRL_VAL_UNKNOWN;
+ *name = midiCtrlName(*ctrl).toLatin1().constData();
+ return ++id;
+ }
+ else if(id >= controlPorts + 2)
return 0;
const DSSI_Descriptor* dssi = synth->dssi;
diff --git a/muse2/muse/midiport.cpp b/muse2/muse/midiport.cpp
index 61e7ab50..e4759d31 100644
--- a/muse2/muse/midiport.cpp
+++ b/muse2/muse/midiport.cpp
@@ -794,7 +794,9 @@ int MidiPort::limitValToInstrCtlRange(int ctl, int val)
return val;
MidiControllerList* cl = _instrument->controller();
-
+
+ // FIXME: This might be optimized by calling midiController instead,
+ // and simply asking if it's a drum controller. Saves one list iteration.
// Is it a drum controller?
MidiController *mc = drumController(ctl);
if(!mc)
diff --git a/muse2/synti/fluidsynth/fluidsynti.cpp b/muse2/synti/fluidsynth/fluidsynti.cpp
index 46f20156..3dd45105 100644
--- a/muse2/synti/fluidsynth/fluidsynti.cpp
+++ b/muse2/synti/fluidsynth/fluidsynti.cpp
@@ -76,6 +76,7 @@ FluidCtrl FluidSynth::fluidCtrl[] = {
{ "Channel reverb send", MusECore::CTRL_REVERB_SEND, 0, 127, 40},
{ "Channel chorus send", MusECore::CTRL_CHORUS_SEND, 0, 127, 0},
{ "Pitch", MusECore::CTRL_PITCH, -8192, 8191, 0},
+ { "Channel pressure", MusECore::CTRL_AFTERTOUCH, 0, 127, 0},
// Added by T356
{ "Pitch bend sensitivity", FS_PITCHWHEELSENS, 0, 24, 2}
};
@@ -508,7 +509,9 @@ bool FluidSynth::processEvent(const MusECore::MidiPlayEvent& ev)
case MusECore::ME_PITCHBEND:
setController(ev.channel(), MusECore::CTRL_PITCH, ev.dataA(), false);
break;
-
+ case MusECore::ME_AFTERTOUCH:
+ setController(ev.channel(), MusECore::CTRL_AFTERTOUCH, ev.dataA(), false);
+ break;
case MusECore::ME_PROGRAM:
setController(ev.channel(), MusECore::CTRL_PROGRAM, ev.dataA(), false);
break;
@@ -983,15 +986,20 @@ void FluidSynth::setController(int channel, int id, int val, bool fromGui)
//
case MusECore::CTRL_PITCH:
// MusE's range is from -8192 to +8191, fluidsynth seems to be [0, 16384]
- val +=8192;
- err = fluid_synth_pitch_bend (fluidsynth, channel, val);
+ if(val != MusECore::CTRL_VAL_UNKNOWN)
+ {
+ val +=8192;
+ err = fluid_synth_pitch_bend (fluidsynth, channel, val);
+ }
+ break;
+ case MusECore::CTRL_AFTERTOUCH:
+ if(val != MusECore::CTRL_VAL_UNKNOWN)
+ err = fluid_synth_channel_pressure (fluidsynth, channel, val);
break;
-
- // Added by T356
case FS_PITCHWHEELSENS:
- err = fluid_synth_pitch_wheel_sens(fluidsynth, channel, val);
+ if(val != MusECore::CTRL_VAL_UNKNOWN)
+ err = fluid_synth_pitch_wheel_sens(fluidsynth, channel, val);
break;
-
case MusECore::CTRL_PROGRAM: {
//Check if MusE is trying to set a preset on an unspecified font. If so, ignore.
if (FS_DEBUG)
diff --git a/muse2/synti/libsynti/mess.cpp b/muse2/synti/libsynti/mess.cpp
index 027a30c1..de24ac00 100644
--- a/muse2/synti/libsynti/mess.cpp
+++ b/muse2/synti/libsynti/mess.cpp
@@ -145,8 +145,10 @@ bool Mess::processEvent(const MusECore::MidiPlayEvent& ev)
return sysex(ev.len(), ev.data());
case MusECore::ME_CONTROLLER:
return setController(ev.channel(), ev.dataA(), ev.dataB());
- case MusECore::ME_PITCHBEND: // Tim.
+ case MusECore::ME_PITCHBEND:
return setController(ev.channel(), MusECore::CTRL_PITCH, ev.dataA());
+ case MusECore::ME_AFTERTOUCH:
+ return setController(ev.channel(), MusECore::CTRL_AFTERTOUCH, ev.dataA());
}
return false;
}