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