1 /* 2 * DISTRHO Plugin Framework (DPF) 3 * Copyright (C) 2012-2018 Filipe Coelho <falktx@falktx.com> 4 * 5 * Permission to use, copy, modify, and/or distribute this software for any purpose with 6 * or without fee is hereby granted, provided that the above copyright notice and this 7 * permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD 10 * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN 11 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 12 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 13 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17 #ifndef DISTRHO_PLUGIN_INTERNAL_HPP_INCLUDED 18 #define DISTRHO_PLUGIN_INTERNAL_HPP_INCLUDED 19 20 #include "../DistrhoPlugin.hpp" 21 22 START_NAMESPACE_DISTRHO 23 24 // ----------------------------------------------------------------------- 25 // Maxmimum values 26 27 static const uint32_t kMaxMidiEvents = 512; 28 29 // ----------------------------------------------------------------------- 30 // Static data, see DistrhoPlugin.cpp 31 32 extern uint32_t d_lastBufferSize; 33 extern double d_lastSampleRate; 34 35 // ----------------------------------------------------------------------- 36 // DSP callbacks 37 38 typedef bool (*writeMidiFunc) (void* ptr, const MidiEvent& midiEvent); 39 40 // ----------------------------------------------------------------------- 41 // Plugin private data 42 43 struct Plugin::PrivateData { 44 bool isProcessing; 45 46 #if DISTRHO_PLUGIN_NUM_INPUTS+DISTRHO_PLUGIN_NUM_OUTPUTS > 0 47 AudioPort* audioPorts; 48 #endif 49 50 uint32_t parameterCount; 51 uint32_t parameterOffset; 52 Parameter* parameters; 53 54 #if DISTRHO_PLUGIN_WANT_PROGRAMS 55 uint32_t programCount; 56 String* programNames; 57 #endif 58 59 #if DISTRHO_PLUGIN_WANT_STATE 60 uint32_t stateCount; 61 String* stateKeys; 62 String* stateDefValues; 63 #endif 64 65 #if DISTRHO_PLUGIN_WANT_LATENCY 66 uint32_t latency; 67 #endif 68 69 #if DISTRHO_PLUGIN_WANT_TIMEPOS 70 TimePosition timePosition; 71 #endif 72 73 // Callbacks 74 void* callbacksPtr; 75 writeMidiFunc writeMidiCallbackFunc; 76 77 uint32_t bufferSize; 78 double sampleRate; 79 PrivateDataPlugin::PrivateData80 PrivateData() noexcept 81 : isProcessing(false), 82 #if DISTRHO_PLUGIN_NUM_INPUTS+DISTRHO_PLUGIN_NUM_OUTPUTS > 0 83 audioPorts(nullptr), 84 #endif 85 parameterCount(0), 86 parameterOffset(0), 87 parameters(nullptr), 88 #if DISTRHO_PLUGIN_WANT_PROGRAMS 89 programCount(0), 90 programNames(nullptr), 91 #endif 92 #if DISTRHO_PLUGIN_WANT_STATE 93 stateCount(0), 94 stateKeys(nullptr), 95 stateDefValues(nullptr), 96 #endif 97 #if DISTRHO_PLUGIN_WANT_LATENCY 98 latency(0), 99 #endif 100 callbacksPtr(nullptr), 101 writeMidiCallbackFunc(nullptr), 102 bufferSize(d_lastBufferSize), 103 sampleRate(d_lastSampleRate) 104 { 105 DISTRHO_SAFE_ASSERT(bufferSize != 0); 106 DISTRHO_SAFE_ASSERT(d_isNotZero(sampleRate)); 107 108 #if defined(DISTRHO_PLUGIN_TARGET_DSSI) || defined(DISTRHO_PLUGIN_TARGET_LV2) 109 parameterOffset += DISTRHO_PLUGIN_NUM_INPUTS + DISTRHO_PLUGIN_NUM_OUTPUTS; 110 # if DISTRHO_PLUGIN_WANT_LATENCY 111 parameterOffset += 1; 112 # endif 113 #endif 114 115 #ifdef DISTRHO_PLUGIN_TARGET_LV2 116 # if (DISTRHO_PLUGIN_IS_SYNTH || DISTRHO_PLUGIN_WANT_TIMEPOS || DISTRHO_PLUGIN_WANT_STATE) 117 parameterOffset += 1; 118 # if DISTRHO_PLUGIN_WANT_STATE 119 parameterOffset += 1; 120 # endif 121 # endif 122 #endif 123 } 124 ~PrivateDataPlugin::PrivateData125 ~PrivateData() noexcept 126 { 127 #if DISTRHO_PLUGIN_NUM_INPUTS+DISTRHO_PLUGIN_NUM_OUTPUTS > 0 128 if (audioPorts != nullptr) 129 { 130 delete[] audioPorts; 131 audioPorts = nullptr; 132 } 133 #endif 134 135 if (parameters != nullptr) 136 { 137 delete[] parameters; 138 parameters = nullptr; 139 } 140 141 #if DISTRHO_PLUGIN_WANT_PROGRAMS 142 if (programNames != nullptr) 143 { 144 delete[] programNames; 145 programNames = nullptr; 146 } 147 #endif 148 149 #if DISTRHO_PLUGIN_WANT_STATE 150 if (stateKeys != nullptr) 151 { 152 delete[] stateKeys; 153 stateKeys = nullptr; 154 } 155 156 if (stateDefValues != nullptr) 157 { 158 delete[] stateDefValues; 159 stateDefValues = nullptr; 160 } 161 #endif 162 } 163 164 #if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT writeMidiCallbackPlugin::PrivateData165 bool writeMidiCallback(const MidiEvent& midiEvent) 166 { 167 if (writeMidiCallbackFunc != nullptr) 168 return writeMidiCallbackFunc(callbacksPtr, midiEvent); 169 170 return false; 171 } 172 #endif 173 }; 174 175 // ----------------------------------------------------------------------- 176 // Plugin exporter class 177 178 class PluginExporter 179 { 180 public: PluginExporter(void * const callbacksPtr,const writeMidiFunc writeMidiCall)181 PluginExporter(void* const callbacksPtr, const writeMidiFunc writeMidiCall) 182 : fPlugin(createPlugin()), 183 fData((fPlugin != nullptr) ? fPlugin->pData : nullptr), 184 fIsActive(false) 185 { 186 DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr,); 187 DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr,); 188 189 #if DISTRHO_PLUGIN_NUM_INPUTS+DISTRHO_PLUGIN_NUM_OUTPUTS > 0 190 { 191 uint32_t j=0; 192 # if DISTRHO_PLUGIN_NUM_INPUTS > 0 193 for (uint32_t i=0; i < DISTRHO_PLUGIN_NUM_INPUTS; ++i, ++j) 194 fPlugin->initAudioPort(true, i, fData->audioPorts[j]); 195 # endif 196 # if DISTRHO_PLUGIN_NUM_OUTPUTS > 0 197 for (uint32_t i=0; i < DISTRHO_PLUGIN_NUM_OUTPUTS; ++i, ++j) 198 fPlugin->initAudioPort(false, i, fData->audioPorts[j]); 199 # endif 200 } 201 #endif 202 203 for (uint32_t i=0, count=fData->parameterCount; i < count; ++i) 204 fPlugin->initParameter(i, fData->parameters[i]); 205 206 #if DISTRHO_PLUGIN_WANT_PROGRAMS 207 for (uint32_t i=0, count=fData->programCount; i < count; ++i) 208 fPlugin->initProgramName(i, fData->programNames[i]); 209 #endif 210 211 #if DISTRHO_PLUGIN_WANT_STATE 212 for (uint32_t i=0, count=fData->stateCount; i < count; ++i) 213 fPlugin->initState(i, fData->stateKeys[i], fData->stateDefValues[i]); 214 #endif 215 216 fData->callbacksPtr = callbacksPtr; 217 fData->writeMidiCallbackFunc = writeMidiCall; 218 } 219 ~PluginExporter()220 ~PluginExporter() 221 { 222 delete fPlugin; 223 } 224 225 // ------------------------------------------------------------------- 226 getName() const227 const char* getName() const noexcept 228 { 229 DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr, ""); 230 231 return fPlugin->getName(); 232 } 233 getLabel() const234 const char* getLabel() const noexcept 235 { 236 DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr, ""); 237 238 return fPlugin->getLabel(); 239 } 240 getDescription() const241 const char* getDescription() const noexcept 242 { 243 DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr, ""); 244 245 return fPlugin->getDescription(); 246 } 247 getMaker() const248 const char* getMaker() const noexcept 249 { 250 DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr, ""); 251 252 return fPlugin->getMaker(); 253 } 254 getHomePage() const255 const char* getHomePage() const noexcept 256 { 257 DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr, ""); 258 259 return fPlugin->getHomePage(); 260 } 261 getLicense() const262 const char* getLicense() const noexcept 263 { 264 DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr, ""); 265 266 return fPlugin->getLicense(); 267 } 268 getVersion() const269 uint32_t getVersion() const noexcept 270 { 271 DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr, 0); 272 273 return fPlugin->getVersion(); 274 } 275 getUniqueId() const276 long getUniqueId() const noexcept 277 { 278 DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr, 0); 279 280 return fPlugin->getUniqueId(); 281 } 282 getInstancePointer() const283 void* getInstancePointer() const noexcept 284 { 285 return fPlugin; 286 } 287 288 // ------------------------------------------------------------------- 289 290 #if DISTRHO_PLUGIN_WANT_LATENCY getLatency() const291 uint32_t getLatency() const noexcept 292 { 293 DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr, 0); 294 295 return fData->latency; 296 } 297 #endif 298 299 #if DISTRHO_PLUGIN_NUM_INPUTS+DISTRHO_PLUGIN_NUM_OUTPUTS > 0 getAudioPort(const bool input,const uint32_t index) const300 const AudioPort& getAudioPort(const bool input, const uint32_t index) const noexcept 301 { 302 DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr, sFallbackAudioPort); 303 304 if (input) 305 { 306 # if DISTRHO_PLUGIN_NUM_INPUTS > 0 307 DISTRHO_SAFE_ASSERT_RETURN(index < DISTRHO_PLUGIN_NUM_INPUTS, sFallbackAudioPort); 308 # endif 309 } 310 else 311 { 312 # if DISTRHO_PLUGIN_NUM_OUTPUTS > 0 313 DISTRHO_SAFE_ASSERT_RETURN(index < DISTRHO_PLUGIN_NUM_OUTPUTS, sFallbackAudioPort); 314 # endif 315 } 316 317 return fData->audioPorts[index + (input ? 0 : DISTRHO_PLUGIN_NUM_INPUTS)]; 318 } 319 #endif 320 getParameterCount() const321 uint32_t getParameterCount() const noexcept 322 { 323 DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr, 0); 324 325 return fData->parameterCount; 326 } 327 getParameterOffset() const328 uint32_t getParameterOffset() const noexcept 329 { 330 DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr, 0); 331 332 return fData->parameterOffset; 333 } 334 getParameterHints(const uint32_t index) const335 uint32_t getParameterHints(const uint32_t index) const noexcept 336 { 337 DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr && index < fData->parameterCount, 0x0); 338 339 return fData->parameters[index].hints; 340 } 341 getParameterDesignation(const uint32_t index) const342 ParameterDesignation getParameterDesignation(const uint32_t index) const noexcept 343 { 344 DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr && index < fData->parameterCount, kParameterDesignationNull); 345 346 return fData->parameters[index].designation; 347 } 348 isParameterInput(const uint32_t index) const349 bool isParameterInput(const uint32_t index) const noexcept 350 { 351 return (getParameterHints(index) & kParameterIsOutput) == 0x0; 352 } 353 isParameterOutput(const uint32_t index) const354 bool isParameterOutput(const uint32_t index) const noexcept 355 { 356 return (getParameterHints(index) & kParameterIsOutput) != 0x0; 357 } 358 isParameterOutputOrTrigger(const uint32_t index) const359 bool isParameterOutputOrTrigger(const uint32_t index) const noexcept 360 { 361 const uint32_t hints = getParameterHints(index); 362 363 if (hints & kParameterIsOutput) 364 return true; 365 if ((hints & kParameterIsTrigger) == kParameterIsTrigger) 366 return true; 367 368 return false; 369 } 370 getParameterName(const uint32_t index) const371 const String& getParameterName(const uint32_t index) const noexcept 372 { 373 DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr && index < fData->parameterCount, sFallbackString); 374 375 return fData->parameters[index].name; 376 } 377 getParameterShortName(const uint32_t index) const378 const String& getParameterShortName(const uint32_t index) const noexcept 379 { 380 DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr && index < fData->parameterCount, sFallbackString); 381 382 return fData->parameters[index].shortName; 383 } 384 getParameterSymbol(const uint32_t index) const385 const String& getParameterSymbol(const uint32_t index) const noexcept 386 { 387 DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr && index < fData->parameterCount, sFallbackString); 388 389 return fData->parameters[index].symbol; 390 } 391 getParameterUnit(const uint32_t index) const392 const String& getParameterUnit(const uint32_t index) const noexcept 393 { 394 DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr && index < fData->parameterCount, sFallbackString); 395 396 return fData->parameters[index].unit; 397 } 398 getParameterDescription(const uint32_t index) const399 const String& getParameterDescription(const uint32_t index) const noexcept 400 { 401 DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr && index < fData->parameterCount, sFallbackString); 402 403 return fData->parameters[index].description; 404 } 405 getParameterEnumValues(const uint32_t index) const406 const ParameterEnumerationValues& getParameterEnumValues(const uint32_t index) const noexcept 407 { 408 DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr && index < fData->parameterCount, sFallbackEnumValues); 409 410 return fData->parameters[index].enumValues; 411 } 412 getParameterRanges(const uint32_t index) const413 const ParameterRanges& getParameterRanges(const uint32_t index) const noexcept 414 { 415 DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr && index < fData->parameterCount, sFallbackRanges); 416 417 return fData->parameters[index].ranges; 418 } 419 getParameterMidiCC(const uint32_t index) const420 uint8_t getParameterMidiCC(const uint32_t index) const noexcept 421 { 422 DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr && index < fData->parameterCount, 0); 423 424 return fData->parameters[index].midiCC; 425 } 426 getParameterValue(const uint32_t index) const427 float getParameterValue(const uint32_t index) const 428 { 429 DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr, 0.0f); 430 DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr && index < fData->parameterCount, 0.0f); 431 432 return fPlugin->getParameterValue(index); 433 } 434 setParameterValue(const uint32_t index,const float value)435 void setParameterValue(const uint32_t index, const float value) 436 { 437 DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr,); 438 DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr && index < fData->parameterCount,); 439 440 fPlugin->setParameterValue(index, value); 441 } 442 443 #if DISTRHO_PLUGIN_WANT_PROGRAMS getProgramCount() const444 uint32_t getProgramCount() const noexcept 445 { 446 DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr, 0); 447 448 return fData->programCount; 449 } 450 getProgramName(const uint32_t index) const451 const String& getProgramName(const uint32_t index) const noexcept 452 { 453 DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr && index < fData->programCount, sFallbackString); 454 455 return fData->programNames[index]; 456 } 457 loadProgram(const uint32_t index)458 void loadProgram(const uint32_t index) 459 { 460 DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr,); 461 DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr && index < fData->programCount,); 462 463 fPlugin->loadProgram(index); 464 } 465 #endif 466 467 #if DISTRHO_PLUGIN_WANT_STATE getStateCount() const468 uint32_t getStateCount() const noexcept 469 { 470 DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr, 0); 471 472 return fData->stateCount; 473 } 474 getStateKey(const uint32_t index) const475 const String& getStateKey(const uint32_t index) const noexcept 476 { 477 DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr && index < fData->stateCount, sFallbackString); 478 479 return fData->stateKeys[index]; 480 } 481 getStateDefaultValue(const uint32_t index) const482 const String& getStateDefaultValue(const uint32_t index) const noexcept 483 { 484 DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr && index < fData->stateCount, sFallbackString); 485 486 return fData->stateDefValues[index]; 487 } 488 489 # if DISTRHO_PLUGIN_WANT_FULL_STATE getState(const char * key) const490 String getState(const char* key) const 491 { 492 DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr, sFallbackString); 493 DISTRHO_SAFE_ASSERT_RETURN(key != nullptr && key[0] != '\0', sFallbackString); 494 495 return fPlugin->getState(key); 496 } 497 # endif 498 setState(const char * const key,const char * const value)499 void setState(const char* const key, const char* const value) 500 { 501 DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr,); 502 DISTRHO_SAFE_ASSERT_RETURN(key != nullptr && key[0] != '\0',); 503 DISTRHO_SAFE_ASSERT_RETURN(value != nullptr,); 504 505 fPlugin->setState(key, value); 506 } 507 wantStateKey(const char * const key) const508 bool wantStateKey(const char* const key) const noexcept 509 { 510 DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr, false); 511 DISTRHO_SAFE_ASSERT_RETURN(key != nullptr && key[0] != '\0', false); 512 513 for (uint32_t i=0; i < fData->stateCount; ++i) 514 { 515 if (fData->stateKeys[i] == key) 516 return true; 517 } 518 519 return false; 520 } 521 #endif 522 523 #if DISTRHO_PLUGIN_WANT_TIMEPOS setTimePosition(const TimePosition & timePosition)524 void setTimePosition(const TimePosition& timePosition) noexcept 525 { 526 DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr,); 527 528 std::memcpy(&fData->timePosition, &timePosition, sizeof(TimePosition)); 529 } 530 #endif 531 532 // ------------------------------------------------------------------- 533 isActive() const534 bool isActive() const noexcept 535 { 536 return fIsActive; 537 } 538 activate()539 void activate() 540 { 541 DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr,); 542 DISTRHO_SAFE_ASSERT_RETURN(! fIsActive,); 543 544 fIsActive = true; 545 fPlugin->activate(); 546 } 547 deactivate()548 void deactivate() 549 { 550 DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr,); 551 DISTRHO_SAFE_ASSERT_RETURN(fIsActive,); 552 553 fIsActive = false; 554 fPlugin->deactivate(); 555 } 556 deactivateIfNeeded()557 void deactivateIfNeeded() 558 { 559 DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr,); 560 561 if (fIsActive) 562 { 563 fIsActive = false; 564 fPlugin->deactivate(); 565 } 566 } 567 568 #if DISTRHO_PLUGIN_WANT_MIDI_INPUT run(const float ** const inputs,float ** const outputs,const uint32_t frames,const MidiEvent * const midiEvents,const uint32_t midiEventCount)569 void run(const float** const inputs, float** const outputs, const uint32_t frames, 570 const MidiEvent* const midiEvents, const uint32_t midiEventCount) 571 { 572 DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr,); 573 DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr,); 574 575 if (! fIsActive) 576 { 577 fIsActive = true; 578 fPlugin->activate(); 579 } 580 581 fData->isProcessing = true; 582 fPlugin->run(inputs, outputs, frames, midiEvents, midiEventCount); 583 fData->isProcessing = false; 584 } 585 #else run(const float ** const inputs,float ** const outputs,const uint32_t frames)586 void run(const float** const inputs, float** const outputs, const uint32_t frames) 587 { 588 DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr,); 589 DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr,); 590 591 if (! fIsActive) 592 { 593 fIsActive = true; 594 fPlugin->activate(); 595 } 596 597 fData->isProcessing = true; 598 fPlugin->run(inputs, outputs, frames); 599 fData->isProcessing = false; 600 } 601 #endif 602 603 // ------------------------------------------------------------------- 604 getBufferSize() const605 uint32_t getBufferSize() const noexcept 606 { 607 DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr, 0); 608 return fData->bufferSize; 609 } 610 getSampleRate() const611 double getSampleRate() const noexcept 612 { 613 DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr, 0.0); 614 return fData->sampleRate; 615 } 616 setBufferSize(const uint32_t bufferSize,const bool doCallback=false)617 void setBufferSize(const uint32_t bufferSize, const bool doCallback = false) 618 { 619 DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr,); 620 DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr,); 621 DISTRHO_SAFE_ASSERT(bufferSize >= 2); 622 623 if (fData->bufferSize == bufferSize) 624 return; 625 626 fData->bufferSize = bufferSize; 627 628 if (doCallback) 629 { 630 if (fIsActive) fPlugin->deactivate(); 631 fPlugin->bufferSizeChanged(bufferSize); 632 if (fIsActive) fPlugin->activate(); 633 } 634 } 635 setSampleRate(const double sampleRate,const bool doCallback=false)636 void setSampleRate(const double sampleRate, const bool doCallback = false) 637 { 638 DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr,); 639 DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr,); 640 DISTRHO_SAFE_ASSERT(sampleRate > 0.0); 641 642 if (d_isEqual(fData->sampleRate, sampleRate)) 643 return; 644 645 fData->sampleRate = sampleRate; 646 647 if (doCallback) 648 { 649 if (fIsActive) fPlugin->deactivate(); 650 fPlugin->sampleRateChanged(sampleRate); 651 if (fIsActive) fPlugin->activate(); 652 } 653 } 654 655 private: 656 // ------------------------------------------------------------------- 657 // Plugin and DistrhoPlugin data 658 659 Plugin* const fPlugin; 660 Plugin::PrivateData* const fData; 661 bool fIsActive; 662 663 // ------------------------------------------------------------------- 664 // Static fallback data, see DistrhoPlugin.cpp 665 666 static const String sFallbackString; 667 static const AudioPort sFallbackAudioPort; 668 static const ParameterRanges sFallbackRanges; 669 static const ParameterEnumerationValues sFallbackEnumValues; 670 671 DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PluginExporter) 672 DISTRHO_PREVENT_HEAP_ALLOCATION 673 }; 674 675 // ----------------------------------------------------------------------- 676 677 END_NAMESPACE_DISTRHO 678 679 #endif // DISTRHO_PLUGIN_INTERNAL_HPP_INCLUDED 680