1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783
|
/*!********************************************************************
Audacity: A Digital Audio Editor
@file EffectInterface.h
Leland Lucius
Copyright (c) 2014, Audacity Team
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
**********************************************************************/
#ifndef __AUDACITY_EFFECTINTERFACE_H__
#define __AUDACITY_EFFECTINTERFACE_H__
#include "ComponentInterface.h"
#include "ComponentInterfaceSymbol.h"
#include "EffectAutomationParameters.h"
#include "TypedAny.h"
#include <memory>
#include <optional>
#include <type_traits>
#include <wx/event.h>
#include "Observer.h"
class ShuttleGui;
template<bool Const> class SettingsVisitorBase;
using SettingsVisitor = SettingsVisitorBase<false>;
using ConstSettingsVisitor = SettingsVisitorBase<true>;
typedef enum EffectType : int
{
EffectTypeNone,
EffectTypeHidden,
EffectTypeGenerate,
EffectTypeProcess,
EffectTypeAnalyze,
EffectTypeTool,
} EffectType;
using EffectFamilySymbol = ComponentInterfaceSymbol;
//! Non-polymorphic package of settings values common to many effects
class COMPONENTS_API EffectSettingsExtra final {
public:
static const RegistryPath &DurationKey();
const NumericFormatSymbol& GetDurationFormat() const
{ return mDurationFormat; }
void SetDurationFormat(const NumericFormatSymbol &durationFormat)
{ mDurationFormat = durationFormat; }
//! @return value is not negative
double GetDuration() const { return mDuration; }
void SetDuration(double value) { mDuration = std::max(0.0, value); }
bool GetActive() const { return mActive; }
void SetActive(bool value) { mActive = value; }
private:
NumericFormatSymbol mDurationFormat{};
double mDuration{}; //!< @invariant non-negative
bool mActive{ true };
};
//! Externalized state of a plug-in
struct EffectSettings : audacity::TypedAny<EffectSettings> {
using TypedAny::TypedAny;
EffectSettingsExtra extra;
void swap(EffectSettings &other)
{
TypedAny::swap(other);
std::swap(extra, other.extra);
}
//! Like make_any but a static member function
template<typename T, typename... Args>
static EffectSettings Make(Args &&... args)
{
return EffectSettings(std::in_place_type<T>, std::forward<Args>(args)...);
}
//! Convenience for defining overrides of
//! EffectDefinitionInterface::CopySettingsContents
template<typename T>
static bool Copy(const EffectSettings &src, EffectSettings &dst)
{
const T *pSrc = src.cast<T>();
T *pDst = dst.cast<T>();
if (pSrc && pDst) {
*pDst = *pSrc;
return true;
}
return false;
}
};
//! Hold values to send to effect output meters
class COMPONENTS_API EffectOutputs {
public:
virtual ~EffectOutputs();
virtual std::unique_ptr<EffectOutputs> Clone() const = 0;
//! Update one Outputs object from another
/*!
This may run in a worker thread, and should avoid allocating and freeing.
Even on the main thread, it must avoid relocation of members of containers.
Therefore do not grow or clear any containers, but assign the preallocated
contents of one container from another.
@param src settings to copy from; assume it comes from the same
EffectSettingsManager as *this
*/
virtual void Assign(EffectOutputs &&src) = 0;
};
//! Interface for accessing an EffectSettings that may change asynchronously in
//! another thread; to be used in the main thread, only.
/*! Updates are communicated atomically both ways. The address of Get() should
not be relied on as unchanging between calls. */
class COMPONENTS_API EffectSettingsAccess
: public std::enable_shared_from_this<EffectSettingsAccess> {
public:
//! Type of messages to send from main thread to processing
class COMPONENTS_API Message {
public:
virtual ~Message();
virtual std::unique_ptr<Message> Clone() const = 0;
//! Update one Message object from another, which is then left "empty"
/*!
This may run in a worker thread, and should avoid allocating and freeing.
Therefore do not copy, grow or clear any containers in it, but assign the
preallocated contents of *this from another, which then should be
reassigned to an initial state.
Assume that src and *this come from the same EffectInstance.
@param src settings to copy from
*/
virtual void Assign(Message &&src) = 0;
//! Combine one Message object with another, which is then left "empty"
/*!
This runs in the main thread.
Combine the contents of one message into *this, and then the other
should be reassigned to an initial state.
Assume that src and *this come from the same EffectInstance.
@param src settings to copy from
*/
virtual void Merge(Message &&src) = 0;
};
virtual ~EffectSettingsAccess();
virtual const EffectSettings &Get() = 0;
virtual void Set(EffectSettings &&settings,
std::unique_ptr<Message> pMessage = nullptr) = 0;
//! Message-only overload of Set(). In future, this should be the only one.
virtual void Set(std::unique_ptr<Message> pMessage = nullptr) = 0;
//! Make the last `Set` changes "persistent" in underlying storage
/*!
@pre called on the main thread only
*/
virtual void Flush() = 0;
//! @return whether this and the other give access to the same settings
virtual bool IsSameAs(const EffectSettingsAccess &other) const = 0;
//! Do a correct read-modify-write of settings
/*!
@param function takes EffectSettings & and its return is a unique pointer
to Message, possibly null.
If it throws an exception, then the settings will not be updated.
Thus, a strong exception safety guarantee.
*/
template<typename Function>
void ModifySettings(Function &&function) {
auto settings = this->Get();
auto result = std::forward<Function>(function)(settings);
this->Set(std::move(settings), std::move(result));
}
};
//! Implementation of EffectSettings for cases where there is only one thread.
class COMPONENTS_API SimpleEffectSettingsAccess final
: public EffectSettingsAccess {
public:
explicit SimpleEffectSettingsAccess(EffectSettings &settings)
: mSettings{settings} {}
~SimpleEffectSettingsAccess() override;
const EffectSettings &Get() override;
void Set(EffectSettings &&settings,
std::unique_ptr<Message> pMessage) override;
void Set(std::unique_ptr<Message> pMessage) override;
void Flush() override;
bool IsSameAs(const EffectSettingsAccess &other) const override;
private:
EffectSettings &mSettings;
};
/*************************************************************************************//**
\class EffectDefinitionInterface
\brief EffectDefinitionInterface is a ComponentInterface that adds some basic
read-only information about effect properties, and getting and setting of
parameters.
*******************************************************************************************/
class COMPONENTS_API EffectDefinitionInterface /* not final */
: public ComponentInterface
{
public:
//! A utility that strips spaces and CamelCases a name.
static Identifier GetSquashedName(const Identifier &ident);
virtual ~EffectDefinitionInterface();
//! Type determines how it behaves.
virtual EffectType GetType() const = 0;
//! Determines which menu it appears in; default same as GetType().
virtual EffectType GetClassification() const;
//! Report identifier and user-visible name of the effect protocol
virtual EffectFamilySymbol GetFamily() const = 0;
//! Whether the effect needs a dialog for entry of settings
virtual bool IsInteractive() const = 0;
//! Whether the effect sorts "above the line" in the menus
virtual bool IsDefault() const = 0;
//! In which versions of Audacity was an effect realtime capable?
enum class RealtimeSince : unsigned {
Never,
Since_3_2,
Always,
};
//! Since which version of Audacity has the effect supported realtime?
virtual RealtimeSince RealtimeSupport() const = 0;
//! Whether the effect supports realtime previewing (while audio is playing).
//! non-virtual
bool SupportsRealtime() const
{ return RealtimeSupport() != RealtimeSince::Never; }
//! Whether the effect has any automatable controls.
virtual bool SupportsAutomation() const = 0;
//! Whether the effect dialog should have a Debug button; default, always false.
virtual bool EnablesDebug() const;
//! Name of a page in the Audacity alpha manual, default is empty
virtual ManualPageID ManualPage() const;
//! Fully qualified local help file name, default is empty
virtual FilePath HelpPage() const;
//! Default is false
virtual bool IsHiddenFromMenus() const;
};
using OptionalMessage =
std::optional<std::unique_ptr<EffectSettingsAccess::Message>>;
/*************************************************************************************//**
\class EffectSettingsManager
\brief EffectSettingsManager is an EffectDefinitionInterface that adds a
factory function for EffectSettings, and const functions for manipulating those
settings. This externalizes certain effect state.
*******************************************************************************************/
class COMPONENTS_API EffectSettingsManager /* not final */
: public EffectDefinitionInterface
{
public:
virtual ~EffectSettingsManager();
/*! @name settings
Interface for saving and loading externalized settings.
All methods are const!
*/
//! @{
//! Produce an object holding new, independent settings
/*!
Default implementation returns an empty `any`
*/
virtual EffectSettings MakeSettings() const;
//! Update one settings object from another
/*!
This may run in a worker thread, and should avoid memory allocations.
Therefore do not copy the underlying std::any, but copy the contents of the
contained objects.
Assume that src and dst were created and previously modified only by `this`
Default implementation does nothing and returns true
@param src settings to copy from
@param dst settings to copy into
@param copyDirection direction in which copy is performed
@return success
*/
virtual bool CopySettingsContents(
const EffectSettings &src, EffectSettings &dst) const;
//! Store settings as keys and values
/*!
The override may assume `parms` is initially empty
@return true on success
*/
virtual bool SaveSettings(
const EffectSettings &settings, CommandParameters & parms) const = 0;
//! Restore settings from keys and values
/*!
@return true on success
*/
virtual bool LoadSettings(
const CommandParameters & parms, EffectSettings &settings) const = 0;
//! Report names of factory presets
virtual RegistryPaths GetFactoryPresets() const = 0;
//! Change settings to a user-named preset
//! @return nullopt for failure
[[nodiscard]] virtual OptionalMessage LoadUserPreset(
const RegistryPath & name, EffectSettings &settings) const = 0;
//! Save settings in the configuration file as a user-named preset
virtual bool SaveUserPreset(
const RegistryPath & name, const EffectSettings &settings) const = 0;
//! Change settings to the preset whose name is `GetFactoryPresets()[id]`
//! @return nullopt for failure
[[nodiscard]] virtual OptionalMessage LoadFactoryPreset(
int id, EffectSettings &settings) const = 0;
//! Change settings back to "factory default"
//! @return nullopt for failure
[[nodiscard]] virtual OptionalMessage LoadFactoryDefaults(
EffectSettings &settings) const = 0;
//! @}
//! Visit settings (and maybe change them), if defined.
//! false means no defined settings.
//! Default implementation returns false
virtual bool VisitSettings(
SettingsVisitor &visitor, EffectSettings &settings); // TODO const
//! Visit settings (read-only), if defined.
//! false means no defined settings.
//! Default implementation returns false
virtual bool VisitSettings(
ConstSettingsVisitor &visitor, const EffectSettings &settings) const;
/*! @name outputs
@{
*/
//! Produce an object to hold values to send to effect output meters
/*!
Default implementation returns nullptr
*/
virtual std::unique_ptr<EffectOutputs> MakeOutputs() const;
//! @}
};
class wxDialog;
class wxWindow;
class EffectUIClientInterface;
// ----------------------------------------------------------------------------
// Supported channel assignments
// ----------------------------------------------------------------------------
enum ChannelName : int {
// Use to mark end of list
ChannelNameEOL = -1,
// The default channel assignment
ChannelNameMono,
// From this point, the channels follow the 22.2 surround sound format
ChannelNameFrontLeft,
ChannelNameFrontRight,
ChannelNameFrontCenter,
ChannelNameLowFrequency1,
ChannelNameBackLeft,
ChannelNameBackRight,
ChannelNameFrontLeftCenter,
ChannelNameFrontRightCenter,
ChannelNameBackCenter,
ChannelNameLowFrequency2,
ChannelNameSideLeft,
ChannelNameSideRight,
ChannelNameTopFrontLeft,
ChannelNameTopFrontRight,
ChannelNameTopFrontCenter,
ChannelNameTopCenter,
ChannelNameTopBackLeft,
ChannelNameTopBackRight,
ChannelNameTopSideLeft,
ChannelNameTopSideRight,
ChannelNameTopBackCenter,
ChannelNameBottomFrontCenter,
ChannelNameBottomFrontLeft,
ChannelNameBottomFrontRight,
};
using ChannelNames = const ChannelName *;
/***************************************************************************//**
\class EffectInstance
@brief Performs effect computation
*******************************************************************************/
class COMPONENTS_API EffectInstance
: public std::enable_shared_from_this<EffectInstance>
{
public:
virtual ~EffectInstance();
//! Call once to set up state for whole list of tracks to be processed
/*!
@return success
Default implementation does nothing, returns true
*/
virtual bool Init();
//! Actually do the effect here.
/*!
@return success
*/
virtual bool Process(EffectSettings &settings) = 0;
virtual size_t GetBlockSize() const = 0;
// Suggest a block size, but the return is the size that was really set:
virtual size_t SetBlockSize(size_t maxBlockSize) = 0;
//! How many input buffers to allocate at once
/*!
If the instance processes channels independently, this can return 1
The result is not necessarily well defined before `RealtimeInitialize`
*/
virtual unsigned GetAudioInCount() const = 0;
//! How many output buffers to allocate at once
/*!
The result is not necessarily well defined before `RealtimeInitialize`
*/
virtual unsigned GetAudioOutCount() const = 0;
/*!
@return success
@post `GetAudioInCount()` and `GetAudioOutCount()` are well defined
Default implementation does nothing, returns false (so assume realtime is
not supported).
Other member functions related to realtime return true or zero, but will not
be called, unless a derived class overrides RealtimeInitialize.
*/
virtual bool RealtimeInitialize(EffectSettings &settings, double sampleRate);
/*!
@return success
Default implementation does nothing, returns true
*/
virtual bool RealtimeAddProcessor(
EffectSettings &settings, EffectOutputs *pOutputs,
unsigned numChannels, float sampleRate);
/*!
@return success
Default implementation does nothing, returns true
*/
virtual bool RealtimeSuspend();
/*!
@return success
Default implementation does nothing, returns true
*/
virtual bool RealtimeResume();
//! Type of messages to send from main thread to processing, which can
//! describe the transitions of settings (instead of their states)
using Message = EffectSettingsAccess::Message;
//! Called on the main thread, in which the result may be cloned
/*! Default implementation returns a null */
virtual std::unique_ptr<Message> MakeMessage() const;
// TODO make it just an alias for Message *
struct MessagePackage { EffectSettings &settings; Message *pMessage{}; };
//! If true, the effect makes no use EffectSettings for inter-thread
//! comminication
/*!
Default implementation returns false. In future, all effects should be
rewritten to use messages and this function will be removed.
*/
virtual bool UsesMessages() const noexcept;
//! settings are possibly changed, since last call, by an asynchronous dialog
/*!
@return success
Default implementation does nothing, returns true
*/
virtual bool RealtimeProcessStart(MessagePackage &package);
/*!
@return success
Default implementation does nothing, returns 0
*/
virtual size_t RealtimeProcess(size_t group, EffectSettings &settings,
const float *const *inBuf, float *const *outBuf, size_t numSamples);
//! settings can be updated to let a dialog change appearance at idle
/*!
@return success
Default implementation does nothing, returns true
*/
virtual bool RealtimeProcessEnd(EffectSettings &settings) noexcept;
/*!
@return success
Default implementation does nothing, returns true
*/
virtual bool RealtimeFinalize(EffectSettings &settings) noexcept;
//! Function that has not yet found a use
//! Correct definitions of it will likely depend on settings and state
virtual size_t GetTailSize() const;
using SampleCount = uint64_t;
/*!
Default implementation returns 0
*/
virtual SampleCount GetLatency(
const EffectSettings &settings, double sampleRate) const;
};
/***************************************************************************//**
\class EffectInstanceEx
@brief Performs effect computation
*******************************************************************************/
class COMPONENTS_API EffectInstanceEx : public virtual EffectInstance {
public:
~EffectInstanceEx() override;
//! Called at start of destructive processing, for each (mono/stereo) track
//! Default implementation does nothing, returns true
/*!
@param chanMap null or array terminated with ChannelNameEOL. Do not retain
the pointer
@post `GetAudioInCount()` and `GetAudioOutCount()` are well defined
*/
virtual bool ProcessInitialize(EffectSettings &settings,
double sampleRate, ChannelNames chanMap) = 0;
//! Called at end of destructive processing, for each (mono/stereo) track
//! Default implementation does nothing, returns true
//! This may be called during stack unwinding:
virtual bool ProcessFinalize() noexcept = 0;
//! Called for destructive effect computation
virtual size_t ProcessBlock(EffectSettings &settings,
const float *const *inBlock, float *const *outBlock, size_t blockLen)
= 0;
};
//! Inherit to add a state variable to an EffectInstance subclass
class COMPONENTS_API EffectInstanceWithBlockSize
: public virtual EffectInstance
{
public:
~EffectInstanceWithBlockSize() override;
size_t GetBlockSize() const override;
size_t SetBlockSize(size_t maxBlockSize) override;
protected:
size_t mBlockSize{ 0 };
};
/***************************************************************************//**
\class EffectInstanceFactory
*******************************************************************************/
class COMPONENTS_API EffectInstanceFactory
: public EffectSettingsManager
{
public:
virtual ~EffectInstanceFactory();
//! Make an object maintaining short-term state of an Effect
/*!
One effect may have multiple instances extant simultaneously.
Instances have state, may be implemented in foreign code, and are temporary,
whereas EffectSettings represents persistent effect state that can be saved
and reloaded from files.
@param settings may be assumed to have a lifetime enclosing the instance's
@post `true` (no promises that the result isn't null)
*/
virtual std::shared_ptr<EffectInstance> MakeInstance() const = 0;
};
/*************************************************************************************/ /**
\class EffectSettingChanged
\brief Message sent by validator when a setting is changed by a user
*******************************************************************************************/
struct COMPONENTS_API EffectSettingChanged final
{
size_t index { size_t(-1) };
float newValue {};
};
/*************************************************************************************//**
\class EffectUIValidator
\brief Interface for transferring values from a panel of effect controls
*******************************************************************************************/
class COMPONENTS_API EffectUIValidator /* not final */
: public Observer::Publisher<EffectSettingChanged>
{
public:
EffectUIValidator(
EffectUIClientInterface &effect, EffectSettingsAccess &access);
virtual ~EffectUIValidator();
//! Get settings data from the panel; may make error dialogs and return false
/*!
@return true only if panel settings are acceptable
*/
virtual bool ValidateUI() = 0;
//! Update appearance of the panel for changes in settings
/*!
Default implementation does nothing, returns true
@return true if successful
*/
virtual bool UpdateUI();
/*!
Default implementation returns false
@return true if using a native plug-in UI, not widgets
*/
virtual bool IsGraphicalUI();
//! On the first call only, may disconnect from further event handling
/*!
Default implemantation does nothing
*/
virtual void Disconnect();
/*!
Handle the UI OnClose event. Default implementation calls mEffect.CloseUI()
*/
virtual void OnClose();
protected:
// Convenience function template for binding event handler functions
template<typename EventTag, typename Class, typename Event>
void BindTo(
wxEvtHandler &src, const EventTag& eventType, void (Class::*pmf)(Event &))
{
src.Bind(eventType, pmf, static_cast<Class *>(this));
}
EffectUIClientInterface &mEffect;
EffectSettingsAccess &mAccess;
bool mUIClosed { false };
};
/*************************************************************************************//**
\class EffectUIClientInterface
\brief EffectUIClientInterface is an abstract base class to populate a UI and validate UI
values. It can import and export presets.
*******************************************************************************************/
class COMPONENTS_API EffectUIClientInterface /* not final */
{
public:
virtual ~EffectUIClientInterface();
/*!
@return 0 if destructive effect processing should not proceed (and there
may be a non-modal dialog still opened); otherwise, modal dialog return code
*/
virtual int ShowClientInterface(wxWindow &parent, wxDialog &dialog,
EffectUIValidator *pValidator, bool forceModal = false) = 0;
/*!
@return true if using a native plug-in UI, not widgets
*/
virtual bool IsGraphicalUI() = 0;
//! Adds controls to a panel that is given as the parent window of `S`
/*!
@param S interface for adding controls to a panel in a dialog
@param instance guaranteed to have a lifetime containing that of the returned
object
@param access guaranteed to have a lifetime containing that of the returned
object
@param pOutputs null, or else points to outputs with lifetime containing
that of the returned object
@return null for failure; else an object invoked to retrieve values of UI
controls; it might also hold some state needed to implement event handlers
of the controls; it will exist only while the dialog continues to exist
*/
virtual std::unique_ptr<EffectUIValidator> PopulateUI(ShuttleGui &S,
EffectInstance &instance, EffectSettingsAccess &access,
const EffectOutputs *pOutputs) = 0;
virtual bool CanExportPresets() = 0;
virtual void ExportPresets(const EffectSettings &settings) const = 0;
//! @return nullopt for failure
[[nodiscard]] virtual OptionalMessage
ImportPresets(EffectSettings &settings) = 0;
virtual bool HasOptions() = 0;
virtual void ShowOptions() = 0;
virtual bool ValidateUI(EffectSettings &settings) = 0;
virtual bool CloseUI() = 0;
};
//! Component of a configuration key path, for last-used destructive settings
COMPONENTS_API const RegistryPath &CurrentSettingsGroup();
//! Component of a configuration key path, for default state of MakeSettings()
COMPONENTS_API const RegistryPath &FactoryDefaultsGroup();
//! Compute part of a registry path, given a name which may be empty
COMPONENTS_API RegistryPath UserPresetsGroup(const RegistryPath & name);
#endif // __AUDACITY_EFFECTINTERFACE_H__
|