| @@ -13,7 +13,7 @@ CARLA_CXX_FLAGS += -DCARLA_BACKEND_NO_NAMESPACE -DCARLA_ENGINE_JACK $(CXXFLAGS) | |||||
| CARLA_CXX_FLAGS += -DVESTIGE_HEADER -I../carla-includes/vestige # Comment this line to not use vestige header | CARLA_CXX_FLAGS += -DVESTIGE_HEADER -I../carla-includes/vestige # Comment this line to not use vestige header | ||||
| CARLA_CXX_FLAGS += -DNDEBUG -DQT_NO_DEBUG -DQT_NO_DEBUG_STREAM -DQT_NO_DEBUG_OUTPUT -O2 -ffast-math -fomit-frame-pointer -fvisibility=hidden -mtune=generic -msse | CARLA_CXX_FLAGS += -DNDEBUG -DQT_NO_DEBUG -DQT_NO_DEBUG_STREAM -DQT_NO_DEBUG_OUTPUT -O2 -ffast-math -fomit-frame-pointer -fvisibility=hidden -mtune=generic -msse | ||||
| # CARLA_CXX_FLAGS += -DDEBUG -O0 -g | # CARLA_CXX_FLAGS += -DDEBUG -O0 -g | ||||
| CARLA_LINK_FLAGS = -shared -fPIC -ldl `pkg-config --libs jack fluidsynth liblo QtCore QtGui` $(LDFLAGS) | |||||
| CARLA_LINK_FLAGS = -shared -fPIC -ldl `pkg-config --libs jack fluidsynth linuxsampler liblo QtCore QtGui` $(LDFLAGS) | |||||
| OBJS = carla_backend.o carla_bridge.o carla_engine_jack.o carla_osc.o carla_shared.o carla_threads.o ladspa.o dssi.o lv2.o vst.o fluidsynth.o linuxsampler.o lv2-rtmempool/rtmempool.o | OBJS = carla_backend.o carla_bridge.o carla_engine_jack.o carla_osc.o carla_shared.o carla_threads.o ladspa.o dssi.o lv2.o vst.o fluidsynth.o linuxsampler.o lv2-rtmempool/rtmempool.o | ||||
| @@ -1257,7 +1257,7 @@ int main(int argc, char* argv[]) | |||||
| if (engine_init("carla_demo")) | if (engine_init("carla_demo")) | ||||
| { | { | ||||
| set_callback_function(main_callback); | set_callback_function(main_callback); | ||||
| short id = add_plugin_dssi("/usr/lib/dssi/calf.so", "Reverb", "/usr/lib/dssi/calf/calf_gtk"); | |||||
| short id = add_plugin_sfz("/home/falktx/Personal/Muzyks/Kits/SFZ/AcousticGuitarFREE/AcousticGuitarFREE Samples/AcousticGuitar.sfz", "xaxaxa"); | |||||
| if (id >= 0) | if (id >= 0) | ||||
| { | { | ||||
| @@ -928,7 +928,8 @@ public: | |||||
| snd_seq_event_t* midi_event = &midi_events[midi_event_count]; | snd_seq_event_t* midi_event = &midi_events[midi_event_count]; | ||||
| memset(midi_event, 0, sizeof(snd_seq_event_t)); | memset(midi_event, 0, sizeof(snd_seq_event_t)); | ||||
| midi_event->type = extMidiNotes[i].onoff ? SND_SEQ_EVENT_NOTEON : SND_SEQ_EVENT_NOTEOFF; | |||||
| midi_event->type = extMidiNotes[i].onoff ? SND_SEQ_EVENT_NOTEON : SND_SEQ_EVENT_NOTEOFF; | |||||
| midi_event->time.tick = nframesOffset; // FIXME - other types may also need time-check here | |||||
| midi_event->data.note.channel = cin_channel; | midi_event->data.note.channel = cin_channel; | ||||
| midi_event->data.note.note = extMidiNotes[i].note; | midi_event->data.note.note = extMidiNotes[i].note; | ||||
| midi_event->data.note.velocity = extMidiNotes[i].velo; | midi_event->data.note.velocity = extMidiNotes[i].velo; | ||||
| @@ -82,9 +82,9 @@ public: | |||||
| { | { | ||||
| switch (param_id) | switch (param_id) | ||||
| { | { | ||||
| case Sf2ChorusType: | |||||
| case FluidSynthChorusType: | |||||
| return 2; | return 2; | ||||
| case Sf2Interpolation: | |||||
| case FluidSynthInterpolation: | |||||
| return 4; | return 4; | ||||
| default: | default: | ||||
| return 0; | return 0; | ||||
| @@ -103,7 +103,7 @@ public: | |||||
| { | { | ||||
| switch (param_id) | switch (param_id) | ||||
| { | { | ||||
| case Sf2ChorusType: | |||||
| case FluidSynthChorusType: | |||||
| switch (scalepoint_id) | switch (scalepoint_id) | ||||
| { | { | ||||
| case 0: | case 0: | ||||
| @@ -113,7 +113,7 @@ public: | |||||
| default: | default: | ||||
| return FLUID_CHORUS_DEFAULT_TYPE; | return FLUID_CHORUS_DEFAULT_TYPE; | ||||
| } | } | ||||
| case Sf2Interpolation: | |||||
| case FluidSynthInterpolation: | |||||
| switch (scalepoint_id) | switch (scalepoint_id) | ||||
| { | { | ||||
| case 0: | case 0: | ||||
| @@ -156,46 +156,46 @@ public: | |||||
| { | { | ||||
| switch (param_id) | switch (param_id) | ||||
| { | { | ||||
| case Sf2ReverbOnOff: | |||||
| case FluidSynthReverbOnOff: | |||||
| strncpy(buf_str, "Reverb On/Off", STR_MAX); | strncpy(buf_str, "Reverb On/Off", STR_MAX); | ||||
| break; | break; | ||||
| case Sf2ReverbRoomSize: | |||||
| case FluidSynthReverbRoomSize: | |||||
| strncpy(buf_str, "Reverb Room Size", STR_MAX); | strncpy(buf_str, "Reverb Room Size", STR_MAX); | ||||
| break; | break; | ||||
| case Sf2ReverbDamp: | |||||
| case FluidSynthReverbDamp: | |||||
| strncpy(buf_str, "Reverb Damp", STR_MAX); | strncpy(buf_str, "Reverb Damp", STR_MAX); | ||||
| break; | break; | ||||
| case Sf2ReverbLevel: | |||||
| case FluidSynthReverbLevel: | |||||
| strncpy(buf_str, "Reverb Level", STR_MAX); | strncpy(buf_str, "Reverb Level", STR_MAX); | ||||
| break; | break; | ||||
| case Sf2ReverbWidth: | |||||
| case FluidSynthReverbWidth: | |||||
| strncpy(buf_str, "Reverb Width", STR_MAX); | strncpy(buf_str, "Reverb Width", STR_MAX); | ||||
| break; | break; | ||||
| case Sf2ChorusOnOff: | |||||
| case FluidSynthChorusOnOff: | |||||
| strncpy(buf_str, "Chorus On/Off", STR_MAX); | strncpy(buf_str, "Chorus On/Off", STR_MAX); | ||||
| break; | break; | ||||
| case Sf2ChorusNr: | |||||
| case FluidSynthChorusNr: | |||||
| strncpy(buf_str, "Chorus Voice Count", STR_MAX); | strncpy(buf_str, "Chorus Voice Count", STR_MAX); | ||||
| break; | break; | ||||
| case Sf2ChorusLevel: | |||||
| case FluidSynthChorusLevel: | |||||
| strncpy(buf_str, "Chorus Level", STR_MAX); | strncpy(buf_str, "Chorus Level", STR_MAX); | ||||
| break; | break; | ||||
| case Sf2ChorusSpeedHz: | |||||
| case FluidSynthChorusSpeedHz: | |||||
| strncpy(buf_str, "Chorus Speed", STR_MAX); | strncpy(buf_str, "Chorus Speed", STR_MAX); | ||||
| break; | break; | ||||
| case Sf2ChorusDepthMs: | |||||
| case FluidSynthChorusDepthMs: | |||||
| strncpy(buf_str, "Chorus Depth", STR_MAX); | strncpy(buf_str, "Chorus Depth", STR_MAX); | ||||
| break; | break; | ||||
| case Sf2ChorusType: | |||||
| case FluidSynthChorusType: | |||||
| strncpy(buf_str, "Chorus Type", STR_MAX); | strncpy(buf_str, "Chorus Type", STR_MAX); | ||||
| break; | break; | ||||
| case Sf2Polyphony: | |||||
| case FluidSynthPolyphony: | |||||
| strncpy(buf_str, "Polyphony", STR_MAX); | strncpy(buf_str, "Polyphony", STR_MAX); | ||||
| break; | break; | ||||
| case Sf2Interpolation: | |||||
| case FluidSynthInterpolation: | |||||
| strncpy(buf_str, "Interpolation", STR_MAX); | strncpy(buf_str, "Interpolation", STR_MAX); | ||||
| break; | break; | ||||
| case Sf2VoiceCount: | |||||
| case FluidSynthVoiceCount: | |||||
| strncpy(buf_str, "Voice Count", STR_MAX); | strncpy(buf_str, "Voice Count", STR_MAX); | ||||
| break; | break; | ||||
| default: | default: | ||||
| @@ -208,10 +208,10 @@ public: | |||||
| { | { | ||||
| switch (param_id) | switch (param_id) | ||||
| { | { | ||||
| case Sf2ChorusSpeedHz: | |||||
| case FluidSynthChorusSpeedHz: | |||||
| strncpy(buf_str, "Hz", STR_MAX); | strncpy(buf_str, "Hz", STR_MAX); | ||||
| break; | break; | ||||
| case Sf2ChorusDepthMs: | |||||
| case FluidSynthChorusDepthMs: | |||||
| strncpy(buf_str, "ms", STR_MAX); | strncpy(buf_str, "ms", STR_MAX); | ||||
| break; | break; | ||||
| default: | default: | ||||
| @@ -224,7 +224,7 @@ public: | |||||
| { | { | ||||
| switch (param_id) | switch (param_id) | ||||
| { | { | ||||
| case Sf2ChorusType: | |||||
| case FluidSynthChorusType: | |||||
| switch (scalepoint_id) | switch (scalepoint_id) | ||||
| { | { | ||||
| case 0: | case 0: | ||||
| @@ -234,7 +234,7 @@ public: | |||||
| strncpy(buf_str, "Triangle wave", STR_MAX); | strncpy(buf_str, "Triangle wave", STR_MAX); | ||||
| return; | return; | ||||
| } | } | ||||
| case Sf2Interpolation: | |||||
| case FluidSynthInterpolation: | |||||
| switch (scalepoint_id) | switch (scalepoint_id) | ||||
| { | { | ||||
| case 0: | case 0: | ||||
| @@ -263,19 +263,19 @@ public: | |||||
| switch(param_id) | switch(param_id) | ||||
| { | { | ||||
| case Sf2ReverbOnOff: | |||||
| case FluidSynthReverbOnOff: | |||||
| value = value > 0.5 ? 1 : 0; | value = value > 0.5 ? 1 : 0; | ||||
| fluid_synth_set_reverb_on(f_synth, value); | fluid_synth_set_reverb_on(f_synth, value); | ||||
| break; | break; | ||||
| case Sf2ReverbRoomSize: | |||||
| case Sf2ReverbDamp: | |||||
| case Sf2ReverbLevel: | |||||
| case Sf2ReverbWidth: | |||||
| fluid_synth_set_reverb(f_synth, param_buffers[Sf2ReverbRoomSize], param_buffers[Sf2ReverbDamp], param_buffers[Sf2ReverbWidth], param_buffers[Sf2ReverbLevel]); | |||||
| case FluidSynthReverbRoomSize: | |||||
| case FluidSynthReverbDamp: | |||||
| case FluidSynthReverbLevel: | |||||
| case FluidSynthReverbWidth: | |||||
| fluid_synth_set_reverb(f_synth, param_buffers[FluidSynthReverbRoomSize], param_buffers[FluidSynthReverbDamp], param_buffers[FluidSynthReverbWidth], param_buffers[FluidSynthReverbLevel]); | |||||
| break; | break; | ||||
| case Sf2ChorusOnOff: | |||||
| case FluidSynthChorusOnOff: | |||||
| { | { | ||||
| const CarlaPluginScopedDisabler m(this, ! CarlaEngine::isOffline()); | const CarlaPluginScopedDisabler m(this, ! CarlaEngine::isOffline()); | ||||
| value = value > 0.5 ? 1 : 0; | value = value > 0.5 ? 1 : 0; | ||||
| @@ -283,25 +283,25 @@ public: | |||||
| break; | break; | ||||
| } | } | ||||
| case Sf2ChorusNr: | |||||
| case Sf2ChorusLevel: | |||||
| case Sf2ChorusSpeedHz: | |||||
| case Sf2ChorusDepthMs: | |||||
| case Sf2ChorusType: | |||||
| case FluidSynthChorusNr: | |||||
| case FluidSynthChorusLevel: | |||||
| case FluidSynthChorusSpeedHz: | |||||
| case FluidSynthChorusDepthMs: | |||||
| case FluidSynthChorusType: | |||||
| { | { | ||||
| const CarlaPluginScopedDisabler m(this, ! CarlaEngine::isOffline()); | const CarlaPluginScopedDisabler m(this, ! CarlaEngine::isOffline()); | ||||
| fluid_synth_set_chorus(f_synth, rint(param_buffers[Sf2ChorusNr]), param_buffers[Sf2ChorusLevel], param_buffers[Sf2ChorusSpeedHz], param_buffers[Sf2ChorusDepthMs], rint(param_buffers[Sf2ChorusType])); | |||||
| fluid_synth_set_chorus(f_synth, rint(param_buffers[FluidSynthChorusNr]), param_buffers[FluidSynthChorusLevel], param_buffers[FluidSynthChorusSpeedHz], param_buffers[FluidSynthChorusDepthMs], rint(param_buffers[FluidSynthChorusType])); | |||||
| break; | break; | ||||
| } | } | ||||
| case Sf2Polyphony: | |||||
| case FluidSynthPolyphony: | |||||
| { | { | ||||
| const CarlaPluginScopedDisabler m(this, ! CarlaEngine::isOffline()); | const CarlaPluginScopedDisabler m(this, ! CarlaEngine::isOffline()); | ||||
| fluid_synth_set_polyphony(f_synth, rint(value)); | fluid_synth_set_polyphony(f_synth, rint(value)); | ||||
| break; | break; | ||||
| } | } | ||||
| case Sf2Interpolation: | |||||
| case FluidSynthInterpolation: | |||||
| { | { | ||||
| const CarlaPluginScopedDisabler m(this, ! CarlaEngine::isOffline()); | const CarlaPluginScopedDisabler m(this, ! CarlaEngine::isOffline()); | ||||
| for (int i=0; i < 16; i++) | for (int i=0; i < 16; i++) | ||||
| @@ -360,7 +360,7 @@ public: | |||||
| uint32_t aouts, params, j; | uint32_t aouts, params, j; | ||||
| aouts = 2; | aouts = 2; | ||||
| params = Sf2ParametersMax; | |||||
| params = FluidSynthParametersMax; | |||||
| aout.ports = new CarlaEngineAudioPort*[aouts]; | aout.ports = new CarlaEngineAudioPort*[aouts]; | ||||
| aout.rindexes = new uint32_t[aouts]; | aout.rindexes = new uint32_t[aouts]; | ||||
| @@ -443,7 +443,7 @@ public: | |||||
| param.port_cout = (CarlaEngineControlPort*)x_client->addPort(port_name, CarlaEnginePortTypeControl, false); | param.port_cout = (CarlaEngineControlPort*)x_client->addPort(port_name, CarlaEnginePortTypeControl, false); | ||||
| // ---------------------- | // ---------------------- | ||||
| j = Sf2ReverbOnOff; | |||||
| j = FluidSynthReverbOnOff; | |||||
| param.data[j].index = j; | param.data[j].index = j; | ||||
| param.data[j].rindex = j; | param.data[j].rindex = j; | ||||
| param.data[j].type = PARAMETER_INPUT; | param.data[j].type = PARAMETER_INPUT; | ||||
| @@ -459,7 +459,7 @@ public: | |||||
| param_buffers[j] = param.ranges[j].def; | param_buffers[j] = param.ranges[j].def; | ||||
| // ---------------------- | // ---------------------- | ||||
| j = Sf2ReverbRoomSize; | |||||
| j = FluidSynthReverbRoomSize; | |||||
| param.data[j].index = j; | param.data[j].index = j; | ||||
| param.data[j].rindex = j; | param.data[j].rindex = j; | ||||
| param.data[j].type = PARAMETER_INPUT; | param.data[j].type = PARAMETER_INPUT; | ||||
| @@ -475,7 +475,7 @@ public: | |||||
| param_buffers[j] = param.ranges[j].def; | param_buffers[j] = param.ranges[j].def; | ||||
| // ---------------------- | // ---------------------- | ||||
| j = Sf2ReverbDamp; | |||||
| j = FluidSynthReverbDamp; | |||||
| param.data[j].index = j; | param.data[j].index = j; | ||||
| param.data[j].rindex = j; | param.data[j].rindex = j; | ||||
| param.data[j].type = PARAMETER_INPUT; | param.data[j].type = PARAMETER_INPUT; | ||||
| @@ -491,7 +491,7 @@ public: | |||||
| param_buffers[j] = param.ranges[j].def; | param_buffers[j] = param.ranges[j].def; | ||||
| // ---------------------- | // ---------------------- | ||||
| j = Sf2ReverbLevel; | |||||
| j = FluidSynthReverbLevel; | |||||
| param.data[j].index = j; | param.data[j].index = j; | ||||
| param.data[j].rindex = j; | param.data[j].rindex = j; | ||||
| param.data[j].type = PARAMETER_INPUT; | param.data[j].type = PARAMETER_INPUT; | ||||
| @@ -507,7 +507,7 @@ public: | |||||
| param_buffers[j] = param.ranges[j].def; | param_buffers[j] = param.ranges[j].def; | ||||
| // ---------------------- | // ---------------------- | ||||
| j = Sf2ReverbWidth; | |||||
| j = FluidSynthReverbWidth; | |||||
| param.data[j].index = j; | param.data[j].index = j; | ||||
| param.data[j].rindex = j; | param.data[j].rindex = j; | ||||
| param.data[j].type = PARAMETER_INPUT; | param.data[j].type = PARAMETER_INPUT; | ||||
| @@ -523,7 +523,7 @@ public: | |||||
| param_buffers[j] = param.ranges[j].def; | param_buffers[j] = param.ranges[j].def; | ||||
| // ---------------------- | // ---------------------- | ||||
| j = Sf2ChorusOnOff; | |||||
| j = FluidSynthChorusOnOff; | |||||
| param.data[j].index = j; | param.data[j].index = j; | ||||
| param.data[j].rindex = j; | param.data[j].rindex = j; | ||||
| param.data[j].type = PARAMETER_INPUT; | param.data[j].type = PARAMETER_INPUT; | ||||
| @@ -539,7 +539,7 @@ public: | |||||
| param_buffers[j] = param.ranges[j].def; | param_buffers[j] = param.ranges[j].def; | ||||
| // ---------------------- | // ---------------------- | ||||
| j = Sf2ChorusNr; | |||||
| j = FluidSynthChorusNr; | |||||
| param.data[j].index = j; | param.data[j].index = j; | ||||
| param.data[j].rindex = j; | param.data[j].rindex = j; | ||||
| param.data[j].type = PARAMETER_INPUT; | param.data[j].type = PARAMETER_INPUT; | ||||
| @@ -555,7 +555,7 @@ public: | |||||
| param_buffers[j] = param.ranges[j].def; | param_buffers[j] = param.ranges[j].def; | ||||
| // ---------------------- | // ---------------------- | ||||
| j = Sf2ChorusLevel; | |||||
| j = FluidSynthChorusLevel; | |||||
| param.data[j].index = j; | param.data[j].index = j; | ||||
| param.data[j].rindex = j; | param.data[j].rindex = j; | ||||
| param.data[j].type = PARAMETER_INPUT; | param.data[j].type = PARAMETER_INPUT; | ||||
| @@ -571,7 +571,7 @@ public: | |||||
| param_buffers[j] = param.ranges[j].def; | param_buffers[j] = param.ranges[j].def; | ||||
| // ---------------------- | // ---------------------- | ||||
| j = Sf2ChorusSpeedHz; | |||||
| j = FluidSynthChorusSpeedHz; | |||||
| param.data[j].index = j; | param.data[j].index = j; | ||||
| param.data[j].rindex = j; | param.data[j].rindex = j; | ||||
| param.data[j].type = PARAMETER_INPUT; | param.data[j].type = PARAMETER_INPUT; | ||||
| @@ -587,7 +587,7 @@ public: | |||||
| param_buffers[j] = param.ranges[j].def; | param_buffers[j] = param.ranges[j].def; | ||||
| // ---------------------- | // ---------------------- | ||||
| j = Sf2ChorusDepthMs; | |||||
| j = FluidSynthChorusDepthMs; | |||||
| param.data[j].index = j; | param.data[j].index = j; | ||||
| param.data[j].rindex = j; | param.data[j].rindex = j; | ||||
| param.data[j].type = PARAMETER_INPUT; | param.data[j].type = PARAMETER_INPUT; | ||||
| @@ -603,7 +603,7 @@ public: | |||||
| param_buffers[j] = param.ranges[j].def; | param_buffers[j] = param.ranges[j].def; | ||||
| // ---------------------- | // ---------------------- | ||||
| j = Sf2ChorusType; | |||||
| j = FluidSynthChorusType; | |||||
| param.data[j].index = j; | param.data[j].index = j; | ||||
| param.data[j].rindex = j; | param.data[j].rindex = j; | ||||
| param.data[j].type = PARAMETER_INPUT; | param.data[j].type = PARAMETER_INPUT; | ||||
| @@ -619,7 +619,7 @@ public: | |||||
| param_buffers[j] = param.ranges[j].def; | param_buffers[j] = param.ranges[j].def; | ||||
| // ---------------------- | // ---------------------- | ||||
| j = Sf2Polyphony; | |||||
| j = FluidSynthPolyphony; | |||||
| param.data[j].index = j; | param.data[j].index = j; | ||||
| param.data[j].rindex = j; | param.data[j].rindex = j; | ||||
| param.data[j].type = PARAMETER_INPUT; | param.data[j].type = PARAMETER_INPUT; | ||||
| @@ -635,7 +635,7 @@ public: | |||||
| param_buffers[j] = param.ranges[j].def; | param_buffers[j] = param.ranges[j].def; | ||||
| // ---------------------- | // ---------------------- | ||||
| j = Sf2Interpolation; | |||||
| j = FluidSynthInterpolation; | |||||
| param.data[j].index = j; | param.data[j].index = j; | ||||
| param.data[j].rindex = j; | param.data[j].rindex = j; | ||||
| param.data[j].type = PARAMETER_INPUT; | param.data[j].type = PARAMETER_INPUT; | ||||
| @@ -651,7 +651,7 @@ public: | |||||
| param_buffers[j] = param.ranges[j].def; | param_buffers[j] = param.ranges[j].def; | ||||
| // ---------------------- | // ---------------------- | ||||
| j = Sf2VoiceCount; | |||||
| j = FluidSynthVoiceCount; | |||||
| param.data[j].index = j; | param.data[j].index = j; | ||||
| param.data[j].rindex = j; | param.data[j].rindex = j; | ||||
| param.data[j].type = PARAMETER_OUTPUT; | param.data[j].type = PARAMETER_OUTPUT; | ||||
| @@ -743,27 +743,24 @@ public: | |||||
| callback_action(CALLBACK_RELOAD_PROGRAMS, m_id, 0, 0, 0.0); | callback_action(CALLBACK_RELOAD_PROGRAMS, m_id, 0, 0, 0.0); | ||||
| #endif | #endif | ||||
| if (init) | |||||
| if (init && midiprog.count > 0) | |||||
| { | { | ||||
| if (midiprog.count > 0) | |||||
| { | |||||
| fluid_synth_program_reset(f_synth); | |||||
| fluid_synth_program_reset(f_synth); | |||||
| for (i=0; i < 16 && i != 9; i++) | |||||
| { | |||||
| for (i=0; i < 16 && i != 9; i++) | |||||
| { | |||||
| #ifdef FLUIDSYNTH_VERSION_NEW_API | #ifdef FLUIDSYNTH_VERSION_NEW_API | ||||
| fluid_synth_set_channel_type(f_synth, i, CHANNEL_TYPE_MELODIC); | |||||
| fluid_synth_set_channel_type(f_synth, i, CHANNEL_TYPE_MELODIC); | |||||
| #endif | #endif | ||||
| fluid_synth_program_select(f_synth, i, f_id, midiprog.data[0].bank, midiprog.data[0].program); | |||||
| } | |||||
| fluid_synth_program_select(f_synth, i, f_id, midiprog.data[0].bank, midiprog.data[0].program); | |||||
| } | |||||
| #ifdef FLUIDSYNTH_VERSION_NEW_API | #ifdef FLUIDSYNTH_VERSION_NEW_API | ||||
| fluid_synth_set_channel_type(f_synth, 9, CHANNEL_TYPE_DRUM); | |||||
| fluid_synth_set_channel_type(f_synth, 9, CHANNEL_TYPE_DRUM); | |||||
| #endif | #endif | ||||
| fluid_synth_program_select(f_synth, 9, f_id, 128, 0); | |||||
| fluid_synth_program_select(f_synth, 9, f_id, 128, 0); | |||||
| set_midi_program(0, false, false, false, true); | |||||
| } | |||||
| set_midi_program(0, false, false, false, true); | |||||
| } | } | ||||
| } | } | ||||
| @@ -773,7 +770,7 @@ public: | |||||
| void process(float** ains_buffer, float** aouts_buffer, uint32_t nframes, uint32_t nframesOffset) | void process(float** ains_buffer, float** aouts_buffer, uint32_t nframes, uint32_t nframesOffset) | ||||
| { | { | ||||
| uint32_t i, k; | uint32_t i, k; | ||||
| unsigned int midi_event_count = 0; | |||||
| uint32_t midi_event_count = 0; | |||||
| double aouts_peak_tmp[2] = { 0.0 }; | double aouts_peak_tmp[2] = { 0.0 }; | ||||
| @@ -1154,7 +1151,7 @@ public: | |||||
| if (nframesOffset == 0 || ! m_active_before) | if (nframesOffset == 0 || ! m_active_before) | ||||
| param.port_cout->initBuffer(cout_buffer); | param.port_cout->initBuffer(cout_buffer); | ||||
| k = Sf2VoiceCount; | |||||
| k = FluidSynthVoiceCount; | |||||
| param_buffers[k] = rint(fluid_synth_get_active_voice_count(f_synth)); | param_buffers[k] = rint(fluid_synth_get_active_voice_count(f_synth)); | ||||
| fix_parameter_value(param_buffers[k], param.ranges[k]); | fix_parameter_value(param_buffers[k], param.ranges[k]); | ||||
| @@ -1199,29 +1196,29 @@ public: | |||||
| } | } | ||||
| private: | private: | ||||
| enum Sf2InputParameters { | |||||
| Sf2ReverbOnOff = 0, | |||||
| Sf2ReverbRoomSize = 1, | |||||
| Sf2ReverbDamp = 2, | |||||
| Sf2ReverbLevel = 3, | |||||
| Sf2ReverbWidth = 4, | |||||
| Sf2ChorusOnOff = 5, | |||||
| Sf2ChorusNr = 6, | |||||
| Sf2ChorusLevel = 7, | |||||
| Sf2ChorusSpeedHz = 8, | |||||
| Sf2ChorusDepthMs = 9, | |||||
| Sf2ChorusType = 10, | |||||
| Sf2Polyphony = 11, | |||||
| Sf2Interpolation = 12, | |||||
| Sf2VoiceCount = 13, | |||||
| Sf2ParametersMax = 14 | |||||
| enum FluidSynthInputParameters { | |||||
| FluidSynthReverbOnOff = 0, | |||||
| FluidSynthReverbRoomSize = 1, | |||||
| FluidSynthReverbDamp = 2, | |||||
| FluidSynthReverbLevel = 3, | |||||
| FluidSynthReverbWidth = 4, | |||||
| FluidSynthChorusOnOff = 5, | |||||
| FluidSynthChorusNr = 6, | |||||
| FluidSynthChorusLevel = 7, | |||||
| FluidSynthChorusSpeedHz = 8, | |||||
| FluidSynthChorusDepthMs = 9, | |||||
| FluidSynthChorusType = 10, | |||||
| FluidSynthPolyphony = 11, | |||||
| FluidSynthInterpolation = 12, | |||||
| FluidSynthVoiceCount = 13, | |||||
| FluidSynthParametersMax = 14 | |||||
| }; | }; | ||||
| fluid_settings_t* f_settings; | fluid_settings_t* f_settings; | ||||
| fluid_synth_t* f_synth; | fluid_synth_t* f_synth; | ||||
| int f_id; | int f_id; | ||||
| double param_buffers[Sf2ParametersMax]; | |||||
| double param_buffers[FluidSynthParametersMax]; | |||||
| const char* m_label; | const char* m_label; | ||||
| }; | }; | ||||
| @@ -21,12 +21,124 @@ | |||||
| #include "carla_plugin.h" | #include "carla_plugin.h" | ||||
| #include <linuxsampler/Sampler.h> | |||||
| #include "linuxsampler/EngineFactory.h" | |||||
| #include <QtCore/QFileInfo> | |||||
| CARLA_BACKEND_START_NAMESPACE | CARLA_BACKEND_START_NAMESPACE | ||||
| #if 0 | #if 0 | ||||
| } /* adjust editor indent */ | } /* adjust editor indent */ | ||||
| #endif | #endif | ||||
| #define LINUXSAMPLER_VOLUME_MAX 3.16227766f // +10 dB | |||||
| #define LINUXSAMPLER_VOLUME_MIN 0.0f // -inf dB | |||||
| class AudioOutputDevicePlugin : public LinuxSampler::AudioOutputDevice | |||||
| { | |||||
| public: | |||||
| AudioOutputDevicePlugin(CarlaPlugin* plugin) : | |||||
| AudioOutputDevice(std::map<String,LinuxSampler::DeviceCreationParameter*>()), | |||||
| m_plugin(plugin) | |||||
| { | |||||
| } | |||||
| // ------------------------------------------------------------------- | |||||
| // LinuxSampler virtual methods | |||||
| void Play() | |||||
| { | |||||
| } | |||||
| bool IsPlaying() | |||||
| { | |||||
| return m_plugin && m_plugin->enabled(); | |||||
| } | |||||
| void Stop() | |||||
| { | |||||
| } | |||||
| uint MaxSamplesPerCycle() | |||||
| { | |||||
| return get_buffer_size(); | |||||
| } | |||||
| uint SampleRate() | |||||
| { | |||||
| return get_sample_rate(); | |||||
| } | |||||
| String Driver() | |||||
| { | |||||
| return "AudioOutputDevicePlugin"; | |||||
| } | |||||
| LinuxSampler::AudioChannel* CreateChannel(uint channelNr) | |||||
| { | |||||
| return new LinuxSampler::AudioChannel(channelNr, nullptr, 0); | |||||
| } | |||||
| // ------------------------------------------------------------------- | |||||
| int Render(uint samples) | |||||
| { | |||||
| return RenderAudio(samples); | |||||
| } | |||||
| private: | |||||
| CarlaPlugin* m_plugin; | |||||
| }; | |||||
| class MidiInputDevicePlugin : public LinuxSampler::MidiInputDevice | |||||
| { | |||||
| public: | |||||
| MidiInputDevicePlugin(LinuxSampler::Sampler* sampler) : LinuxSampler::MidiInputDevice(std::map<String, LinuxSampler::DeviceCreationParameter*>(), sampler) | |||||
| { | |||||
| } | |||||
| // ------------------------------------------------------------------- | |||||
| // MIDI Port implementation for this plugin MIDI input driver | |||||
| class MidiInputPortPlugin : public LinuxSampler::MidiInputPort | |||||
| { | |||||
| protected: | |||||
| MidiInputPortPlugin(MidiInputDevicePlugin* device, int portNumber) : LinuxSampler::MidiInputPort(device, portNumber) | |||||
| { | |||||
| } | |||||
| friend class MidiInputDevicePlugin; | |||||
| }; | |||||
| // ------------------------------------------------------------------- | |||||
| // LinuxSampler virtual methods | |||||
| void Listen() | |||||
| { | |||||
| } | |||||
| void StopListen() | |||||
| { | |||||
| } | |||||
| String Driver() | |||||
| { | |||||
| return "MidiInputDevicePlugin"; | |||||
| } | |||||
| LinuxSampler::MidiInputPort* CreateMidiPort() | |||||
| { | |||||
| return new MidiInputPortPlugin(this, Ports.size()); | |||||
| } | |||||
| // ------------------------------------------------------------------- | |||||
| void DeleteMidiPort(LinuxSampler::MidiInputPort* port) | |||||
| { | |||||
| delete (MidiInputPortPlugin*)port; | |||||
| } | |||||
| }; | |||||
| class LinuxSamplerPlugin : public CarlaPlugin | class LinuxSamplerPlugin : public CarlaPlugin | ||||
| { | { | ||||
| public: | public: | ||||
| @@ -35,15 +147,42 @@ public: | |||||
| qDebug("LinuxSamplerPlugin::LinuxSamplerPlugin()"); | qDebug("LinuxSamplerPlugin::LinuxSamplerPlugin()"); | ||||
| m_type = isGIG ? PLUGIN_GIG : PLUGIN_SFZ; | m_type = isGIG ? PLUGIN_GIG : PLUGIN_SFZ; | ||||
| sampler = new LinuxSampler::Sampler; | |||||
| audioOutputDevice = new AudioOutputDevicePlugin(this); | |||||
| midiInputDevice = new MidiInputDevicePlugin(sampler); | |||||
| midiInputPort = midiInputDevice->CreateMidiPort(); | |||||
| m_isGIG = isGIG; | |||||
| m_name = nullptr; | |||||
| m_label = nullptr; | m_label = nullptr; | ||||
| m_maker = nullptr; | |||||
| } | } | ||||
| ~LinuxSamplerPlugin() | ~LinuxSamplerPlugin() | ||||
| { | { | ||||
| qDebug("LinuxSamplerPlugin::~LinuxSamplerPlugin()"); | qDebug("LinuxSamplerPlugin::~LinuxSamplerPlugin()"); | ||||
| if (sampler_channel) | |||||
| { | |||||
| midiInputPort->Disconnect(sampler_channel->GetEngineChannel()); | |||||
| sampler->RemoveSamplerChannel(sampler_channel); | |||||
| } | |||||
| midiInputDevice->DeleteMidiPort(midiInputPort); | |||||
| delete audioOutputDevice; | |||||
| delete midiInputDevice; | |||||
| delete sampler; | |||||
| if (m_name) | |||||
| free((void*)m_name); | |||||
| if (m_label) | if (m_label) | ||||
| free((void*)m_label); | free((void*)m_label); | ||||
| if (m_maker) | |||||
| free((void*)m_maker); | |||||
| } | } | ||||
| // ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
| @@ -54,24 +193,466 @@ public: | |||||
| return PLUGIN_CATEGORY_SYNTH; | return PLUGIN_CATEGORY_SYNTH; | ||||
| } | } | ||||
| // ------------------------------------------------------------------- | |||||
| // Information (per-plugin data) | |||||
| void get_label(char* buf_str) | |||||
| { | |||||
| strncpy(buf_str, m_label, STR_MAX); | |||||
| } | |||||
| void get_maker(char* buf_str) | |||||
| { | |||||
| strncpy(buf_str, m_maker, STR_MAX); | |||||
| } | |||||
| void get_copyright(char* buf_str) | |||||
| { | |||||
| strncpy(buf_str, m_maker, STR_MAX); | |||||
| } | |||||
| void get_real_name(char* buf_str) | |||||
| { | |||||
| strncpy(buf_str, m_name, STR_MAX); | |||||
| } | |||||
| // ------------------------------------------------------------------- | |||||
| // Plugin state | |||||
| void reload() | |||||
| { | |||||
| qDebug("LinuxSamplerPlugin::reload() - start"); | |||||
| // Safely disable plugin for reload | |||||
| const CarlaPluginScopedDisabler m(this); | |||||
| if (x_client->isActive()) | |||||
| x_client->deactivate(); | |||||
| // Remove client ports | |||||
| remove_client_ports(); | |||||
| // Delete old data | |||||
| delete_buffers(); | |||||
| uint32_t aouts; | |||||
| aouts = 2; | |||||
| aout.ports = new CarlaEngineAudioPort*[aouts]; | |||||
| aout.rindexes = new uint32_t[aouts]; | |||||
| const int port_name_size = CarlaEngine::maxPortNameSize() - 1; | |||||
| char port_name[port_name_size]; | |||||
| // --------------------------------------- | |||||
| // Audio Outputs | |||||
| #ifndef BUILD_BRIDGE | |||||
| if (carla_options.global_jack_client) | |||||
| { | |||||
| strcpy(port_name, m_name); | |||||
| strcat(port_name, ":out-left"); | |||||
| } | |||||
| else | |||||
| #endif | |||||
| strcpy(port_name, "out-left"); | |||||
| aout.ports[0] = (CarlaEngineAudioPort*)x_client->addPort(port_name, CarlaEnginePortTypeAudio, false); | |||||
| aout.rindexes[0] = 0; | |||||
| #ifndef BUILD_BRIDGE | |||||
| if (carla_options.global_jack_client) | |||||
| { | |||||
| strcpy(port_name, m_name); | |||||
| strcat(port_name, ":out-right"); | |||||
| } | |||||
| else | |||||
| #endif | |||||
| strcpy(port_name, "out-right"); | |||||
| aout.ports[1] = (CarlaEngineAudioPort*)x_client->addPort(port_name, CarlaEnginePortTypeAudio, false); | |||||
| aout.rindexes[1] = 1; | |||||
| // --------------------------------------- | |||||
| // MIDI Input | |||||
| #ifndef BUILD_BRIDGE | |||||
| if (carla_options.global_jack_client) | |||||
| { | |||||
| strcpy(port_name, m_name); | |||||
| strcat(port_name, ":midi-in"); | |||||
| } | |||||
| else | |||||
| #endif | |||||
| strcpy(port_name, "midi-in"); | |||||
| midi.port_min = (CarlaEngineMidiPort*)x_client->addPort(port_name, CarlaEnginePortTypeMIDI, true); | |||||
| // --------------------------------------- | |||||
| aout.count = aouts; | |||||
| // plugin checks | |||||
| m_hints &= ~(PLUGIN_IS_SYNTH | PLUGIN_USES_CHUNKS | PLUGIN_CAN_DRYWET | PLUGIN_CAN_VOLUME | PLUGIN_CAN_BALANCE); | |||||
| m_hints |= PLUGIN_IS_SYNTH; | |||||
| m_hints |= PLUGIN_CAN_VOLUME; | |||||
| m_hints |= PLUGIN_CAN_BALANCE; | |||||
| reload_programs(true); | |||||
| x_client->activate(); | |||||
| qDebug("LinuxSamplerPlugin::reload() - end"); | |||||
| } | |||||
| void reload_programs(bool init) | |||||
| { | |||||
| qDebug("LinuxSamplerPlugin::reload_programs(%s)", bool2str(init)); | |||||
| // Delete old programs | |||||
| if (midiprog.count > 0) | |||||
| { | |||||
| for (uint32_t i=0; i < midiprog.count; i++) | |||||
| free((void*)midiprog.data[i].name); | |||||
| delete[] midiprog.data; | |||||
| } | |||||
| midiprog.count = 0; | |||||
| midiprog.data = nullptr; | |||||
| // Query new programs | |||||
| uint32_t i = 0; | |||||
| midiprog.count += instrumentIds.size(); | |||||
| if (midiprog.count > 0) | |||||
| midiprog.data = new midi_program_t [midiprog.count]; | |||||
| // Update data | |||||
| for (i=0; i < midiprog.count; i++) | |||||
| { | |||||
| LinuxSampler::InstrumentManager::instrument_info_t info = instrument->GetInstrumentInfo(instrumentIds[i]); | |||||
| midiprog.data[i].bank = 0; | |||||
| midiprog.data[i].program = i; | |||||
| midiprog.data[i].name = strdup(info.InstrumentName.c_str()); | |||||
| } | |||||
| #ifndef BUILD_BRIDGE | |||||
| // Update OSC Names | |||||
| osc_global_send_set_midi_program_count(m_id, midiprog.count); | |||||
| for (i=0; i < midiprog.count; i++) | |||||
| osc_global_send_set_midi_program_data(m_id, i, midiprog.data[i].bank, midiprog.data[i].program, midiprog.data[i].name); | |||||
| callback_action(CALLBACK_RELOAD_PROGRAMS, m_id, 0, 0, 0.0); | |||||
| #endif | |||||
| if (init && midiprog.count > 0) | |||||
| { | |||||
| set_midi_program(0, false, false, false, true); | |||||
| } | |||||
| } | |||||
| // ------------------------------------------------------------------- | |||||
| // Plugin processing | |||||
| void process(float** ains_buffer, float** aouts_buffer, uint32_t nframes, uint32_t nframesOffset = 0) | |||||
| { | |||||
| uint32_t i, k; | |||||
| uint32_t midi_event_count = 0; | |||||
| double aouts_peak_tmp[2] = { 0.0 }; | |||||
| CARLA_PROCESS_CONTINUE_CHECK; | |||||
| // -------------------------------------------------------------------------------------------------------- | |||||
| // MIDI Input (External) | |||||
| if (cin_channel >= 0 && cin_channel < 16 && m_active && m_active_before) | |||||
| { | |||||
| carla_midi_lock(); | |||||
| for (i=0; i < MAX_MIDI_EVENTS && midi_event_count < MAX_MIDI_EVENTS; i++) | |||||
| { | |||||
| if (extMidiNotes[i].valid) | |||||
| { | |||||
| if (extMidiNotes[i].onoff) | |||||
| midiInputPort->DispatchNoteOn(extMidiNotes[i].note, extMidiNotes[i].velo, cin_channel, nframesOffset); | |||||
| else | |||||
| midiInputPort->DispatchNoteOff(extMidiNotes[i].note, extMidiNotes[i].velo, cin_channel, nframesOffset); | |||||
| extMidiNotes[i].valid = false; | |||||
| midi_event_count += 1; | |||||
| } | |||||
| else | |||||
| break; | |||||
| } | |||||
| carla_midi_unlock(); | |||||
| } // End of MIDI Input (External) | |||||
| CARLA_PROCESS_CONTINUE_CHECK; | |||||
| // -------------------------------------------------------------------------------------------------------- | |||||
| // MIDI Input (System) | |||||
| if (m_active && m_active_before) | |||||
| { | |||||
| void* min_buffer = midi.port_min->getBuffer(); | |||||
| const CarlaEngineMidiEvent* min_event; | |||||
| uint32_t time, n_min_events = midi.port_min->getEventCount(min_buffer); | |||||
| for (i=0; i < n_min_events && midi_event_count < MAX_MIDI_EVENTS; i++) | |||||
| { | |||||
| min_event = midi.port_min->getEvent(min_buffer, i); | |||||
| if (! min_event) | |||||
| continue; | |||||
| time = min_event->time - nframesOffset; | |||||
| if (time >= nframes) | |||||
| continue; | |||||
| uint8_t status = min_event->data[0]; | |||||
| uint8_t channel = status & 0x0F; | |||||
| // Fix bad note-off | |||||
| if (MIDI_IS_STATUS_NOTE_ON(status) && min_event->data[2] == 0) | |||||
| status -= 0x10; | |||||
| if (MIDI_IS_STATUS_NOTE_OFF(status)) | |||||
| { | |||||
| uint8_t note = min_event->data[1]; | |||||
| midiInputPort->DispatchNoteOff(note, 0, channel, time); | |||||
| if (channel == cin_channel) | |||||
| postpone_event(PluginPostEventNoteOff, note, 0.0); | |||||
| } | |||||
| else if (MIDI_IS_STATUS_NOTE_ON(status)) | |||||
| { | |||||
| uint8_t note = min_event->data[1]; | |||||
| uint8_t velo = min_event->data[2]; | |||||
| midiInputPort->DispatchNoteOn(note, velo, channel, time); | |||||
| if (channel == cin_channel) | |||||
| postpone_event(PluginPostEventNoteOn, note, velo); | |||||
| } | |||||
| else if (MIDI_IS_STATUS_AFTERTOUCH(status)) | |||||
| { | |||||
| uint8_t pressure = min_event->data[1]; | |||||
| midiInputPort->DispatchControlChange(MIDI_STATUS_AFTERTOUCH, pressure, channel, time); | |||||
| } | |||||
| else if (MIDI_IS_STATUS_PITCH_WHEEL_CONTROL(status)) | |||||
| { | |||||
| uint8_t lsb = min_event->data[1]; | |||||
| uint8_t msb = min_event->data[2]; | |||||
| midiInputPort->DispatchPitchbend(((msb << 7) | lsb) - 8192, channel, time); | |||||
| } | |||||
| else | |||||
| continue; | |||||
| midi_event_count += 1; | |||||
| } | |||||
| } // End of MIDI Input (System) | |||||
| CARLA_PROCESS_CONTINUE_CHECK; | |||||
| // -------------------------------------------------------------------------------------------------------- | |||||
| // Plugin processing | |||||
| if (m_active) | |||||
| { | |||||
| if (! m_active_before) | |||||
| { | |||||
| if (cin_channel >= 0 && cin_channel < 16) | |||||
| { | |||||
| midiInputPort->DispatchControlChange(MIDI_CONTROL_ALL_SOUND_OFF, 0, cin_channel); | |||||
| midiInputPort->DispatchControlChange(MIDI_CONTROL_ALL_NOTES_OFF, 0, cin_channel); | |||||
| } | |||||
| } | |||||
| audioOutputDevice->Channel(0)->SetBuffer(aouts_buffer[0]); | |||||
| audioOutputDevice->Channel(1)->SetBuffer(aouts_buffer[1]); | |||||
| // QUESTION: Need to clear it before? | |||||
| audioOutputDevice->Render(nframes); | |||||
| } | |||||
| // -------------------------------------------------------------------------------------------------------- | |||||
| // Post-processing (dry/wet, volume and balance) | |||||
| if (m_active) | |||||
| { | |||||
| bool do_volume = x_vol != 1.0; | |||||
| bool do_balance = (x_bal_left != -1.0 || x_bal_right != 1.0); | |||||
| double bal_rangeL, bal_rangeR; | |||||
| float old_bal_left[do_balance ? nframes : 0]; | |||||
| for (i=0; i < aout.count; i++) | |||||
| { | |||||
| // Volume | |||||
| if (do_volume) | |||||
| { | |||||
| for (k=0; k<nframes; k++) | |||||
| aouts_buffer[i][k] *= x_vol; | |||||
| } | |||||
| // Balance | |||||
| if (do_balance) | |||||
| { | |||||
| if (i%2 == 0) | |||||
| memcpy(&old_bal_left, aouts_buffer[i], sizeof(float)*nframes); | |||||
| bal_rangeL = (x_bal_left+1.0)/2; | |||||
| bal_rangeR = (x_bal_right+1.0)/2; | |||||
| for (k=0; k<nframes; k++) | |||||
| { | |||||
| if (i%2 == 0) | |||||
| { | |||||
| // left output | |||||
| aouts_buffer[i][k] = old_bal_left[k]*(1.0-bal_rangeL); | |||||
| aouts_buffer[i][k] += aouts_buffer[i+1][k]*(1.0-bal_rangeR); | |||||
| } | |||||
| else | |||||
| { | |||||
| // right | |||||
| aouts_buffer[i][k] = aouts_buffer[i][k]*bal_rangeR; | |||||
| aouts_buffer[i][k] += old_bal_left[k]*bal_rangeL; | |||||
| } | |||||
| } | |||||
| } | |||||
| // Output VU | |||||
| for (k=0; k < nframes && i < 2; k++) | |||||
| { | |||||
| if (abs_d(aouts_buffer[i][k]) > aouts_peak_tmp[i]) | |||||
| aouts_peak_tmp[i] = abs_d(aouts_buffer[i][k]); | |||||
| } | |||||
| } | |||||
| } | |||||
| else | |||||
| { | |||||
| // disable any output sound if not active | |||||
| for (i=0; i < aout.count; i++) | |||||
| memset(aouts_buffer[i], 0.0f, sizeof(float)*nframes); | |||||
| aouts_peak_tmp[0] = 0.0; | |||||
| aouts_peak_tmp[1] = 0.0; | |||||
| } // End of Post-processing | |||||
| CARLA_PROCESS_CONTINUE_CHECK; | |||||
| // -------------------------------------------------------------------------------------------------------- | |||||
| // Peak Values | |||||
| aouts_peak[(m_id*2)+0] = aouts_peak_tmp[0]; | |||||
| aouts_peak[(m_id*2)+1] = aouts_peak_tmp[1]; | |||||
| m_active_before = m_active; | |||||
| } | |||||
| // ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
| bool init(const char* filename, const char* label) | bool init(const char* filename, const char* label) | ||||
| { | { | ||||
| m_filename = strdup(filename); | |||||
| m_label = strdup(label); | |||||
| m_name = get_unique_name(label); | |||||
| x_client = new CarlaEngineClient(this); | |||||
| QFileInfo file(filename); | |||||
| if (x_client->isOk()) | |||||
| return true; | |||||
| if (file.exists() && file.isFile() && file.isReadable()) | |||||
| { | |||||
| const char* stype = m_isGIG ? "gig" : "sfz"; | |||||
| try { | |||||
| engine = LinuxSampler::EngineFactory::Create(stype); | |||||
| } | |||||
| catch (LinuxSampler::Exception& e) | |||||
| { | |||||
| set_last_error(e.what()); | |||||
| return false; | |||||
| } | |||||
| try { | |||||
| instrument = engine->GetInstrumentManager(); | |||||
| } | |||||
| catch (LinuxSampler::Exception& e) | |||||
| { | |||||
| set_last_error(e.what()); | |||||
| return false; | |||||
| } | |||||
| try { | |||||
| instrumentIds = instrument->GetInstrumentFileContent(filename); | |||||
| } | |||||
| catch (LinuxSampler::Exception& e) | |||||
| { | |||||
| set_last_error(e.what()); | |||||
| return false; | |||||
| } | |||||
| if (instrumentIds.size() > 0) | |||||
| { | |||||
| LinuxSampler::InstrumentManager::instrument_info_t info = instrument->GetInstrumentInfo(instrumentIds[0]); | |||||
| m_name = strdup(info.InstrumentName.c_str()); | |||||
| m_label = strdup(info.Product.c_str()); | |||||
| m_maker = strdup(info.Artists.c_str()); | |||||
| m_filename = strdup(filename); | |||||
| sampler_channel = sampler->AddSamplerChannel(); | |||||
| sampler_channel->SetEngineType(stype); | |||||
| sampler_channel->SetAudioOutputDevice(audioOutputDevice); | |||||
| //sampler_channel->SetMidiInputDevice(midiInputDevice); | |||||
| //sampler_channel->SetMidiInputChannel(LinuxSampler::midi_chan_1); | |||||
| midiInputPort->Connect(sampler_channel->GetEngineChannel(), LinuxSampler::midi_chan_all); | |||||
| engine_channel = sampler_channel->GetEngineChannel(); | |||||
| engine_channel->Connect(audioOutputDevice); | |||||
| engine_channel->PrepareLoadInstrument(filename, 0); // todo - find instrument from label | |||||
| engine_channel->LoadInstrument(); | |||||
| engine_channel->Volume(LINUXSAMPLER_VOLUME_MAX); | |||||
| x_client = new CarlaEngineClient(this); | |||||
| if (x_client->isOk()) | |||||
| return true; | |||||
| else | |||||
| set_last_error("Failed to register plugin client"); | |||||
| } | |||||
| else | |||||
| set_last_error("Failed to find any instruments"); | |||||
| } | |||||
| else | |||||
| set_last_error("Requested file is not valid or does not exist"); | |||||
| set_last_error("Failed to register plugin client"); | |||||
| return false; | return false; | ||||
| } | } | ||||
| private: | private: | ||||
| LinuxSampler::Sampler* sampler; | |||||
| LinuxSampler::SamplerChannel* sampler_channel; | |||||
| LinuxSampler::Engine* engine; | |||||
| LinuxSampler::EngineChannel* engine_channel; | |||||
| LinuxSampler::InstrumentManager* instrument; | |||||
| std::vector<LinuxSampler::InstrumentManager::instrument_id_t> instrumentIds; | |||||
| AudioOutputDevicePlugin* audioOutputDevice; | |||||
| MidiInputDevicePlugin* midiInputDevice; | |||||
| LinuxSampler::MidiInputPort* midiInputPort; | |||||
| bool m_isGIG; | |||||
| const char* m_name; | |||||
| const char* m_label; | const char* m_label; | ||||
| const char* m_maker; | |||||
| }; | }; | ||||
| short add_plugin_linuxsampler(const char* filename, const char* label, bool isGIG) | short add_plugin_linuxsampler(const char* filename, const char* label, bool isGIG) | ||||
| @@ -3,7 +3,7 @@ | |||||
| QT = core gui | QT = core gui | ||||
| CONFIG = debug link_pkgconfig qt warn_on | CONFIG = debug link_pkgconfig qt warn_on | ||||
| PKGCONFIG = jack liblo fluidsynth | |||||
| PKGCONFIG = jack liblo fluidsynth linuxsampler | |||||
| TARGET = carla_backend | TARGET = carla_backend | ||||
| TEMPLATE = app | TEMPLATE = app | ||||
| @@ -1150,25 +1150,10 @@ void do_linuxsampler_check(const char* filename, const char* stype) | |||||
| QFileInfo file(filename); | QFileInfo file(filename); | ||||
| if (! file.exists()) | |||||
| { | |||||
| DISCOVERY_OUT("error", "Requested file does not exist"); | |||||
| return; | |||||
| } | |||||
| if (! file.isFile()) | |||||
| { | |||||
| DISCOVERY_OUT("error", "Requested filename is not a file"); | |||||
| return; | |||||
| } | |||||
| if (! file.isReadable()) | |||||
| { | |||||
| DISCOVERY_OUT("error", "Requested file is not readable"); | |||||
| return; | |||||
| } | |||||
| const ScopedEngine engine(filename, stype); | |||||
| if (file.exists() && file.isFile() && file.isReadable()) | |||||
| const ScopedEngine engine(filename, stype); | |||||
| else | |||||
| DISCOVERY_OUT("error", "Requested file is not valid or does not exist"); | |||||
| #else | #else | ||||
| (void)filename; | (void)filename; | ||||