Browse Source

LS per-channel patch and 16out is working

tags/1.9.4
falkTX 11 years ago
parent
commit
cc205f3e85
1 changed files with 70 additions and 77 deletions
  1. +70
    -77
      source/backend/plugin/LinuxSamplerPlugin.cpp

+ 70
- 77
source/backend/plugin/LinuxSamplerPlugin.cpp View File

@@ -48,13 +48,15 @@ static const float kVolumeMin = 0.0f; // -inf dB
class AudioOutputDevicePlugin : public AudioOutputDevice class AudioOutputDevicePlugin : public AudioOutputDevice
{ {
public: public:
AudioOutputDevicePlugin(const CarlaEngine* const engine, const CarlaPlugin* const plugin)
AudioOutputDevicePlugin(const CarlaEngine* const engine, const CarlaPlugin* const plugin, const bool uses16Outs)
: AudioOutputDevice(std::map<String, DeviceCreationParameter*>()), : AudioOutputDevice(std::map<String, DeviceCreationParameter*>()),
fEngine(engine), fEngine(engine),
fPlugin(plugin) fPlugin(plugin)
{ {
CARLA_ASSERT(engine != nullptr); CARLA_ASSERT(engine != nullptr);
CARLA_ASSERT(plugin != nullptr); CARLA_ASSERT(plugin != nullptr);

AcquireChannels(uses16Outs ? 32 : 2);
} }


~AudioOutputDevicePlugin() override {} ~AudioOutputDevicePlugin() override {}
@@ -183,18 +185,18 @@ public:
fMaker(nullptr), fMaker(nullptr),
fRealName(nullptr), fRealName(nullptr),
fEngine(nullptr), fEngine(nullptr),
fAudioOutputDevice(nullptr),
fMidiInputDevice(nullptr), fMidiInputDevice(nullptr),
fMidiInputPort(nullptr), fMidiInputPort(nullptr),
fInstrument(nullptr) fInstrument(nullptr)
{ {
carla_debug("LinuxSamplerPlugin::LinuxSamplerPlugin(%p, %i, %s, %s)", engine, id, format, bool2str(use16Outs)); carla_debug("LinuxSamplerPlugin::LinuxSamplerPlugin(%p, %i, %s, %s)", engine, id, format, bool2str(use16Outs));


for (int i=0; i < 16; ++i)
for (int i=0; i < MAX_MIDI_CHANNELS; ++i)
{ {
fCurMidiProgs[0] = 0;
fSamplerChannels[i] = nullptr;
fEngineChannels[i] = nullptr;
fAudioOutputDevices[i] = nullptr;
fCurMidiProgs[0] = 0;
fSamplerChannels[i] = nullptr;
fEngineChannels[i] = nullptr;
} }
} }


@@ -220,7 +222,7 @@ public:
{ {
if (fMidiInputPort != nullptr) if (fMidiInputPort != nullptr)
{ {
for (int i=0; i < 16; ++i)
for (int i=0; i < MAX_MIDI_CHANNELS; ++i)
{ {
if (fSamplerChannels[i] != nullptr) if (fSamplerChannels[i] != nullptr)
{ {
@@ -233,21 +235,9 @@ public:


fSampler.RemoveSamplerChannel(fSamplerChannels[i]); fSampler.RemoveSamplerChannel(fSamplerChannels[i]);
fSamplerChannels[i] = nullptr; fSamplerChannels[i] = nullptr;

if (fAudioOutputDevices[i] != nullptr && fUses16Outs)
{
delete fAudioOutputDevices[i];
fAudioOutputDevices[i] = nullptr;
}
} }
} }


if (fAudioOutputDevices[0] != nullptr)
{
delete fAudioOutputDevices[0];
fAudioOutputDevices[0] = nullptr;
}

delete fMidiInputPort; delete fMidiInputPort;
fMidiInputPort = nullptr; fMidiInputPort = nullptr;
} }
@@ -256,6 +246,12 @@ public:
fMidiInputDevice = nullptr; fMidiInputDevice = nullptr;
} }


if (fAudioOutputDevice != nullptr)
{
delete fAudioOutputDevice;
fAudioOutputDevice = nullptr;
}

fInstrument = nullptr; fInstrument = nullptr;


LinuxSampler::EngineFactory::Destroy(fEngine); LinuxSampler::EngineFactory::Destroy(fEngine);
@@ -420,12 +416,12 @@ public:
const uint32_t program = pData->midiprog.data[index].program; const uint32_t program = pData->midiprog.data[index].program;
const uint32_t rIndex = bank*128 + program; const uint32_t rIndex = bank*128 + program;


if (pData->engine->isOffline())
/*if (pData->engine->isOffline())
{ {
fEngineChannels[i]->PrepareLoadInstrument(pData->filename, rIndex); fEngineChannels[i]->PrepareLoadInstrument(pData->filename, rIndex);
fEngineChannels[i]->LoadInstrument(); fEngineChannels[i]->LoadInstrument();
} }
else
else*/
{ {
fInstrument->LoadInstrumentInBackground(fInstrumentIds[rIndex], fEngineChannels[i]); fInstrument->LoadInstrumentInBackground(fInstrumentIds[rIndex], fEngineChannels[i]);
} }
@@ -463,12 +459,12 @@ public:


const ScopedSingleProcessLocker spl(this, (sendGui || sendOsc || sendCallback)); const ScopedSingleProcessLocker spl(this, (sendGui || sendOsc || sendCallback));


if (pData->engine->isOffline())
/*if (pData->engine->isOffline())
{ {
engineChannel->PrepareLoadInstrument(pData->filename, rIndex); engineChannel->PrepareLoadInstrument(pData->filename, rIndex);
engineChannel->LoadInstrument(); engineChannel->LoadInstrument();
} }
else
else*/
{ {
fInstrument->LoadInstrumentInBackground(fInstrumentIds[rIndex], engineChannel); fInstrument->LoadInstrumentInBackground(fInstrumentIds[rIndex], engineChannel);
} }
@@ -668,12 +664,13 @@ public:


if (init) if (init)
{ {
for (int i=0; i < 16; ++i)
for (int i=0; i < MAX_MIDI_CHANNELS; ++i)
{ {
CARLA_SAFE_ASSERT_CONTINUE(fEngineChannels[i] != nullptr); CARLA_SAFE_ASSERT_CONTINUE(fEngineChannels[i] != nullptr);


fEngineChannels[i]->PrepareLoadInstrument(pData->filename, 0);
fEngineChannels[i]->LoadInstrument();
/*fEngineChannels[i]->PrepareLoadInstrument(pData->filename, 0);
fEngineChannels[i]->LoadInstrument();*/
fInstrument->LoadInstrumentInBackground(fInstrumentIds[0], fEngineChannels[i]);
fCurMidiProgs[i] = 0; fCurMidiProgs[i] = 0;
} }


@@ -691,7 +688,7 @@ public:
#if 0 #if 0
void activate() override void activate() override
{ {
for (int i=0; i < 16; ++i)
for (int i=0; i < MAX_MIDI_CHANNELS; ++i)
{ {
if (fAudioOutputDevices[i] != nullptr) if (fAudioOutputDevices[i] != nullptr)
fAudioOutputDevices[i]->Play(); fAudioOutputDevices[i]->Play();
@@ -700,7 +697,7 @@ public:


void deactivate() override void deactivate() override
{ {
for (int i=0; i < 16; ++i)
for (int i=0; i < MAX_MIDI_CHANNELS; ++i)
{ {
if (fAudioOutputDevices[i] != nullptr) if (fAudioOutputDevices[i] != nullptr)
fAudioOutputDevices[i]->Stop(); fAudioOutputDevices[i]->Stop();
@@ -928,12 +925,12 @@ public:
{ {
LinuxSampler::EngineChannel* const engineChannel(fEngineChannels[pData->ctrlChannel]); LinuxSampler::EngineChannel* const engineChannel(fEngineChannels[pData->ctrlChannel]);


if (pData->engine->isOffline())
/*if (pData->engine->isOffline())
{ {
engineChannel->PrepareLoadInstrument(pData->filename, rIndex); engineChannel->PrepareLoadInstrument(pData->filename, rIndex);
engineChannel->LoadInstrument(); engineChannel->LoadInstrument();
} }
else
else*/
{ {
fInstrument->LoadInstrumentInBackground(fInstrumentIds[rIndex], engineChannel); fInstrument->LoadInstrumentInBackground(fInstrumentIds[rIndex], engineChannel);
} }
@@ -992,12 +989,19 @@ public:
if (MIDI_IS_STATUS_PITCH_WHEEL_CONTROL(status) && (pData->options & PLUGIN_OPTION_SEND_PITCHBEND) == 0) if (MIDI_IS_STATUS_PITCH_WHEEL_CONTROL(status) && (pData->options & PLUGIN_OPTION_SEND_PITCHBEND) == 0)
continue; continue;


fMidiInputPort->DispatchRaw(const_cast<uint8_t*>(midiEvent.data), sampleAccurate ? startTime : time);
// put back channel in data
uint8_t data[EngineMidiEvent::kDataSize];
std::memcpy(data, event.midi.data, EngineMidiEvent::kDataSize);

if (status < 0xF0 && channel < MAX_MIDI_CHANNELS)
data[0] = uint8_t(data[0] + channel);

fMidiInputPort->DispatchRaw(data, sampleAccurate ? startTime : time);


if (status == MIDI_STATUS_NOTE_ON) if (status == MIDI_STATUS_NOTE_ON)
pData->postponeRtEvent(kPluginPostRtEventNoteOn, channel, midiEvent.data[1], midiEvent.data[2]);
pData->postponeRtEvent(kPluginPostRtEventNoteOn, channel, data[1], data[2]);
else if (status == MIDI_STATUS_NOTE_OFF) else if (status == MIDI_STATUS_NOTE_OFF)
pData->postponeRtEvent(kPluginPostRtEventNoteOff, channel, midiEvent.data[1], 0.0f);
pData->postponeRtEvent(kPluginPostRtEventNoteOff, channel,data[1], 0.0f);


break; break;
} }
@@ -1038,25 +1042,14 @@ public:
// -------------------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------------------
// Run plugin // Run plugin


if (fUses16Outs)
{
for (int i=0; i < 16; ++i)
{
if (fAudioOutputDevices[i] != nullptr)
{
fAudioOutputDevices[i]->Channel(0)->SetBuffer(outBuffer[i*2 ] + timeOffset);
fAudioOutputDevices[i]->Channel(1)->SetBuffer(outBuffer[i*2+1] + timeOffset);
fAudioOutputDevices[i]->Render(frames);
}
}
}
else
for (uint32_t i=0; i < pData->audioOut.count; ++i)
{ {
fAudioOutputDevices[0]->Channel(0)->SetBuffer(outBuffer[0] + timeOffset);
fAudioOutputDevices[0]->Channel(1)->SetBuffer(outBuffer[1] + timeOffset);
fAudioOutputDevices[0]->Render(frames);
if (LinuxSampler::AudioChannel* const outDev = fAudioOutputDevice->Channel(i))
outDev->SetBuffer(outBuffer[i] + timeOffset);
} }


fAudioOutputDevice->Render(frames);

#ifndef BUILD_BRIDGE #ifndef BUILD_BRIDGE
// -------------------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------------------
// Post-processing (dry/wet, volume and balance) // Post-processing (dry/wet, volume and balance)
@@ -1112,16 +1105,18 @@ public:
return true; return true;
} }


void bufferSizeChanged(const uint32_t newBufferSize) override
void bufferSizeChanged(const uint32_t) override
{ {
// TODO
(void)newBufferSize;
CARLA_SAFE_ASSERT_RETURN(fAudioOutputDevice != nullptr,);

fAudioOutputDevice->ReconnectAll();
} }


void sampleRateChanged(const double newSampleRate) override
void sampleRateChanged(const double) override
{ {
// TODO
(void)newSampleRate;
CARLA_SAFE_ASSERT_RETURN(fAudioOutputDevice != nullptr,);

fAudioOutputDevice->ReconnectAll();
} }


// ------------------------------------------------------------------- // -------------------------------------------------------------------
@@ -1185,38 +1180,36 @@ public:
// --------------------------------------------------------------- // ---------------------------------------------------------------
// Init LinuxSampler stuff // Init LinuxSampler stuff


fAudioOutputDevice = new LinuxSampler::AudioOutputDevicePlugin(pData->engine, this, fUses16Outs);

fMidiInputDevice = new LinuxSampler::MidiInputDevicePlugin(&fSampler); fMidiInputDevice = new LinuxSampler::MidiInputDevicePlugin(&fSampler);
fMidiInputPort = fMidiInputDevice->CreateMidiPortPlugin(); fMidiInputPort = fMidiInputDevice->CreateMidiPortPlugin();


// always needs at least 1 output device
fAudioOutputDevices[0] = new LinuxSampler::AudioOutputDevicePlugin(pData->engine, this);

for (int i=0; i < 16; ++i)
for (int i=0; i < MAX_MIDI_CHANNELS; ++i)
{ {
LinuxSampler::AudioOutputDevicePlugin* outputDevice;

if (fUses16Outs)
{
fAudioOutputDevices[i] = new LinuxSampler::AudioOutputDevicePlugin(pData->engine, this);
outputDevice = fAudioOutputDevices[i];
}
else
{
outputDevice = fAudioOutputDevices[0];
}

fSamplerChannels[i] = fSampler.AddSamplerChannel(); fSamplerChannels[i] = fSampler.AddSamplerChannel();
CARLA_SAFE_ASSERT_CONTINUE(fSamplerChannels[i] != nullptr); CARLA_SAFE_ASSERT_CONTINUE(fSamplerChannels[i] != nullptr);


fSamplerChannels[i]->SetEngineType(ctype); fSamplerChannels[i]->SetEngineType(ctype);
fSamplerChannels[i]->SetAudioOutputDevice(outputDevice);
fSamplerChannels[i]->SetAudioOutputDevice(fAudioOutputDevice);


fEngineChannels[i] = fSamplerChannels[i]->GetEngineChannel(); fEngineChannels[i] = fSamplerChannels[i]->GetEngineChannel();
CARLA_SAFE_ASSERT_CONTINUE(fEngineChannels[i] != nullptr); CARLA_SAFE_ASSERT_CONTINUE(fEngineChannels[i] != nullptr);


fEngineChannels[i]->Connect(outputDevice);
fEngineChannels[i]->Connect(fAudioOutputDevice);
fEngineChannels[i]->Volume(LinuxSampler::kVolumeMax); fEngineChannels[i]->Volume(LinuxSampler::kVolumeMax);


if (fUses16Outs)
{
fEngineChannels[i]->SetOutputChannel(0, i*2);
fEngineChannels[i]->SetOutputChannel(1, i*2 +1);
}
else
{
fEngineChannels[i]->SetOutputChannel(0, 0);
fEngineChannels[i]->SetOutputChannel(1, 1);
}

fMidiInputPort->Connect(fEngineChannels[i], static_cast<LinuxSampler::midi_chan_t>(i)); fMidiInputPort->Connect(fEngineChannels[i], static_cast<LinuxSampler::midi_chan_t>(i));
} }


@@ -1331,15 +1324,15 @@ private:
const char* fMaker; const char* fMaker;
const char* fRealName; const char* fRealName;


int32_t fCurMidiProgs[16];
int32_t fCurMidiProgs[MAX_MIDI_CHANNELS];


LinuxSampler::Sampler fSampler; LinuxSampler::Sampler fSampler;
LinuxSampler::Engine* fEngine; LinuxSampler::Engine* fEngine;


LinuxSampler::SamplerChannel* fSamplerChannels[16];
LinuxSampler::EngineChannel* fEngineChannels[16];
LinuxSampler::SamplerChannel* fSamplerChannels[MAX_MIDI_CHANNELS];
LinuxSampler::EngineChannel* fEngineChannels[MAX_MIDI_CHANNELS];


LinuxSampler::AudioOutputDevicePlugin* fAudioOutputDevices[16];
LinuxSampler::AudioOutputDevicePlugin* fAudioOutputDevice;
LinuxSampler::MidiInputDevicePlugin* fMidiInputDevice; LinuxSampler::MidiInputDevicePlugin* fMidiInputDevice;
LinuxSampler::MidiInputPortPlugin* fMidiInputPort; LinuxSampler::MidiInputPortPlugin* fMidiInputPort;




Loading…
Cancel
Save