| 
				
				
					
				
				
				 | 
			
			 | 
			@@ -48,8 +48,8 @@ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			 * - hide parameter outputs? | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			 * - hide program parameter? | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			 * - deal with parameter triggers | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			 * - midi cc parameter mapping | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			 * - full MIDI1 encode and decode | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			 * - MIDI program changes | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			 * - append MIDI input events in a sorted way | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			 * - decode version number (0x010203 -> 1.2.3) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			 * - bus arrangements | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			 * - optional audio buses, create dummy buffer of max_block_size length for them | 
		
		
	
	
		
			
				| 
				
					
				
				
					
				
				
				 | 
			
			 | 
			@@ -130,7 +130,6 @@ const char* tuid2str(const v3_tuid iid) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        { V3_ID(0xF040B4B3,0xA36045EC,0xABCDC045,0xB4D5A2CC), "{v3_component_handler2|NOT}" }, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        { V3_ID(0x7F4EFE59,0xF3204967,0xAC27A3AE,0xAFB63038), "{v3_edit_controller2|NOT}" }, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        { V3_ID(0x067D02C1,0x5B4E274D,0xA92D90FD,0x6EAF7240), "{v3_component_handler_bus_activation|NOT}" }, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        { V3_ID(0xDF0FF9F7,0x49B74669,0xB63AB732,0x7ADBF5E5), "{v3_midi_mapping|NOT}" }, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        { V3_ID(0xC1271208,0x70594098,0xB9DD34B3,0x6BB0195E), "{v3_edit_controller_host_editing|NOT}" }, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        // units | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        { V3_ID(0x8683B01F,0x7B354F70,0xA2651DEC,0x353AF4FF), "{v3_program_list_data|NOT}" }, | 
		
		
	
	
		
			
				| 
				
					
				
				
					
				
				
				 | 
			
			 | 
			@@ -164,6 +163,8 @@ const char* tuid2str(const v3_tuid iid) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        return "{v3_funknown}"; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    if (v3_tuid_match(iid, v3_message_iid)) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        return "{v3_message_iid}"; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    if (v3_tuid_match(iid, v3_midi_mapping_iid)) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        return "{v3_midi_mapping_iid}"; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    if (v3_tuid_match(iid, v3_param_value_queue_iid)) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        return "{v3_param_value_queue}"; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    if (v3_tuid_match(iid, v3_param_changes_iid)) | 
		
		
	
	
		
			
				| 
				
					
				
				
					
				
				
				 | 
			
			 | 
			@@ -1189,12 +1190,12 @@ public: | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                case V3_EVENT_NOTE_OFF: | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                // case V3_EVENT_DATA: | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                case V3_EVENT_POLY_PRESSURE: | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                    break; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                // case V3_EVENT_NOTE_EXP_VALUE: | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                // case V3_EVENT_NOTE_EXP_TEXT: | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                // case V3_EVENT_CHORD: | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                // case V3_EVENT_SCALE: | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                case V3_EVENT_LEGACY_MIDI_CC_OUT: | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                    break; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                // case V3_EVENT_LEGACY_MIDI_CC_OUT: | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                default: | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                    continue; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                } | 
		
		
	
	
		
			
				| 
				
					
				
				
					
				
				
				 | 
			
			 | 
			@@ -1226,14 +1227,6 @@ public: | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                    midiEvent.data[2] = std::max(0, std::min(127, (int)(event.poly_pressure.pressure * 127))); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                    midiEvent.data[3] = 0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                    break; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                case V3_EVENT_LEGACY_MIDI_CC_OUT: | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                    midiEvent.size = 3; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                    midiEvent.data[0] = 0xB0 | (event.midi_cc_out.channel & 0xf); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                    midiEvent.data[1] = event.midi_cc_out.cc_number; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                    midiEvent.data[2] = event.midi_cc_out.value; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                    midiEvent.data[3] = 0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                    // midiEvent.data[3] = event.midi_cc_out.value2; // TODO check when size should be 4 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                    break; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                default: | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                    midiEvent.size = 0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                    break; | 
		
		
	
	
		
			
				| 
				
				
				
					
				
				 | 
			
			 | 
			@@ -1244,6 +1237,75 @@ public: | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        // TODO append MIDI events in a sorted way | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        if (v3_param_changes** const inparamsptr = data->input_params) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            v3_param_value_queue** queue; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            int32_t offset; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            double value; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            for (int32_t i = 0, count = v3_cpp_obj(inparamsptr)->get_param_count(inparamsptr); i < count; ++i) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                queue = v3_cpp_obj(inparamsptr)->get_param_data(inparamsptr, i); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                DISTRHO_SAFE_ASSERT_BREAK(queue != nullptr); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                v3_param_id rindex = v3_cpp_obj(queue)->get_param_id(queue); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                DISTRHO_SAFE_ASSERT_UINT_BREAK(rindex < fRealParameterCount, rindex); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                // not supported yet | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                if (rindex >= fParameterOffset) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                    continue; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			# if DISTRHO_PLUGIN_WANT_PROGRAMS | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                if (rindex == 0) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                    continue; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                --rindex; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			# endif | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                for (int32_t j = 0, pcount = v3_cpp_obj(queue)->get_point_count(queue); j < pcount; ++j) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                    if (v3_cpp_obj(queue)->get_point(queue, j, &offset, &value) != V3_OK) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                        break; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                    DISTRHO_SAFE_ASSERT_BREAK(offset < data->nframes); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                    MidiEvent& midiEvent(fMidiEvents[midiEventCount++]); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                    midiEvent.frame = offset; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                    midiEvent.size = 3; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                    midiEvent.data[0] = (rindex / 130) & 0xf; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                    switch (rindex) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                    { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                    case 128: // channel pressure | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                        midiEvent.data[0] |= 0xD0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                        midiEvent.data[1] = std::max(0, std::min(127, (int)(value * 127))); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                        midiEvent.data[2] = 0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                        midiEvent.data[3] = 0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                        break; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                    case 129: // pitchbend | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                        midiEvent.data[0] |= 0xE0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                        midiEvent.data[1] = std::max(0, std::min(16384, (int)(value * 16384))) & 0x7f; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                        midiEvent.data[2] = std::max(0, std::min(16384, (int)(value * 16384))) >> 7; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                        midiEvent.data[3] = 0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                        break; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                    default: | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                        midiEvent.data[0] |= 0xB0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                        midiEvent.data[1] = rindex % 130; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                        midiEvent.data[2] = std::max(0, std::min(127, (int)(value * 127))); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                        midiEvent.data[3] = 0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                        break; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                    } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                    if (midiEventCount == kMaxMidiEvents) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                        break; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                if (midiEventCount == kMaxMidiEvents) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                    break; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        fPlugin.run(inputs, outputs, data->nframes, fMidiEvents, midiEventCount); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#else | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        fPlugin.run(inputs, outputs, data->nframes); | 
		
		
	
	
		
			
				| 
				
					
				
				
					
				
				
				 | 
			
			 | 
			@@ -2018,7 +2080,25 @@ private: | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            event.midi_cc_out.channel = data[0] & 0xf; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            event.midi_cc_out.cc_number = data[1]; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            event.midi_cc_out.value = data[2]; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            event.midi_cc_out.value2 = midiEvent.size == 4 ? data[3] : 0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            if (midiEvent.size == 4) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                event.midi_cc_out.value2 = midiEvent.size == 4; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            break; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        /* TODO how do we deal with program changes?? | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        case 0xC0: | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            break; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        case 0xD0: | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            event.type = V3_EVENT_LEGACY_MIDI_CC_OUT; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            event.midi_cc_out.channel = data[0] & 0xf; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            event.midi_cc_out.cc_number = 128; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            event.midi_cc_out.value = data[1]; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            break; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        case 0xE0: | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            event.type = V3_EVENT_LEGACY_MIDI_CC_OUT; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            event.midi_cc_out.channel = data[0] & 0xf; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            event.midi_cc_out.cc_number = 129; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            event.midi_cc_out.value = data[1]; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            event.midi_cc_out.value2 = data[2]; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            break; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        default: | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            return true; | 
		
		
	
	
		
			
				| 
				
					
				
				
					
				
				
				 | 
			
			 | 
			@@ -2594,18 +2674,78 @@ struct dpf_dsp_connection_point : v3_connection_point_cpp { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			}; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#endif | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#if DISTRHO_PLUGIN_WANT_MIDI_INPUT | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			// -------------------------------------------------------------------------------------------------------------------- | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			// dpf_edit_controller | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			// dpf_midi_mapping | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			struct v3_edit_controller_cpp : v3_funknown { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    v3_plugin_base base; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    v3_edit_controller controller; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			struct dpf_midi_mapping : v3_midi_mapping_cpp { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    ScopedPointer<PluginVst3>& vst3; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    dpf_midi_mapping(ScopedPointer<PluginVst3>& v) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        : vst3(v) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        static const uint8_t* kSupportedInterfaces[] = { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            v3_funknown_iid, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            v3_midi_mapping_iid | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        }; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        // ------------------------------------------------------------------------------------------------------------ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        // v3_funknown | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        query_interface = []V3_API(void* self, const v3_tuid iid, void** iface) -> v3_result | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            d_stdout("dpf_midi_mapping::query_interface               => %p %s %p", self, tuid2str(iid), iface); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            *iface = NULL; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            DISTRHO_SAFE_ASSERT_RETURN(self != nullptr, V3_NO_INTERFACE); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            for (const uint8_t* interface_iid : kSupportedInterfaces) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                if (v3_tuid_match(interface_iid, iid)) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                    *iface = self; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                    return V3_OK; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            return V3_NO_INTERFACE; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        }; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        // there is only a single instance of this, so we don't have to care here | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        ref = []V3_API(void*) -> uint32_t { return 1; }; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        unref = []V3_API(void*) -> uint32_t { return 0; }; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        // ------------------------------------------------------------------------------------------------------------ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        // v3_midi_mapping | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        map.get_midi_controller_assignment = []V3_API(void*, int32_t bus, int16_t channel, int16_t cc, v3_param_id* id) -> v3_result | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            DISTRHO_SAFE_ASSERT_INT_RETURN(bus == 0, bus, V3_FALSE); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            DISTRHO_SAFE_ASSERT_INT_RETURN(channel >= 0 && channel < 16, channel, V3_FALSE); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            DISTRHO_SAFE_ASSERT_INT_RETURN(cc >= 0 && cc < 130, cc, V3_FALSE); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#if DISTRHO_PLUGIN_WANT_PROGRAMS | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            static constexpr const v3_param_id offset = 1; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#else | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            static const constexpr v3_param_id offset = 0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#endif | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            *id = offset + channel * 130 + cc; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            return V3_OK; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        }; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			}; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#endif | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			// -------------------------------------------------------------------------------------------------------------------- | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			// dpf_edit_controller | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			struct dpf_edit_controller : v3_edit_controller_cpp { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#if DISTRHO_PLUGIN_HAS_UI | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    ScopedPointer<dpf_dsp_connection_point> connectionComp;   // kConnectionPointController | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    ScopedPointer<dpf_dsp_connection_point> connectionBridge; // kConnectionPointBridge | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#endif | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#if DISTRHO_PLUGIN_WANT_MIDI_INPUT | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    ScopedPointer<dpf_midi_mapping> midiMapping; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#endif | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    ScopedPointer<PluginVst3>& vst3; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    bool initialized; | 
		
		
	
	
		
			
				| 
				
					
				
				
					
				
				
				 | 
			
			 | 
			@@ -2640,10 +2780,10 @@ struct dpf_edit_controller : v3_edit_controller_cpp { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#if DISTRHO_PLUGIN_HAS_UI | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            dpf_edit_controller* const controller = *(dpf_edit_controller**)self; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            DISTRHO_SAFE_ASSERT_RETURN(controller != nullptr, V3_NO_INTERFACE); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#if DISTRHO_PLUGIN_HAS_UI | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            if (v3_tuid_match(v3_connection_point_iid, iid)) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                if (controller->connectionComp == nullptr) | 
		
		
	
	
		
			
				| 
				
				
				
					
				
				 | 
			
			 | 
			@@ -2654,6 +2794,16 @@ struct dpf_edit_controller : v3_edit_controller_cpp { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#endif | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#if DISTRHO_PLUGIN_WANT_MIDI_INPUT | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            if (v3_tuid_match(v3_midi_mapping_iid, iid)) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                if (controller->midiMapping == nullptr) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                    controller->midiMapping = new dpf_midi_mapping(controller->vst3); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                *iface = &controller->midiMapping; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                return V3_OK; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#endif | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            return V3_NO_INTERFACE; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        }; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
	
		
			
				| 
				
					
				
				
				
				 | 
			
			 | 
			
  |