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_WANT_MIDI_INPUT || 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_STATEFILES isStateFile(const uint32_t index) const490 bool isStateFile(const uint32_t index) const 491 { 492 DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr && index < fData->stateCount, false); 493 494 return fPlugin->isStateFile(index); 495 } 496 # endif 497 498 # if DISTRHO_PLUGIN_WANT_FULL_STATE getState(const char * key) const499 String getState(const char* key) const 500 { 501 DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr, sFallbackString); 502 DISTRHO_SAFE_ASSERT_RETURN(key != nullptr && key[0] != '\0', sFallbackString); 503 504 return fPlugin->getState(key); 505 } 506 # endif 507 setState(const char * const key,const char * const value)508 void setState(const char* const key, const char* const value) 509 { 510 DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr,); 511 DISTRHO_SAFE_ASSERT_RETURN(key != nullptr && key[0] != '\0',); 512 DISTRHO_SAFE_ASSERT_RETURN(value != nullptr,); 513 514 fPlugin->setState(key, value); 515 } 516 wantStateKey(const char * const key) const517 bool wantStateKey(const char* const key) const noexcept 518 { 519 DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr, false); 520 DISTRHO_SAFE_ASSERT_RETURN(key != nullptr && key[0] != '\0', false); 521 522 for (uint32_t i=0; i < fData->stateCount; ++i) 523 { 524 if (fData->stateKeys[i] == key) 525 return true; 526 } 527 528 return false; 529 } 530 #endif 531 532 #if DISTRHO_PLUGIN_WANT_TIMEPOS setTimePosition(const TimePosition & timePosition)533 void setTimePosition(const TimePosition& timePosition) noexcept 534 { 535 DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr,); 536 537 std::memcpy(&fData->timePosition, &timePosition, sizeof(TimePosition)); 538 } 539 #endif 540 541 // ------------------------------------------------------------------- 542 isActive() const543 bool isActive() const noexcept 544 { 545 return fIsActive; 546 } 547 activate()548 void activate() 549 { 550 DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr,); 551 DISTRHO_SAFE_ASSERT_RETURN(! fIsActive,); 552 553 fIsActive = true; 554 fPlugin->activate(); 555 } 556 deactivate()557 void deactivate() 558 { 559 DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr,); 560 DISTRHO_SAFE_ASSERT_RETURN(fIsActive,); 561 562 fIsActive = false; 563 fPlugin->deactivate(); 564 } 565 deactivateIfNeeded()566 void deactivateIfNeeded() 567 { 568 DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr,); 569 570 if (fIsActive) 571 { 572 fIsActive = false; 573 fPlugin->deactivate(); 574 } 575 } 576 577 #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)578 void run(const float** const inputs, float** const outputs, const uint32_t frames, 579 const MidiEvent* const midiEvents, const uint32_t midiEventCount) 580 { 581 DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr,); 582 DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr,); 583 584 if (! fIsActive) 585 { 586 fIsActive = true; 587 fPlugin->activate(); 588 } 589 590 fData->isProcessing = true; 591 fPlugin->run(inputs, outputs, frames, midiEvents, midiEventCount); 592 fData->isProcessing = false; 593 } 594 #else run(const float ** const inputs,float ** const outputs,const uint32_t frames)595 void run(const float** const inputs, float** const outputs, const uint32_t frames) 596 { 597 DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr,); 598 DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr,); 599 600 if (! fIsActive) 601 { 602 fIsActive = true; 603 fPlugin->activate(); 604 } 605 606 fData->isProcessing = true; 607 fPlugin->run(inputs, outputs, frames); 608 fData->isProcessing = false; 609 } 610 #endif 611 612 // ------------------------------------------------------------------- 613 getBufferSize() const614 uint32_t getBufferSize() const noexcept 615 { 616 DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr, 0); 617 return fData->bufferSize; 618 } 619 getSampleRate() const620 double getSampleRate() const noexcept 621 { 622 DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr, 0.0); 623 return fData->sampleRate; 624 } 625 setBufferSize(const uint32_t bufferSize,const bool doCallback=false)626 void setBufferSize(const uint32_t bufferSize, const bool doCallback = false) 627 { 628 DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr,); 629 DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr,); 630 DISTRHO_SAFE_ASSERT(bufferSize >= 2); 631 632 if (fData->bufferSize == bufferSize) 633 return; 634 635 fData->bufferSize = bufferSize; 636 637 if (doCallback) 638 { 639 if (fIsActive) fPlugin->deactivate(); 640 fPlugin->bufferSizeChanged(bufferSize); 641 if (fIsActive) fPlugin->activate(); 642 } 643 } 644 setSampleRate(const double sampleRate,const bool doCallback=false)645 void setSampleRate(const double sampleRate, const bool doCallback = false) 646 { 647 DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr,); 648 DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr,); 649 DISTRHO_SAFE_ASSERT(sampleRate > 0.0); 650 651 if (d_isEqual(fData->sampleRate, sampleRate)) 652 return; 653 654 fData->sampleRate = sampleRate; 655 656 if (doCallback) 657 { 658 if (fIsActive) fPlugin->deactivate(); 659 fPlugin->sampleRateChanged(sampleRate); 660 if (fIsActive) fPlugin->activate(); 661 } 662 } 663 664 private: 665 // ------------------------------------------------------------------- 666 // Plugin and DistrhoPlugin data 667 668 Plugin* const fPlugin; 669 Plugin::PrivateData* const fData; 670 bool fIsActive; 671 672 // ------------------------------------------------------------------- 673 // Static fallback data, see DistrhoPlugin.cpp 674 675 static const String sFallbackString; 676 static const AudioPort sFallbackAudioPort; 677 static const ParameterRanges sFallbackRanges; 678 static const ParameterEnumerationValues sFallbackEnumValues; 679 680 DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PluginExporter) 681 DISTRHO_PREVENT_HEAP_ALLOCATION 682 }; 683 684 // ----------------------------------------------------------------------- 685 686 END_NAMESPACE_DISTRHO 687 688 #endif // DISTRHO_PLUGIN_INTERNAL_HPP_INCLUDED 689