@@ -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; | ||||