Browse Source

Carla: Update fluidsynth as linuxsampler code (sync)

tags/v0.9.0
falkTX 13 years ago
parent
commit
21da1fe755
2 changed files with 248 additions and 195 deletions
  1. +158
    -123
      c++/carla-backend/fluidsynth.cpp
  2. +90
    -72
      c++/carla-backend/linuxsampler.cpp

+ 158
- 123
c++/carla-backend/fluidsynth.cpp View File

@@ -98,7 +98,7 @@ public:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Information (count) // Information (count)


uint32_t parameterScalePointCount(uint32_t parameterId)
uint32_t parameterScalePointCount(const uint32_t parameterId)
{ {
Q_ASSERT(parameterId < param.count); Q_ASSERT(parameterId < param.count);


@@ -116,13 +116,14 @@ public:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Information (per-plugin data) // Information (per-plugin data)


double getParameterValue(uint32_t parameterId)
double getParameterValue(const uint32_t parameterId)
{ {
Q_ASSERT(parameterId < param.count); Q_ASSERT(parameterId < param.count);
return param_buffers[parameterId];

return paramBuffers[parameterId];
} }


double getParameterScalePointValue(uint32_t parameterId, uint32_t scalePointId)
double getParameterScalePointValue(const uint32_t parameterId, const uint32_t scalePointId)
{ {
Q_ASSERT(parameterId < param.count); Q_ASSERT(parameterId < param.count);
Q_ASSERT(scalePointId < parameterScalePointCount(parameterId)); Q_ASSERT(scalePointId < parameterScalePointCount(parameterId));
@@ -160,7 +161,10 @@ public:


void getLabel(char* const strBuf) void getLabel(char* const strBuf)
{ {
strncpy(strBuf, m_label, STR_MAX);
if (m_label)
strncpy(strBuf, m_label, STR_MAX);
else
CarlaPlugin::getLabel(strBuf);
} }


void getMaker(char* const strBuf) void getMaker(char* const strBuf)
@@ -178,7 +182,7 @@ public:
getLabel(strBuf); getLabel(strBuf);
} }


void getParameterName(uint32_t parameterId, char* const strBuf)
void getParameterName(const uint32_t parameterId, char* const strBuf)
{ {
Q_ASSERT(parameterId < param.count); Q_ASSERT(parameterId < param.count);


@@ -227,12 +231,12 @@ public:
strncpy(strBuf, "Voice Count", STR_MAX); strncpy(strBuf, "Voice Count", STR_MAX);
break; break;
default: default:
*strBuf = 0;
CarlaPlugin::getParameterName(parameterId, strBuf);
break; break;
} }
} }


void getParameterUnit(uint32_t parameterId, char* const strBuf)
void getParameterUnit(const uint32_t parameterId, char* const strBuf)
{ {
Q_ASSERT(parameterId < param.count); Q_ASSERT(parameterId < param.count);


@@ -245,12 +249,12 @@ public:
strncpy(strBuf, "ms", STR_MAX); strncpy(strBuf, "ms", STR_MAX);
break; break;
default: default:
*strBuf = 0;
CarlaPlugin::getParameterUnit(parameterId, strBuf);
break; break;
} }
} }


void getParameterScalePointLabel(uint32_t parameterId, uint32_t scalePointId, char* const strBuf)
void getParameterScalePointLabel(const uint32_t parameterId, const uint32_t scalePointId, char* const strBuf)
{ {
Q_ASSERT(parameterId < param.count); Q_ASSERT(parameterId < param.count);
Q_ASSERT(scalePointId < parameterScalePointCount(parameterId)); Q_ASSERT(scalePointId < parameterScalePointCount(parameterId));
@@ -285,16 +289,16 @@ public:
} }
} }


*strBuf = 0;
CarlaPlugin::getParameterScalePointLabel(parameterId, scalePointId, strBuf);
} }


// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Set data (plugin-specific stuff) // Set data (plugin-specific stuff)


void setParameterValue(uint32_t parameterId, double value, bool sendGui, bool sendOsc, bool sendCallback)
void setParameterValue(const uint32_t parameterId, double value, const bool sendGui, const bool sendOsc, const bool sendCallback)
{ {
Q_ASSERT(parameterId < param.count); Q_ASSERT(parameterId < param.count);
param_buffers[parameterId] = fixParameterValue(value, param.ranges[parameterId]);
paramBuffers[parameterId] = fixParameterValue(value, param.ranges[parameterId]);


switch (parameterId) switch (parameterId)
{ {
@@ -307,7 +311,7 @@ public:
case FluidSynthReverbDamp: case FluidSynthReverbDamp:
case FluidSynthReverbLevel: case FluidSynthReverbLevel:
case FluidSynthReverbWidth: case FluidSynthReverbWidth:
fluid_synth_set_reverb(f_synth, param_buffers[FluidSynthReverbRoomSize], param_buffers[FluidSynthReverbDamp], param_buffers[FluidSynthReverbWidth], param_buffers[FluidSynthReverbLevel]);
fluid_synth_set_reverb(f_synth, paramBuffers[FluidSynthReverbRoomSize], paramBuffers[FluidSynthReverbDamp], paramBuffers[FluidSynthReverbWidth], paramBuffers[FluidSynthReverbLevel]);
break; break;


case FluidSynthChorusOnOff: case FluidSynthChorusOnOff:
@@ -325,7 +329,7 @@ public:
case FluidSynthChorusType: case FluidSynthChorusType:
{ {
const ScopedDisabler m(this, ! x_engine->isOffline()); const ScopedDisabler m(this, ! x_engine->isOffline());
fluid_synth_set_chorus(f_synth, rint(param_buffers[FluidSynthChorusNr]), param_buffers[FluidSynthChorusLevel], param_buffers[FluidSynthChorusSpeedHz], param_buffers[FluidSynthChorusDepthMs], rint(param_buffers[FluidSynthChorusType]));
fluid_synth_set_chorus(f_synth, rint(paramBuffers[FluidSynthChorusNr]), paramBuffers[FluidSynthChorusLevel], paramBuffers[FluidSynthChorusSpeedHz], paramBuffers[FluidSynthChorusDepthMs], rint(paramBuffers[FluidSynthChorusType]));
break; break;
} }


@@ -351,9 +355,14 @@ public:
CarlaPlugin::setParameterValue(parameterId, value, sendGui, sendOsc, sendCallback); CarlaPlugin::setParameterValue(parameterId, value, sendGui, sendOsc, sendCallback);
} }


void setMidiProgram(int32_t index, bool sendGui, bool sendOsc, bool sendCallback, bool block)
void setMidiProgram(int32_t index, const bool sendGui, const bool sendOsc, const bool sendCallback, const bool block)
{ {
Q_ASSERT(index < (int32_t)midiprog.count);
Q_ASSERT(index >= -1 && index < (int32_t)midiprog.count);

if (index < -1)
index = -1;
else if (index > (int32_t)midiprog.count)
return;


if (m_ctrlInChannel < 0 || m_ctrlInChannel > 15) if (m_ctrlInChannel < 0 || m_ctrlInChannel > 15)
return; return;
@@ -405,8 +414,8 @@ public:
param.data = new ParameterData[params]; param.data = new ParameterData[params];
param.ranges = new ParameterRanges[params]; param.ranges = new ParameterRanges[params];


//const int portNameSize = CarlaEngine::maxPortNameSize() - 1;
char portName[STR_MAX];
const int portNameSize = CarlaEngine::maxPortNameSize() - 1;
char portName[portNameSize];


// --------------------------------------- // ---------------------------------------
// Audio Outputs // Audio Outputs
@@ -489,11 +498,11 @@ public:
param.data[j].midiCC = -1; param.data[j].midiCC = -1;
param.ranges[j].min = 0.0; param.ranges[j].min = 0.0;
param.ranges[j].max = 1.0; param.ranges[j].max = 1.0;
param.ranges[j].def = 0.0;
param.ranges[j].def = 0.0; // off
param.ranges[j].step = 1.0; param.ranges[j].step = 1.0;
param.ranges[j].stepSmall = 1.0; param.ranges[j].stepSmall = 1.0;
param.ranges[j].stepLarge = 1.0; param.ranges[j].stepLarge = 1.0;
param_buffers[j] = param.ranges[j].def;
paramBuffers[j] = param.ranges[j].def;


// ---------------------- // ----------------------
j = FluidSynthReverbRoomSize; j = FluidSynthReverbRoomSize;
@@ -509,7 +518,7 @@ public:
param.ranges[j].step = 0.01; param.ranges[j].step = 0.01;
param.ranges[j].stepSmall = 0.0001; param.ranges[j].stepSmall = 0.0001;
param.ranges[j].stepLarge = 0.1; param.ranges[j].stepLarge = 0.1;
param_buffers[j] = param.ranges[j].def;
paramBuffers[j] = param.ranges[j].def;


// ---------------------- // ----------------------
j = FluidSynthReverbDamp; j = FluidSynthReverbDamp;
@@ -525,7 +534,7 @@ public:
param.ranges[j].step = 0.01; param.ranges[j].step = 0.01;
param.ranges[j].stepSmall = 0.0001; param.ranges[j].stepSmall = 0.0001;
param.ranges[j].stepLarge = 0.1; param.ranges[j].stepLarge = 0.1;
param_buffers[j] = param.ranges[j].def;
paramBuffers[j] = param.ranges[j].def;


// ---------------------- // ----------------------
j = FluidSynthReverbLevel; j = FluidSynthReverbLevel;
@@ -541,7 +550,7 @@ public:
param.ranges[j].step = 0.01; param.ranges[j].step = 0.01;
param.ranges[j].stepSmall = 0.0001; param.ranges[j].stepSmall = 0.0001;
param.ranges[j].stepLarge = 0.1; param.ranges[j].stepLarge = 0.1;
param_buffers[j] = param.ranges[j].def;
paramBuffers[j] = param.ranges[j].def;


// ---------------------- // ----------------------
j = FluidSynthReverbWidth; j = FluidSynthReverbWidth;
@@ -557,7 +566,7 @@ public:
param.ranges[j].step = 0.01; param.ranges[j].step = 0.01;
param.ranges[j].stepSmall = 0.0001; param.ranges[j].stepSmall = 0.0001;
param.ranges[j].stepLarge = 0.1; param.ranges[j].stepLarge = 0.1;
param_buffers[j] = param.ranges[j].def;
paramBuffers[j] = param.ranges[j].def;


// ---------------------- // ----------------------
j = FluidSynthChorusOnOff; j = FluidSynthChorusOnOff;
@@ -569,11 +578,11 @@ public:
param.data[j].midiCC = -1; param.data[j].midiCC = -1;
param.ranges[j].min = 0.0; param.ranges[j].min = 0.0;
param.ranges[j].max = 1.0; param.ranges[j].max = 1.0;
param.ranges[j].def = 0.0;
param.ranges[j].def = 0.0; // off
param.ranges[j].step = 1.0; param.ranges[j].step = 1.0;
param.ranges[j].stepSmall = 1.0; param.ranges[j].stepSmall = 1.0;
param.ranges[j].stepLarge = 1.0; param.ranges[j].stepLarge = 1.0;
param_buffers[j] = param.ranges[j].def;
paramBuffers[j] = param.ranges[j].def;


// ---------------------- // ----------------------
j = FluidSynthChorusNr; j = FluidSynthChorusNr;
@@ -589,7 +598,7 @@ public:
param.ranges[j].step = 1.0; param.ranges[j].step = 1.0;
param.ranges[j].stepSmall = 1.0; param.ranges[j].stepSmall = 1.0;
param.ranges[j].stepLarge = 10.0; param.ranges[j].stepLarge = 10.0;
param_buffers[j] = param.ranges[j].def;
paramBuffers[j] = param.ranges[j].def;


// ---------------------- // ----------------------
j = FluidSynthChorusLevel; j = FluidSynthChorusLevel;
@@ -605,7 +614,7 @@ public:
param.ranges[j].step = 0.01; param.ranges[j].step = 0.01;
param.ranges[j].stepSmall = 0.0001; param.ranges[j].stepSmall = 0.0001;
param.ranges[j].stepLarge = 0.1; param.ranges[j].stepLarge = 0.1;
param_buffers[j] = param.ranges[j].def;
paramBuffers[j] = param.ranges[j].def;


// ---------------------- // ----------------------
j = FluidSynthChorusSpeedHz; j = FluidSynthChorusSpeedHz;
@@ -621,7 +630,7 @@ public:
param.ranges[j].step = 0.01; param.ranges[j].step = 0.01;
param.ranges[j].stepSmall = 0.0001; param.ranges[j].stepSmall = 0.0001;
param.ranges[j].stepLarge = 0.1; param.ranges[j].stepLarge = 0.1;
param_buffers[j] = param.ranges[j].def;
paramBuffers[j] = param.ranges[j].def;


// ---------------------- // ----------------------
j = FluidSynthChorusDepthMs; j = FluidSynthChorusDepthMs;
@@ -637,7 +646,7 @@ public:
param.ranges[j].step = 0.01; param.ranges[j].step = 0.01;
param.ranges[j].stepSmall = 0.0001; param.ranges[j].stepSmall = 0.0001;
param.ranges[j].stepLarge = 0.1; param.ranges[j].stepLarge = 0.1;
param_buffers[j] = param.ranges[j].def;
paramBuffers[j] = param.ranges[j].def;


// ---------------------- // ----------------------
j = FluidSynthChorusType; j = FluidSynthChorusType;
@@ -653,7 +662,7 @@ public:
param.ranges[j].step = 1; param.ranges[j].step = 1;
param.ranges[j].stepSmall = 1; param.ranges[j].stepSmall = 1;
param.ranges[j].stepLarge = 1; param.ranges[j].stepLarge = 1;
param_buffers[j] = param.ranges[j].def;
paramBuffers[j] = param.ranges[j].def;


// ---------------------- // ----------------------
j = FluidSynthPolyphony; j = FluidSynthPolyphony;
@@ -669,7 +678,7 @@ public:
param.ranges[j].step = 1; param.ranges[j].step = 1;
param.ranges[j].stepSmall = 1; param.ranges[j].stepSmall = 1;
param.ranges[j].stepLarge = 10; param.ranges[j].stepLarge = 10;
param_buffers[j] = param.ranges[j].def;
paramBuffers[j] = param.ranges[j].def;


// ---------------------- // ----------------------
j = FluidSynthInterpolation; j = FluidSynthInterpolation;
@@ -685,7 +694,7 @@ public:
param.ranges[j].step = 1; param.ranges[j].step = 1;
param.ranges[j].stepSmall = 1; param.ranges[j].stepSmall = 1;
param.ranges[j].stepLarge = 1; param.ranges[j].stepLarge = 1;
param_buffers[j] = param.ranges[j].def;
paramBuffers[j] = param.ranges[j].def;


// ---------------------- // ----------------------
j = FluidSynthVoiceCount; j = FluidSynthVoiceCount;
@@ -701,7 +710,7 @@ public:
param.ranges[j].step = 1; param.ranges[j].step = 1;
param.ranges[j].stepSmall = 1; param.ranges[j].stepSmall = 1;
param.ranges[j].stepLarge = 1; param.ranges[j].stepLarge = 1;
param_buffers[j] = param.ranges[j].def;
paramBuffers[j] = param.ranges[j].def;


// --------------------------------------- // ---------------------------------------


@@ -722,7 +731,7 @@ public:
qDebug("FluidSynthPlugin::reload() - end"); qDebug("FluidSynthPlugin::reload() - end");
} }


void reloadPrograms(bool init)
void reloadPrograms(const bool init)
{ {
qDebug("FluidSynthPlugin::reloadPrograms(%s)", bool2str(init)); qDebug("FluidSynthPlugin::reloadPrograms(%s)", bool2str(init));


@@ -741,6 +750,7 @@ public:
// Query new programs // Query new programs
fluid_sfont_t* f_sfont; fluid_sfont_t* f_sfont;
fluid_preset_t f_preset; fluid_preset_t f_preset;
bool hasDrums = false;


f_sfont = fluid_synth_get_sfont_by_id(f_synth, f_id); f_sfont = fluid_synth_get_sfont_by_id(f_synth, f_id);


@@ -749,8 +759,11 @@ public:
while (f_sfont->iteration_next(f_sfont, &f_preset)) while (f_sfont->iteration_next(f_sfont, &f_preset))
midiprog.count += 1; midiprog.count += 1;


// soundfonts must always have at least 1 midi-program
Q_ASSERT(midiprog.count > 0);

if (midiprog.count > 0) if (midiprog.count > 0)
midiprog.data = new midi_program_t [midiprog.count];
midiprog.data = new midi_program_t[midiprog.count];


// Update data // Update data
uint32_t i = 0; uint32_t i = 0;
@@ -761,6 +774,10 @@ public:
midiprog.data[i].bank = f_preset.get_banknum(&f_preset); midiprog.data[i].bank = f_preset.get_banknum(&f_preset);
midiprog.data[i].program = f_preset.get_num(&f_preset); midiprog.data[i].program = f_preset.get_num(&f_preset);
midiprog.data[i].name = strdup(f_preset.get_name(&f_preset)); midiprog.data[i].name = strdup(f_preset.get_name(&f_preset));

if (midiprog.data[i].bank == 128)
hasDrums = true;

i++; i++;
} }


@@ -777,30 +794,38 @@ public:
} }
#endif #endif


// FIXME
x_engine->callback(CALLBACK_RELOAD_PROGRAMS, m_id, 0, 0, 0.0);

if (init) if (init)
{ {
fluid_synth_program_reset(f_synth); fluid_synth_program_reset(f_synth);


if (midiprog.count > 0)
for (i=0; i < 16 && i != 9; i++)
{ {
for (i=0; i < 16 && i != 9; i++)
{
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, i, CHANNEL_TYPE_MELODIC);
fluid_synth_set_channel_type(f_synth, i, CHANNEL_TYPE_MELODIC);
#endif #endif
}
}


if (hasDrums)
{
fluid_synth_program_select(f_synth, 9, f_id, 128, 0); fluid_synth_program_select(f_synth, 9, f_id, 128, 0);
#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

setMidiProgram(0, false, false, false, true);
} }
else
{
fluid_synth_program_select(f_synth, 9, f_id, midiprog.data[0].bank, midiprog.data[0].program);
#ifdef FLUIDSYNTH_VERSION_NEW_API
fluid_synth_set_channel_type(f_synth, 9, CHANNEL_TYPE_MELODIC);
#endif
}

setMidiProgram(0, false, false, false, true);
}
else
{
x_engine->callback(CALLBACK_RELOAD_PROGRAMS, m_id, 0, 0, 0.0);
} }
} }


@@ -812,7 +837,7 @@ public:
uint32_t i, k; uint32_t i, k;
uint32_t midiEventCount = 0; uint32_t midiEventCount = 0;


double aouts_peak_tmp[2] = { 0.0 };
double aOutsPeak[2] = { 0.0 };


CARLA_PROCESS_CONTINUE_CHECK; CARLA_PROCESS_CONTINUE_CHECK;


@@ -877,12 +902,12 @@ public:
double left, right; double left, right;
value = cinEvent->value/0.5 - 1.0; value = cinEvent->value/0.5 - 1.0;


if (value < 0)
if (value < 0.0)
{ {
left = -1.0; left = -1.0;
right = (value*2)+1.0; right = (value*2)+1.0;
} }
else if (value > 0)
else if (value > 0.0)
{ {
left = (value*2)-1.0; left = (value*2)-1.0;
right = 1.0; right = 1.0;
@@ -1006,95 +1031,104 @@ public:
CARLA_PROCESS_CONTINUE_CHECK; CARLA_PROCESS_CONTINUE_CHECK;


// -------------------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------------------
// MIDI Input (External)
// MIDI Input


if (m_ctrlInChannel >= 0 && m_ctrlInChannel < 16 && m_active && m_activeBefore)
if (m_active && m_activeBefore)
{ {
engineMidiLock();
// ----------------------------------------------------------------------------------------------------
// MIDI Input (External)


for (i=0; i < MAX_MIDI_EVENTS && midiEventCount < MAX_MIDI_EVENTS; i++)
{ {
if (extMidiNotes[i].channel < 0)
break;
engineMidiLock();


if (extMidiNotes[i].velo)
fluid_synth_noteon(f_synth, m_ctrlInChannel, extMidiNotes[i].note, extMidiNotes[i].velo);
else
fluid_synth_noteoff(f_synth, m_ctrlInChannel, extMidiNotes[i].note);
for (i=0; i < MAX_MIDI_EVENTS && midiEventCount < MAX_MIDI_EVENTS; i++)
{
if (extMidiNotes[i].channel < 0)
break;


extMidiNotes[i].channel = -1;
midiEventCount += 1;
}
if (extMidiNotes[i].velo)
fluid_synth_noteon(f_synth, m_ctrlInChannel, extMidiNotes[i].note, extMidiNotes[i].velo);
else
fluid_synth_noteoff(f_synth, m_ctrlInChannel, extMidiNotes[i].note);


engineMidiUnlock();
extMidiNotes[i].channel = -1; // mark as invalid
midiEventCount += 1;
}


} // End of MIDI Input (External)
engineMidiUnlock();


CARLA_PROCESS_CONTINUE_CHECK;
} // End of MIDI Input (External)


// --------------------------------------------------------------------------------------------------------
// MIDI Input (System)
CARLA_PROCESS_CONTINUE_CHECK;


if (m_active && m_activeBefore)
{
const CarlaEngineMidiEvent* minEvent;
uint32_t time, nEvents = midi.portMin->getEventCount();
// ----------------------------------------------------------------------------------------------------
// MIDI Input (System)


for (i=0; i < nEvents && midiEventCount < MAX_MIDI_EVENTS; i++)
{ {
minEvent = midi.portMin->getEvent(i);
const CarlaEngineMidiEvent* minEvent;
uint32_t time, nEvents = midi.portMin->getEventCount();


if (! minEvent)
continue;
for (i=0; i < nEvents && midiEventCount < MAX_MIDI_EVENTS; i++)
{
minEvent = midi.portMin->getEvent(i);


time = minEvent->time - framesOffset;
if (! minEvent)
continue;


if (time >= frames)
continue;
time = minEvent->time - framesOffset;


uint8_t status = minEvent->data[0];
uint8_t channel = status & 0x0F;
if (time >= frames)
continue;


// Fix bad note-off
if (MIDI_IS_STATUS_NOTE_ON(status) && minEvent->data[2] == 0)
status -= 0x10;
uint8_t status = minEvent->data[0];
uint8_t channel = status & 0x0F;


if (MIDI_IS_STATUS_NOTE_OFF(status))
{
uint8_t note = minEvent->data[1];
// Fix bad note-off
if (MIDI_IS_STATUS_NOTE_ON(status) && minEvent->data[2] == 0)
status -= 0x10;


fluid_synth_noteoff(f_synth, channel, note);
if (MIDI_IS_STATUS_NOTE_OFF(status))
{
uint8_t note = minEvent->data[1];


postponeEvent(PluginPostEventNoteOff, channel, note, 0.0);
}
else if (MIDI_IS_STATUS_NOTE_ON(status))
{
uint8_t note = minEvent->data[1];
uint8_t velo = minEvent->data[2];
fluid_synth_noteoff(f_synth, channel, note);


fluid_synth_noteon(f_synth, channel, note, velo);
postponeEvent(PluginPostEventNoteOff, channel, note, 0.0);
}
else if (MIDI_IS_STATUS_NOTE_ON(status))
{
uint8_t note = minEvent->data[1];
uint8_t velo = minEvent->data[2];


postponeEvent(PluginPostEventNoteOn, channel, note, velo);
}
else if (MIDI_IS_STATUS_AFTERTOUCH(status))
{
uint8_t pressure = minEvent->data[1];
fluid_synth_noteon(f_synth, channel, note, velo);


fluid_synth_channel_pressure(f_synth, channel, pressure);
}
else if (MIDI_IS_STATUS_PITCH_WHEEL_CONTROL(status))
{
uint8_t lsb = minEvent->data[1];
uint8_t msb = minEvent->data[2];
postponeEvent(PluginPostEventNoteOn, channel, note, velo);
}
else if (MIDI_IS_STATUS_POLYPHONIC_AFTERTOUCH(status))
{
// TODO, not in fluidsynth API?
}
else if (MIDI_IS_STATUS_AFTERTOUCH(status))
{
uint8_t pressure = minEvent->data[1];

fluid_synth_channel_pressure(f_synth, channel, pressure);
}
else if (MIDI_IS_STATUS_PITCH_WHEEL_CONTROL(status))
{
uint8_t lsb = minEvent->data[1];
uint8_t msb = minEvent->data[2];

fluid_synth_pitch_bend(f_synth, channel, (msb << 7) | lsb);
}
else
continue;


fluid_synth_pitch_bend(f_synth, channel, (msb << 7) | lsb);
midiEventCount += 1;
} }
else
continue;
} // End of MIDI Input (System)


midiEventCount += 1;
}
} // End of MIDI Input (System)
} // End of MIDI Input


CARLA_PROCESS_CONTINUE_CHECK; CARLA_PROCESS_CONTINUE_CHECK;


@@ -1169,8 +1203,8 @@ public:
// Output VU // Output VU
for (k=0; i < 2 && k < frames; k++) for (k=0; i < 2 && k < frames; k++)
{ {
if (abs(outBuffer[i][k]) > aouts_peak_tmp[i])
aouts_peak_tmp[i] = abs(outBuffer[i][k]);
if (abs(outBuffer[i][k]) > aOutsPeak[i])
aOutsPeak[i] = abs(outBuffer[i][k]);
} }
} }
} }
@@ -1180,8 +1214,8 @@ public:
for (i=0; i < aOut.count; i++) for (i=0; i < aOut.count; i++)
memset(outBuffer[i], 0.0f, sizeof(float)*frames); memset(outBuffer[i], 0.0f, sizeof(float)*frames);


aouts_peak_tmp[0] = 0.0;
aouts_peak_tmp[1] = 0.0;
aOutsPeak[0] = 0.0;
aOutsPeak[1] = 0.0;


} // End of Post-processing } // End of Post-processing


@@ -1193,12 +1227,12 @@ public:
if (m_active) if (m_active)
{ {
k = FluidSynthVoiceCount; k = FluidSynthVoiceCount;
param_buffers[k] = fluid_synth_get_active_voice_count(f_synth);
fixParameterValue(param_buffers[k], param.ranges[k]);
paramBuffers[k] = fluid_synth_get_active_voice_count(f_synth);
fixParameterValue(paramBuffers[k], param.ranges[k]);


if (param.data[k].midiCC > 0) if (param.data[k].midiCC > 0)
{ {
double value = (param_buffers[k] - param.ranges[k].min) / (param.ranges[k].max - param.ranges[k].min);
double value = (paramBuffers[k] - param.ranges[k].min) / (param.ranges[k].max - param.ranges[k].min);
param.portCout->writeEvent(CarlaEngineEventControlChange, framesOffset, param.data[k].midiChannel, param.data[k].midiCC, value); param.portCout->writeEvent(CarlaEngineEventControlChange, framesOffset, param.data[k].midiChannel, param.data[k].midiCC, value);
} }
} // End of Control Output } // End of Control Output
@@ -1208,8 +1242,8 @@ public:
// -------------------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------------------
// Peak Values // Peak Values


x_engine->setOutputPeak(m_id, 0, aouts_peak_tmp[0]);
x_engine->setOutputPeak(m_id, 1, aouts_peak_tmp[1]);
x_engine->setOutputPeak(m_id, 0, aOutsPeak[0]);
x_engine->setOutputPeak(m_id, 1, aOutsPeak[1]);


m_activeBefore = m_active; m_activeBefore = m_active;
} }
@@ -1277,7 +1311,8 @@ private:
fluid_synth_t* f_synth; fluid_synth_t* f_synth;
int f_id; int f_id;


double param_buffers[FluidSynthParametersMax];
double paramBuffers[FluidSynthParametersMax];

const char* m_label; const char* m_label;
}; };
#endif // WANT_FLUIDSYNTH #endif // WANT_FLUIDSYNTH


+ 90
- 72
c++/carla-backend/linuxsampler.cpp View File

@@ -154,7 +154,8 @@ public:
aOut.ports = new CarlaEngineAudioPort*[aOuts]; aOut.ports = new CarlaEngineAudioPort*[aOuts];
aOut.rindexes = new uint32_t[aOuts]; aOut.rindexes = new uint32_t[aOuts];


char portName[STR_MAX];
const int portNameSize = CarlaEngine::maxPortNameSize() - 1;
char portName[portNameSize];


// --------------------------------------- // ---------------------------------------
// Audio Outputs // Audio Outputs
@@ -238,6 +239,9 @@ public:
uint32_t i = 0; uint32_t i = 0;
midiprog.count += instrumentIds.size(); midiprog.count += instrumentIds.size();


// sound kits must always have at least 1 midi-program
Q_ASSERT(midiprog.count > 0);

if (midiprog.count > 0) if (midiprog.count > 0)
midiprog.data = new midi_program_t [midiprog.count]; midiprog.data = new midi_program_t [midiprog.count];


@@ -263,13 +267,15 @@ public:
} }
#endif #endif


// TODO

if (init) if (init)
{ {
if (midiprog.count > 0) if (midiprog.count > 0)
setMidiProgram(0, false, false, false, true); setMidiProgram(0, false, false, false, true);
} }
else
{
x_engine->callback(CALLBACK_RELOAD_PROGRAMS, m_id, 0, 0, 0.0);
}
} }


// ------------------------------------------------------------------- // -------------------------------------------------------------------
@@ -280,100 +286,112 @@ public:
uint32_t i, k; uint32_t i, k;
uint32_t midiEventCount = 0; uint32_t midiEventCount = 0;


double aouts_peak_tmp[2] = { 0.0 };
double aOutsPeak[2] = { 0.0 };


CARLA_PROCESS_CONTINUE_CHECK; CARLA_PROCESS_CONTINUE_CHECK;


// -------------------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------------------
// MIDI Input (External)
// MIDI Input


if (m_ctrlInChannel >= 0 && m_ctrlInChannel < 16 && m_active && m_activeBefore)
if (m_active && m_activeBefore)
{ {
engineMidiLock();
// ----------------------------------------------------------------------------------------------------
// MIDI Input (External)


for (i=0; i < MAX_MIDI_EVENTS && midiEventCount < MAX_MIDI_EVENTS; i++)
{ {
if (extMidiNotes[i].channel < 0)
break;
engineMidiLock();


if (extMidiNotes[i].velo)
midiInputPort->DispatchNoteOn(extMidiNotes[i].note, extMidiNotes[i].velo, m_ctrlInChannel, 0);
else
midiInputPort->DispatchNoteOff(extMidiNotes[i].note, extMidiNotes[i].velo, m_ctrlInChannel, 0);
for (i=0; i < MAX_MIDI_EVENTS && midiEventCount < MAX_MIDI_EVENTS; i++)
{
if (extMidiNotes[i].channel < 0)
break;


extMidiNotes[i].channel = -1;
midiEventCount += 1;
}
if (extMidiNotes[i].velo)
midiInputPort->DispatchNoteOn(extMidiNotes[i].note, extMidiNotes[i].velo, m_ctrlInChannel, 0);
else
midiInputPort->DispatchNoteOff(extMidiNotes[i].note, extMidiNotes[i].velo, m_ctrlInChannel, 0);


engineMidiUnlock();
extMidiNotes[i].channel = -1; // mark as invalid
midiEventCount += 1;
}


} // End of MIDI Input (External)
engineMidiUnlock();


CARLA_PROCESS_CONTINUE_CHECK;
} // End of MIDI Input (External)


// --------------------------------------------------------------------------------------------------------
// MIDI Input (System)
CARLA_PROCESS_CONTINUE_CHECK;


if (m_active && m_activeBefore)
{
const CarlaEngineMidiEvent* minEvent;
uint32_t time, nEvents = midi.portMin->getEventCount();
// ----------------------------------------------------------------------------------------------------
// MIDI Input (System)


for (i=0; i < nEvents && midiEventCount < MAX_MIDI_EVENTS; i++)
{ {
minEvent = midi.portMin->getEvent(i);
const CarlaEngineMidiEvent* minEvent;
uint32_t time, nEvents = midi.portMin->getEventCount();


if (! minEvent)
continue;
for (i=0; i < nEvents && midiEventCount < MAX_MIDI_EVENTS; i++)
{
minEvent = midi.portMin->getEvent(i);


time = minEvent->time - framesOffset;
if (! minEvent)
continue;


if (time >= frames)
continue;
time = minEvent->time - framesOffset;


uint8_t status = minEvent->data[0];
uint8_t channel = status & 0x0F;
if (time >= frames)
continue;


// Fix bad note-off
if (MIDI_IS_STATUS_NOTE_ON(status) && minEvent->data[2] == 0)
status -= 0x10;
uint8_t status = minEvent->data[0];
uint8_t channel = status & 0x0F;


if (MIDI_IS_STATUS_NOTE_OFF(status))
{
uint8_t note = minEvent->data[1];
// Fix bad note-off
if (MIDI_IS_STATUS_NOTE_ON(status) && minEvent->data[2] == 0)
status -= 0x10;


midiInputPort->DispatchNoteOff(note, 0, channel, time);
if (MIDI_IS_STATUS_NOTE_OFF(status))
{
uint8_t note = minEvent->data[1];


postponeEvent(PluginPostEventNoteOff, channel, note, 0.0);
}
else if (MIDI_IS_STATUS_NOTE_ON(status))
{
uint8_t note = minEvent->data[1];
uint8_t velo = minEvent->data[2];
midiInputPort->DispatchNoteOff(note, 0, channel, time);


midiInputPort->DispatchNoteOn(note, velo, channel, time);
postponeEvent(PluginPostEventNoteOff, channel, note, 0.0);
}
else if (MIDI_IS_STATUS_NOTE_ON(status))
{
uint8_t note = minEvent->data[1];
uint8_t velo = minEvent->data[2];


postponeEvent(PluginPostEventNoteOn, channel, note, velo);
}
else if (MIDI_IS_STATUS_AFTERTOUCH(status))
{
uint8_t pressure = minEvent->data[1];
midiInputPort->DispatchNoteOn(note, velo, channel, time);


midiInputPort->DispatchControlChange(MIDI_STATUS_AFTERTOUCH, pressure, channel, time);
}
else if (MIDI_IS_STATUS_PITCH_WHEEL_CONTROL(status))
{
uint8_t lsb = minEvent->data[1];
uint8_t msb = minEvent->data[2];
postponeEvent(PluginPostEventNoteOn, channel, note, velo);
}
else if (MIDI_IS_STATUS_POLYPHONIC_AFTERTOUCH(status))
{
//uint8_t note = minEvent->data[1];
//uint8_t pressure = minEvent->data[2];


midiInputPort->DispatchPitchbend(((msb << 7) | lsb) - 8192, channel, time);
// TODO, not in linuxsampler API?
}
else if (MIDI_IS_STATUS_AFTERTOUCH(status))
{
uint8_t pressure = minEvent->data[1];

midiInputPort->DispatchControlChange(MIDI_STATUS_AFTERTOUCH, pressure, channel, time);
}
else if (MIDI_IS_STATUS_PITCH_WHEEL_CONTROL(status))
{
uint8_t lsb = minEvent->data[1];
uint8_t msb = minEvent->data[2];

midiInputPort->DispatchPitchbend(((msb << 7) | lsb) - 8192, channel, time);
}
else
continue;

midiEventCount += 1;
} }
else
continue;
} // End of MIDI Input (System)


midiEventCount += 1;
}
} // End of MIDI Input (System)
} // End of MIDI Input


CARLA_PROCESS_CONTINUE_CHECK; CARLA_PROCESS_CONTINUE_CHECK;


@@ -448,8 +466,8 @@ public:
// Output VU // Output VU
for (k=0; i < 2 && k < frames; k++) for (k=0; i < 2 && k < frames; k++)
{ {
if (abs(outBuffer[i][k]) > aouts_peak_tmp[i])
aouts_peak_tmp[i] = abs(outBuffer[i][k]);
if (abs(outBuffer[i][k]) > aOutsPeak[i])
aOutsPeak[i] = abs(outBuffer[i][k]);
} }
} }
} }
@@ -459,8 +477,8 @@ public:
for (i=0; i < aOut.count; i++) for (i=0; i < aOut.count; i++)
memset(outBuffer[i], 0.0f, sizeof(float)*frames); memset(outBuffer[i], 0.0f, sizeof(float)*frames);


aouts_peak_tmp[0] = 0.0;
aouts_peak_tmp[1] = 0.0;
aOutsPeak[0] = 0.0;
aOutsPeak[1] = 0.0;


} // End of Post-processing } // End of Post-processing


@@ -469,8 +487,8 @@ public:
// -------------------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------------------
// Peak Values // Peak Values


x_engine->setOutputPeak(m_id, 0, aouts_peak_tmp[0]);
x_engine->setOutputPeak(m_id, 1, aouts_peak_tmp[1]);
x_engine->setOutputPeak(m_id, 0, aOutsPeak[0]);
x_engine->setOutputPeak(m_id, 1, aOutsPeak[1]);


m_activeBefore = m_active; m_activeBefore = m_active;
} }


Loading…
Cancel
Save