| @@ -1294,7 +1294,7 @@ public: | |||
| { | |||
| for (k=0; k < frames; k++) | |||
| { | |||
| if (aOut.count == 1) | |||
| if (aIn.count == 1) | |||
| outBuffer[i][k] = (outBuffer[i][k]*x_dryWet)+(inBuffer[0][k]*(1.0-x_dryWet)); | |||
| else | |||
| outBuffer[i][k] = (outBuffer[i][k]*x_dryWet)+(inBuffer[i][k]*(1.0-x_dryWet)); | |||
| @@ -233,6 +233,10 @@ public: | |||
| #endif | |||
| m_ctrlInChannel = 0; | |||
| m_latency = 0; | |||
| m_tempBufferIn = nullptr; | |||
| m_tempBufferOut = nullptr; | |||
| #ifndef BUILD_BRIDGE | |||
| osc.data.path = nullptr; | |||
| osc.data.source = nullptr; | |||
| @@ -305,6 +309,22 @@ public: | |||
| custom.clear(); | |||
| } | |||
| if (m_tempBufferIn) | |||
| { | |||
| for (uint32_t i=0; i < aIn.count; i++) | |||
| delete[] m_tempBufferIn[i]; | |||
| delete[] m_tempBufferIn; | |||
| } | |||
| if (m_tempBufferOut) | |||
| { | |||
| for (uint32_t i=0; i < aOut.count; i++) | |||
| delete[] m_tempBufferOut[i]; | |||
| delete[] m_tempBufferOut; | |||
| } | |||
| m_count -= 1; | |||
| } | |||
| @@ -1367,7 +1387,49 @@ public: | |||
| */ | |||
| virtual void bufferSizeChanged(const uint32_t newBufferSize) | |||
| { | |||
| Q_UNUSED(newBufferSize); | |||
| recreateTempBuffers(newBufferSize); | |||
| } | |||
| /*! | |||
| * Recreate temporary audio buffers. | |||
| */ | |||
| void recreateTempBuffers(const uint32_t bufferSize) | |||
| { | |||
| if (m_tempBufferIn) | |||
| { | |||
| for (uint32_t i=0; i < aIn.count; i++) | |||
| delete[] m_tempBufferIn[i]; | |||
| delete[] m_tempBufferIn; | |||
| } | |||
| if (m_tempBufferOut) | |||
| { | |||
| for (uint32_t i=0; i < aOut.count; i++) | |||
| delete[] m_tempBufferOut[i]; | |||
| delete[] m_tempBufferOut; | |||
| } | |||
| if (aIn.count > 0) | |||
| { | |||
| m_tempBufferIn = new float* [aIn.count]; | |||
| for (uint32_t i=0; i < aIn.count; i++) | |||
| m_tempBufferIn[i] = new float [bufferSize]; | |||
| } | |||
| else | |||
| m_tempBufferIn = nullptr; | |||
| if (aOut.count > 0) | |||
| { | |||
| m_tempBufferOut = new float* [aOut.count]; | |||
| for (uint32_t i=0; i < aOut.count; i++) | |||
| m_tempBufferOut[i] = new float [bufferSize]; | |||
| } | |||
| else | |||
| m_tempBufferOut = nullptr; | |||
| } | |||
| // ------------------------------------------------------------------- | |||
| @@ -2177,7 +2239,11 @@ protected: | |||
| const char* m_name; | |||
| const char* m_filename; | |||
| int8_t m_ctrlInChannel; | |||
| int8_t m_ctrlInChannel; | |||
| uint32_t m_latency; | |||
| float** m_tempBufferIn; | |||
| float** m_tempBufferOut; | |||
| // ------------------------------------------------------------------- | |||
| // Storage Data | |||
| @@ -699,7 +699,7 @@ public: | |||
| // check latency | |||
| { | |||
| bool hasLatency = false; | |||
| uint32_t latency = 0; | |||
| m_latency = 0; | |||
| for (uint32_t i=0; i < param.count; i++) | |||
| { | |||
| @@ -731,7 +731,7 @@ public: | |||
| ldescriptor->run(handle, 2); | |||
| ldescriptor->deactivate(handle); | |||
| latency = rint(paramBuffers[i]); | |||
| m_latency = rint(paramBuffers[i]); | |||
| hasLatency = true; | |||
| break; | |||
| } | |||
| @@ -740,7 +740,7 @@ public: | |||
| if (hasLatency) | |||
| { | |||
| for (uint32_t i=0; i < aIn.count; i++) | |||
| aIn.ports[i]->setLatency(latency); | |||
| aIn.ports[i]->setLatency(m_latency); | |||
| x_client->recomputeLatencies(); | |||
| } | |||
| @@ -748,6 +748,7 @@ public: | |||
| reloadPrograms(true); | |||
| recreateTempBuffers(x_engine->getBufferSize()); | |||
| x_client->activate(); | |||
| qDebug("DssiPlugin::reload() - end"); | |||
| @@ -1303,7 +1304,7 @@ public: | |||
| { | |||
| for (k=0; k < frames; k++) | |||
| { | |||
| if (aOut.count == 1) | |||
| if (aIn.count == 1) | |||
| outBuffer[i][k] = (outBuffer[i][k]*x_dryWet)+(inBuffer[0][k]*(1.0-x_dryWet)); | |||
| else | |||
| outBuffer[i][k] = (outBuffer[i][k]*x_dryWet)+(inBuffer[i][k]*(1.0-x_dryWet)); | |||
| @@ -668,7 +668,7 @@ public: | |||
| // check latency | |||
| { | |||
| bool hasLatency = false; | |||
| uint32_t latency = 0; | |||
| m_latency = 0; | |||
| for (uint32_t i=0; i < param.count; i++) | |||
| { | |||
| @@ -700,7 +700,7 @@ public: | |||
| descriptor->run(handle, 2); | |||
| descriptor->deactivate(handle); | |||
| latency = rint(paramBuffers[i]); | |||
| m_latency = rint(paramBuffers[i]); | |||
| hasLatency = true; | |||
| break; | |||
| } | |||
| @@ -709,12 +709,13 @@ public: | |||
| if (hasLatency) | |||
| { | |||
| for (uint32_t i=0; i < aIn.count; i++) | |||
| aIn.ports[i]->setLatency(latency); | |||
| aIn.ports[i]->setLatency(m_latency); | |||
| x_client->recomputeLatencies(); | |||
| } | |||
| } | |||
| recreateTempBuffers(x_engine->getBufferSize()); | |||
| x_client->activate(); | |||
| qDebug("LadspaPlugin::reload() - end"); | |||
| @@ -979,7 +980,7 @@ public: | |||
| { | |||
| for (k=0; k < frames; k++) | |||
| { | |||
| if (aOut.count == 1) | |||
| if (aIn.count == 1) | |||
| outBuffer[i][k] = (outBuffer[i][k]*x_dryWet)+(inBuffer[0][k]*(1.0-x_dryWet)); | |||
| else | |||
| outBuffer[i][k] = (outBuffer[i][k]*x_dryWet)+(inBuffer[i][k]*(1.0-x_dryWet)); | |||
| @@ -1740,7 +1740,7 @@ public: | |||
| // check latency | |||
| { | |||
| bool hasLatency = false; | |||
| uint32_t latency = 0; | |||
| m_latency = 0; | |||
| for (uint32_t i=0; i < param.count; i++) | |||
| { | |||
| @@ -1763,7 +1763,7 @@ public: | |||
| descriptor->run(handle, 0); | |||
| descriptor->deactivate(handle); | |||
| latency = rint(paramBuffers[i]); | |||
| m_latency = rint(paramBuffers[i]); | |||
| hasLatency = true; | |||
| break; | |||
| } | |||
| @@ -1772,7 +1772,7 @@ public: | |||
| if (hasLatency) | |||
| { | |||
| for (uint32_t i=0; i < aIn.count; i++) | |||
| aIn.ports[i]->setLatency(latency); | |||
| aIn.ports[i]->setLatency(m_latency); | |||
| x_client->recomputeLatencies(); | |||
| } | |||
| @@ -1780,6 +1780,7 @@ public: | |||
| reloadPrograms(true); | |||
| recreateTempBuffers(x_engine->getBufferSize()); | |||
| x_client->activate(); | |||
| qDebug("Lv2Plugin::reload() - end"); | |||
| @@ -2580,7 +2581,7 @@ public: | |||
| { | |||
| for (k=0; k < frames; k++) | |||
| { | |||
| if (aOut.count == 1) | |||
| if (aIn.count == 1) | |||
| outBuffer[i][k] = (outBuffer[i][k]*x_dryWet)+(inBuffer[0][k]*(1.0-x_dryWet)); | |||
| else | |||
| outBuffer[i][k] = (outBuffer[i][k]*x_dryWet)+(inBuffer[i][k]*(1.0-x_dryWet)); | |||
| @@ -2761,6 +2762,8 @@ public: | |||
| void bufferSizeChanged(const uint32_t newBufferSize) | |||
| { | |||
| lv2Options.bufferSize = newBufferSize; | |||
| CarlaPlugin::bufferSizeChanged(newBufferSize); | |||
| } | |||
| // ------------------------------------------------------------------- | |||
| @@ -734,19 +734,20 @@ public: | |||
| #ifdef VESTIGE_HEADER | |||
| char* const empty3Ptr = &effect->empty3[0]; | |||
| int32_t* initialDelayPtr = (int32_t*)empty3Ptr; | |||
| uint32_t latency = *initialDelayPtr; | |||
| m_latency = *initialDelayPtr; | |||
| #else | |||
| uint32_t latency = effect->initialDelay; | |||
| m_latency = effect->initialDelay; | |||
| #endif | |||
| for (uint32_t i=0; i < aIn.count; i++) | |||
| aIn.ports[i]->setLatency(latency); | |||
| aIn.ports[i]->setLatency(m_latency); | |||
| x_client->recomputeLatencies(); | |||
| } | |||
| reloadPrograms(true); | |||
| recreateTempBuffers(x_engine->getBufferSize()); | |||
| x_client->activate(); | |||
| qDebug("VstPlugin::reload() - end"); | |||
| @@ -1209,6 +1210,12 @@ public: | |||
| midiEventCount = MAX_MIDI_CHANNELS*2; | |||
| } | |||
| for (i=0; i < aIn.count; i++) | |||
| memset(m_tempBufferIn[i], 0, sizeof(float)*x_engine->getBufferSize()); | |||
| for (i=0; i < aOut.count; i++) | |||
| memset(m_tempBufferOut[i], 0, sizeof(float)*x_engine->getBufferSize()); | |||
| effect->dispatcher(effect, effStartProcess, 0, 0, nullptr, 0.0f); | |||
| } | |||
| @@ -1260,7 +1267,7 @@ public: | |||
| bool do_balance = (m_hints & PLUGIN_CAN_BALANCE) > 0 && (x_balanceLeft != -1.0 || x_balanceRight != 1.0); | |||
| double bal_rangeL, bal_rangeR; | |||
| float oldBufLeft[do_balance ? frames : 0]; | |||
| float bufValue, oldBufLeft[do_balance ? frames : 0]; | |||
| for (i=0; i < aOut.count; i++) | |||
| { | |||
| @@ -1269,10 +1276,12 @@ public: | |||
| { | |||
| for (k=0; k < frames; k++) | |||
| { | |||
| if (aOut.count == 1) | |||
| outBuffer[i][k] = (outBuffer[i][k]*x_dryWet)+(inBuffer[0][k]*(1.0-x_dryWet)); | |||
| if (k < m_latency && m_latency < frames) | |||
| bufValue = (aIn.count == 1) ? m_tempBufferIn[0][k] : m_tempBufferIn[i][k]; | |||
| else | |||
| outBuffer[i][k] = (outBuffer[i][k]*x_dryWet)+(inBuffer[i][k]*(1.0-x_dryWet)); | |||
| bufValue = (aIn.count == 1) ? inBuffer[0][k-m_latency] : inBuffer[i][k-m_latency]; | |||
| outBuffer[i][k] = (outBuffer[i][k]*x_dryWet)+(bufValue*(1.0-x_dryWet)); | |||
| } | |||
| } | |||
| @@ -1316,6 +1325,13 @@ public: | |||
| aOutsPeak[i] = abs(outBuffer[i][k]); | |||
| } | |||
| } | |||
| // Latency, save values for next callback | |||
| if (m_latency > 0 && m_latency < frames) | |||
| { | |||
| for (i=0; i < aIn.count; i++) | |||
| memcpy(m_tempBufferIn[i], inBuffer[i] + (frames - m_latency), sizeof(float)*m_latency); | |||
| } | |||
| } | |||
| else | |||
| { | |||
| @@ -1376,6 +1392,8 @@ public: | |||
| if (m_active) | |||
| effect->dispatcher(effect, effStartProcess, 0, 0, nullptr, 0.0f); | |||
| CarlaPlugin::bufferSizeChanged(newBufferSize); | |||
| } | |||
| // ------------------------------------------------------------------- | |||