示例#1
0
文件: Mapper.cs 项目: jweite/JoeMidi
        public void NoteOn(NoteOnMessage msg)
        {
            // Find the per-device/channel mappings for the message's Device/Channel.  If there's none, nothing to do.
            String deviceKey = Mapping.PerDeviceChannelMapping.createKey(msg.Device.Name, (int)msg.Channel);

            if (!m_perDeviceChannelMappings.ContainsKey(deviceKey))
            {
                return;
            }
            Mapping.PerDeviceChannelMapping perDeviceChannelMapping = m_perDeviceChannelMappings[deviceKey];

            // Iterate over the NoteMappings for this device/channel
            foreach (NoteMapping mapping in perDeviceChannelMapping.noteMappings)
            {
                // See if the note received is in range for the NoteMapping currently under consideration
                if (msg.Pitch >= (Pitch)mapping.lowestNote && msg.Pitch <= (Pitch)mapping.highestNote)
                {
                    // It is.
                    // Create mapped note record
                    MappedNote mappedNoteRecord = new MappedNote();
                    mappedNoteRecord.sourceDeviceName = msg.Device.Name;
                    mappedNoteRecord.sourceChannel    = msg.Channel;
                    mappedNoteRecord.origNote         = msg.Pitch;
                    SoundGenerator soundGenerator = mapping.soundGenerator;
                    mappedNoteRecord.mappedDevice  = soundGenerator.device;
                    mappedNoteRecord.mappedChannel = (Channel)mapping.soundGeneratorPhysicalChannel;
                    mappedNoteRecord.mappedNote    = msg.Pitch + mapping.pitchOffset + masterTranspose;

                    if (mappedNoteRecord.mappedNote < 0 || mappedNoteRecord.mappedNote > (Pitch)127)
                    {
                        continue;
                    }

                    // See if this note is already sounding.  Look it up based on it's unmapped device, channel and note#.
                    MappedNote matchingMappedNoteAlreadySounding = FindMappedNote(mappedNoteRecord);
                    if (matchingMappedNoteAlreadySounding != null)
                    {
                        matchingMappedNoteAlreadySounding.mappedDevice.SendNoteOff(matchingMappedNoteAlreadySounding.mappedChannel, matchingMappedNoteAlreadySounding.mappedNote, 127);
                        m_mappedNotesList.Remove(matchingMappedNoteAlreadySounding);
                    }

                    // Now, play the new mapping of the source note.
                    mappedNoteRecord.mappedDevice.SendNoteOn(mappedNoteRecord.mappedChannel, mappedNoteRecord.mappedNote, msg.Velocity);

                    // And add it to the dictionary of sounding notes.
                    m_mappedNotesList.Add(mappedNoteRecord);
                }
            }
        }
示例#2
0
文件: Mapper.cs 项目: jweite/JoeMidi
        public void PitchBend(PitchBendMessage msg)
        {
            // Find the per-device/channel mappings for the message's Device/Channel.  If there's none, nothing to do.
            String deviceKey = Mapping.PerDeviceChannelMapping.createKey(msg.Device.Name, (int)msg.Channel);

            if (!m_perDeviceChannelMappings.ContainsKey(deviceKey))
            {
                return;
            }
            Mapping.PerDeviceChannelMapping perDeviceChannelMapping = m_perDeviceChannelMappings[deviceKey];

            // Iterate over the pitch-bend mappings for this device/channel and send the pitch bend, scaled per the mapping, to the target device
            foreach (PitchBendMapping pitchBendMapping in perDeviceChannelMapping.pitchBendMappings)
            {
                if (pitchBendMapping.scale != 0.0)
                {
                    pitchBendMapping.soundGenerator.device.SendPitchBend((Channel)pitchBendMapping.soundGeneratorPhysicalChannel, (int)(msg.Value * pitchBendMapping.scale));
                }
            }
        }
示例#3
0
        public void createTrialConfiguration()
        {
            dirty = true;

            try
            {
                Mapping.PerDeviceChannelMapping globalPerInputDeviceChannelMapping = new Mapping.PerDeviceChannelMapping();
                globalPerInputDeviceChannelMapping.logicalInputDeviceName = "Input Device 1";
                globalPerInputDeviceChannelMapping.inputDeviceChannel     = 0;

                ControlMapping globalControlMapping = new ControlMapping();
                globalControlMapping.soundGeneratorName            = "Reaper";
                globalControlMapping.soundGeneratorRelativeChannel = 0;
                globalControlMapping.sourceControlNumber           = 75; // Top Left Rotary Knob on Oxygen
                globalControlMapping.mappedControlNumber           = 9;  // I've got Reaper Master Volume mapped to this.
                globalControlMapping.min = 30;                           // This provides a nice workable vol range
                globalControlMapping.max = 91;
                globalPerInputDeviceChannelMapping.controlMappings.Add(globalControlMapping);

                globalControlMappings.Add(globalPerInputDeviceChannelMapping);

                primaryInputDeviceName = "Input Device 1";

                LogicalInputDevice.createTrialConfiguration(logicalInputDeviceDict);

                LogicalOutputDevice.createTrialConfiguration(logicalOutputDeviceDict);

                SoundGenerator.createTrialConfiguration(soundGenerators);

                Mapping.createTrialConfiguration(mappings);

                MidiProgram.createTrialConfiguration(midiPrograms);

                Setlist.createTrialConfiguration(songDict, setlists);
            }
            catch (Exception e)
            {
                MessageBox.Show("Exception creating trial configurations: " + e);
            }
        }
示例#4
0
文件: Mapper.cs 项目: jweite/JoeMidi
        public void ControlChange(ControlChangeMessage msg)
        {
            // First we see if this is a "global" control, ie, one registered for JoeMidi as a whole, not for particular mappings.
            //  This might be used to create a master-volume control that's always in effect.

            bool globalControlChangeSent = false;

            foreach (Mapping.PerDeviceChannelMapping globalPerDeviceChannelMappings in configuration.globalControlMappings)
            {
                if (globalPerDeviceChannelMappings.inputDevice != null && globalPerDeviceChannelMappings.inputDevice.Equals(msg.Device) && globalPerDeviceChannelMappings.inputDeviceChannel == (int)msg.Channel)
                {
                    foreach (ControlMapping controlMapping in globalPerDeviceChannelMappings.controlMappings)
                    {
                        if (controlMapping.sourceControlNumber == (int)msg.Control)
                        {
                            int scaledValue = (int)(msg.Value * controlMapping.scale) + controlMapping.min;
                            controlMapping.soundGenerator.device.SendControlChange((Channel)controlMapping.soundGeneratorPhysicalChannel, (Midi.Control)controlMapping.mappedControlNumber, scaledValue);
                            globalControlChangeSent = true;
                        }
                    }
                }
            }
            if (globalControlChangeSent == true)
            {
                // When a control mapping is defined globally any per-mapping definitions of it are ignored.  Debatable one day...
                return;
            }


            // Find the per-device/channel mappings for the message's Device/Channel.  If there's none, nothing else to do.
            String deviceKey = Mapping.PerDeviceChannelMapping.createKey(msg.Device.Name, (int)msg.Channel);

            if (!m_perDeviceChannelMappings.ContainsKey(deviceKey))
            {
                return;
            }
            Mapping.PerDeviceChannelMapping perDeviceChannelMapping = m_perDeviceChannelMappings[deviceKey];

            // Iterate over the control mappings ...
            foreach (ControlMapping controlMapping in perDeviceChannelMapping.controlMappings)
            {
                // If we've received a control change message that the current mapping remaps process it.
                if (controlMapping.sourceControlNumber == (int)msg.Control && controlMapping.mappedControlNumber >= 0)
                {
                    // Two control mapping modes: toggle and regular.
                    if (controlMapping.bToggle == false)
                    {
                        // Regular remap of incoming control message to a different outgoing control#, with value scaled from the incoming range of
                        //  0-127 to an outgoing range of min-max.
                        int scaledValue = (int)(msg.Value * controlMapping.scale) + controlMapping.min;

                        // Special processing for sustain pedal
                        if (controlMapping.mappedControlNumber == (int)Midi.Control.SustainPedal)
                        {
                            if (msg.Value > 0)
                            {
                                // Down: Record what physical device/channels are receiving it from the source device.
                                recordSustainPedalDown(msg.Device, controlMapping.soundGenerator.device, (Channel)controlMapping.soundGeneratorPhysicalChannel);
                                controlMapping.soundGenerator.device.SendControlChange((Channel)controlMapping.soundGeneratorPhysicalChannel, (Midi.Control)controlMapping.mappedControlNumber, scaledValue);
                            }
                            else
                            {
                                // Up: un-sustain any soundGen that was previously sustained by a message originating from the source input device
                                sendSustainPedalUpToAllDeviceChannelsWithSustainPedalDown(msg.Device);
                            }
                        }
                        // Special Processing for cc7: Scaling again, on a per-sound-generator basis, to accomodate diff sound generator cc7 ranges.
                        else if (controlMapping.mappedControlNumber == (int)Midi.Control.Volume)
                        {
                            scaledValue = (int)(scaledValue * controlMapping.soundGenerator.cc7Scale) + controlMapping.soundGenerator.cc7Min;
                            controlMapping.soundGenerator.device.SendControlChange((Channel)controlMapping.soundGeneratorPhysicalChannel, (Midi.Control)controlMapping.mappedControlNumber, scaledValue);
                        }
                        else
                        {
                            controlMapping.soundGenerator.device.SendControlChange((Channel)controlMapping.soundGeneratorPhysicalChannel, (Midi.Control)controlMapping.mappedControlNumber, scaledValue);
                        }
                    }
                    else
                    {
                        // Toggle mode alternately sends min and max remapped values to the remap control# on receipt of remappable control messages with values > 0x40.
                        //  This is typically used with momentary switch controls which send 7F on press and 0 on release.
                        //  I created this to allow my sustain pedal to toggle Rotary Speaker speed between high and low on each press.
                        if (msg.Value >= 0x40)
                        {
                            if (controlMapping.currentToggleState == true)
                            {
                                controlMapping.currentToggleState = false;
                                controlMapping.soundGenerator.device.SendControlChange((Channel)controlMapping.soundGeneratorPhysicalChannel, (Midi.Control)controlMapping.mappedControlNumber, controlMapping.max);
                            }
                            else
                            {
                                controlMapping.currentToggleState = true;
                                controlMapping.soundGenerator.device.SendControlChange((Channel)controlMapping.soundGeneratorPhysicalChannel, (Midi.Control)controlMapping.mappedControlNumber, controlMapping.min);
                            }
                        }
                    }
                }
            }
        }
示例#5
0
        virtual public bool bind(Dictionary <String, LogicalInputDevice> logicalInputDeviceDict, Dictionary <String, SoundGenerator> soundGenerators, Dictionary <String, Mapping> mappings, LogicalInputDevice primaryInputDevice)
        {
            // Find or create a Mapping for this MidiProgram that it will point to

            if (bSingle == false)       // If it's not a single, then it's a mapping, so just find the one named.
            {
                if (mappings.ContainsKey(this.MappingName))
                {
                    mapping = mappings[this.MappingName];
                    return(true);
                }
                else
                {
                    MessageBox.Show("MidiProgram Mapping " + this.MappingName + " not defined in this configuration.");
                    return(false);
                }
            }
            else
            {
                // If it's a single, then we create a mapping on the fly for it.

                mapping = new Mapping();

                String candidateName = "(S) " + this.SinglePatchName;
                if (mappings.ContainsKey(candidateName))
                {
                    // Patch Name alone isn't a unique mapping name.  Fully qualify it with the SG name too.
                    candidateName = "(S) " + this.SingleSoundGeneratorName + " - " + this.SinglePatchName;
                }
                mapping.name = candidateName;

                // Create a single mapping with some settings values on the fly
                Mapping.PerDeviceChannelMapping perDeviceChannelMapping = new Mapping.PerDeviceChannelMapping();
                perDeviceChannelMapping.logicalInputDeviceName = primaryInputDevice.logicalDeviceName;
                perDeviceChannelMapping.inputDeviceChannel     = 0;

                NoteMapping noteMapping = new NoteMapping();
                noteMapping.soundGeneratorName            = this.SingleSoundGeneratorName;
                noteMapping.soundGeneratorRelativeChannel = 0;
                noteMapping.lowestNote  = 0;
                noteMapping.highestNote = 127;
                noteMapping.pitchOffset = 0;
                perDeviceChannelMapping.noteMappings.Add(noteMapping);

                MappingPatch mappingPatch = new MappingPatch();
                mappingPatch.soundGeneratorName            = this.SingleSoundGeneratorName;
                mappingPatch.soundGeneratorRelativeChannel = 0;
                mappingPatch.patchName = this.SinglePatchName;
                perDeviceChannelMapping.mappingPatches.Add(mappingPatch);

                PitchBendMapping pitchBendMapping = new PitchBendMapping();
                pitchBendMapping.soundGeneratorName            = this.SingleSoundGeneratorName;
                pitchBendMapping.soundGeneratorRelativeChannel = 0;
                pitchBendMapping.scale = 1.0;
                perDeviceChannelMapping.pitchBendMappings.Add(pitchBendMapping);

                ControlMapping controlMapping = new ControlMapping();
                controlMapping.soundGeneratorName            = this.SingleSoundGeneratorName;
                controlMapping.soundGeneratorRelativeChannel = 0;
                controlMapping.sourceControlNumber           = 1; // Mod Wheel
                controlMapping.mappedControlNumber           = 1;
                controlMapping.min          = 0;
                controlMapping.max          = 127;
                controlMapping.initialValue = -1;
                perDeviceChannelMapping.controlMappings.Add(controlMapping);

                controlMapping = new ControlMapping();
                controlMapping.soundGeneratorName            = this.SingleSoundGeneratorName;
                controlMapping.soundGeneratorRelativeChannel = 0;
                controlMapping.sourceControlNumber           = -1;
                controlMapping.mappedControlNumber           = 7; // Vol
                controlMapping.min          = 0;
                controlMapping.max          = 127;
                controlMapping.initialValue = 127;
                perDeviceChannelMapping.controlMappings.Add(controlMapping);

                controlMapping = new ControlMapping();
                controlMapping.soundGeneratorName            = this.SingleSoundGeneratorName;
                controlMapping.soundGeneratorRelativeChannel = 0;
                controlMapping.sourceControlNumber           = 64; // Damper
                controlMapping.mappedControlNumber           = 64;
                controlMapping.min          = 0;
                controlMapping.max          = 127;
                controlMapping.initialValue = -1;
                perDeviceChannelMapping.controlMappings.Add(controlMapping);

                // Kurzweil Artis Variation Button...
                controlMapping = new ControlMapping();
                controlMapping.soundGeneratorName            = this.SingleSoundGeneratorName;
                controlMapping.soundGeneratorRelativeChannel = 0;
                controlMapping.sourceControlNumber           = 0x1D;
                controlMapping.mappedControlNumber           = 0x1D;
                controlMapping.min          = 0;
                controlMapping.max          = 127;
                controlMapping.initialValue = -1;
                perDeviceChannelMapping.controlMappings.Add(controlMapping);

                mapping.perDeviceChannelMappings.Add(perDeviceChannelMapping.key, perDeviceChannelMapping);

                return(mapping.bind(logicalInputDeviceDict, soundGenerators));
            }
        }
示例#6
0
        override public bool bind(Dictionary <String, LogicalInputDevice> logicalInputDeviceDict, Dictionary <String, SoundGenerator> soundGenerators)
        {
            // Builds out an actual Mapping based on the SimpleMapping.

            Dictionary <String, int> soundGeneratorChannelAssignments = new Dictionary <string, int>();

            perDeviceChannelMappings.Clear();

            foreach (PerDeviceSimpleMapping perDeviceSimpleMapping in perDeviceSimpleMappings)
            {
                Mapping.PerDeviceChannelMapping perDeviceChannelMapping = new Mapping.PerDeviceChannelMapping(perDeviceSimpleMapping.inputDeviceName, perDeviceSimpleMapping.inputDeviceChannel);

                foreach (SimpleMappingDefinition simpleMappingDefinition in perDeviceSimpleMapping.simpleMappingDefinitions)
                {
                    NoteMapping noteMapping        = new NoteMapping();
                    String      soundGeneratorName = simpleMappingDefinition.soundGeneratorName;
                    noteMapping.soundGeneratorName = soundGeneratorName;

                    int soundGeneratorRelativeChannel = 0;
                    if (soundGeneratorChannelAssignments.ContainsKey(soundGeneratorName))
                    {
                        soundGeneratorRelativeChannel = soundGeneratorChannelAssignments[soundGeneratorName] + 1;
                        soundGeneratorChannelAssignments[soundGeneratorName] = soundGeneratorRelativeChannel;
                    }
                    else
                    {
                        soundGeneratorRelativeChannel = 0;
                        soundGeneratorChannelAssignments.Add(soundGeneratorName, 0);
                    }
                    noteMapping.soundGeneratorRelativeChannel = soundGeneratorRelativeChannel;

                    if (perDeviceSimpleMapping.splitPoint == -1)
                    {
                        noteMapping.highestNote = 127;
                        noteMapping.lowestNote  = 0;
                    }
                    else if (simpleMappingDefinition.bLower == true)
                    {
                        noteMapping.highestNote = perDeviceSimpleMapping.splitPoint - 1;
                        noteMapping.lowestNote  = 0;
                    }
                    else
                    {
                        noteMapping.highestNote = 127;
                        noteMapping.lowestNote  = perDeviceSimpleMapping.splitPoint;
                    }
                    noteMapping.pitchOffset = simpleMappingDefinition.transpose;
                    perDeviceChannelMapping.noteMappings.Add(noteMapping);

                    MappingPatch mappingPatch = new MappingPatch();
                    mappingPatch.patchName                     = simpleMappingDefinition.programName;
                    mappingPatch.soundGeneratorName            = soundGeneratorName;
                    mappingPatch.soundGeneratorRelativeChannel = soundGeneratorRelativeChannel;
                    perDeviceChannelMapping.mappingPatches.Add(mappingPatch);

                    if (simpleMappingDefinition.pbScale != 0)
                    {
                        PitchBendMapping pitchBendMapping = new PitchBendMapping();
                        pitchBendMapping.soundGeneratorName            = soundGeneratorName;
                        pitchBendMapping.soundGeneratorRelativeChannel = soundGeneratorRelativeChannel;
                        pitchBendMapping.scale = simpleMappingDefinition.pbScale;
                        perDeviceChannelMapping.pitchBendMappings.Add(pitchBendMapping);
                    }

                    if (simpleMappingDefinition.bEnaVolControl == true || simpleMappingDefinition.initialVolume >= 0)
                    {
                        // This may be a mapping only, it may be an initial value setting only, or it may be both
                        ControlMapping ctlMapping = new ControlMapping();
                        ctlMapping.soundGeneratorName            = soundGeneratorName;
                        ctlMapping.soundGeneratorRelativeChannel = soundGeneratorRelativeChannel;
                        ctlMapping.sourceControlNumber           = (simpleMappingDefinition.bEnaVolControl == true) ? 7 : -1;
                        ctlMapping.mappedControlNumber           = 7;
                        ctlMapping.initialValue = (simpleMappingDefinition.initialVolume >= 0) ? simpleMappingDefinition.initialVolume : 127;
                        perDeviceChannelMapping.controlMappings.Add(ctlMapping);
                    }
                    if (simpleMappingDefinition.bEnaModControl == true)
                    {
                        ControlMapping ctlMapping = new ControlMapping();
                        ctlMapping.soundGeneratorName            = soundGeneratorName;
                        ctlMapping.soundGeneratorRelativeChannel = soundGeneratorRelativeChannel;
                        ctlMapping.sourceControlNumber           = 1;
                        ctlMapping.mappedControlNumber           = 1;
                        ctlMapping.initialValue = 0;
                        perDeviceChannelMapping.controlMappings.Add(ctlMapping);
                    }
                    if (simpleMappingDefinition.bEnaDamperControl == true)
                    {
                        ControlMapping ctlMapping = new ControlMapping();
                        ctlMapping.soundGeneratorName            = soundGeneratorName;
                        ctlMapping.soundGeneratorRelativeChannel = soundGeneratorRelativeChannel;
                        ctlMapping.sourceControlNumber           = 64;
                        ctlMapping.mappedControlNumber           = simpleMappingDefinition.damperRemap;
                        ctlMapping.bToggle      = simpleMappingDefinition.bDamplerToggle;               // Special option for damper: toggle mode: ie for Leslie ctl.
                        ctlMapping.initialValue = 0;
                        perDeviceChannelMapping.controlMappings.Add(ctlMapping);
                    }

                    {
                        // Kurzweil Artis Variation Button
                        ControlMapping ctlMapping = new ControlMapping();
                        ctlMapping.soundGeneratorName            = soundGeneratorName;
                        ctlMapping.soundGeneratorRelativeChannel = soundGeneratorRelativeChannel;
                        ctlMapping.sourceControlNumber           = 0x1D;
                        ctlMapping.mappedControlNumber           = 0x1D;
                        ctlMapping.initialValue = 0;
                        perDeviceChannelMapping.controlMappings.Add(ctlMapping);
                    }
                }

                perDeviceChannelMappings.Add(perDeviceChannelMapping.key, perDeviceChannelMapping);
            }

            return(base.bind(logicalInputDeviceDict, soundGenerators));
        }