mirror of
https://github.com/cookiengineer/audacity
synced 2025-09-17 16:50:26 +02:00
Separate power button and playing state
This will allow the power button to function independently of the actual playback state. It also gets rid of the whole "Bypass" folderol.
This commit is contained in:
parent
b78f096826
commit
6ecf2e38e9
@ -90,6 +90,10 @@ Effect::Effect()
|
||||
mNumGroups = 0;
|
||||
mProgress = NULL;
|
||||
|
||||
mRealtimeSuspendLock.Enter();
|
||||
mRealtimeSuspendCount = 1; // Effects are initially suspended
|
||||
mRealtimeSuspendLock.Leave();
|
||||
|
||||
// Can change effect flags later (this is the new way)
|
||||
// OR using the old way, over-ride GetEffectFlags().
|
||||
mFlags = BUILTIN_EFFECT | PROCESS_EFFECT | ADVANCED_EFFECT;
|
||||
@ -1566,7 +1570,13 @@ bool Effect::RealtimeSuspend()
|
||||
#if defined(EXPERIMENTAL_REALTIME_EFFECTS)
|
||||
if (mClient)
|
||||
{
|
||||
return mClient->RealtimeSuspend();
|
||||
if (mClient->RealtimeSuspend())
|
||||
{
|
||||
mRealtimeSuspendLock.Enter();
|
||||
mRealtimeSuspendCount++;
|
||||
mRealtimeSuspendLock.Leave();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1578,7 +1588,13 @@ bool Effect::RealtimeResume()
|
||||
#if defined(EXPERIMENTAL_REALTIME_EFFECTS)
|
||||
if (mClient)
|
||||
{
|
||||
return mClient->RealtimeResume();
|
||||
if (mClient->RealtimeResume())
|
||||
{
|
||||
mRealtimeSuspendLock.Enter();
|
||||
mRealtimeSuspendCount--;
|
||||
mRealtimeSuspendLock.Leave();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1600,7 +1616,7 @@ sampleCount Effect::RealtimeProcess(int group,
|
||||
//
|
||||
// Effects always require a certain number of input and output buffers,
|
||||
// so if the number of channels we're curently processing are different
|
||||
// that was the effect expects, then we use a few methods of satisfying
|
||||
// than what the effect expects, then we use a few methods of satisfying
|
||||
// the effects requirements.
|
||||
float **clientIn = (float **) alloca(mNumAudioIn * sizeof(float *));
|
||||
float **clientOut = (float **) alloca(mNumAudioOut * sizeof(float *));
|
||||
@ -1715,6 +1731,11 @@ sampleCount Effect::RealtimeProcess(int group,
|
||||
#endif
|
||||
}
|
||||
|
||||
bool Effect::IsRealtimeActive()
|
||||
{
|
||||
return mRealtimeSuspendCount == 0;
|
||||
}
|
||||
|
||||
void Effect::Preview(bool dryOnly)
|
||||
{
|
||||
if (mNumTracks==0) // nothing to preview
|
||||
@ -2032,7 +2053,7 @@ enum
|
||||
kUserPresetsDummyID = 30006,
|
||||
kDeletePresetDummyID = 30007,
|
||||
kMenuID = 30100,
|
||||
kBypassID = 30101,
|
||||
kPowerID = 30101,
|
||||
kPlayID = 30102,
|
||||
kRewindID = 30103,
|
||||
kFFwdID = 30104,
|
||||
@ -2048,7 +2069,7 @@ BEGIN_EVENT_TABLE(EffectUIHost, wxDialog)
|
||||
EVT_BUTTON(wxID_APPLY, EffectUIHost::OnApply)
|
||||
EVT_BUTTON(wxID_CANCEL, EffectUIHost::OnCancel)
|
||||
EVT_BUTTON(kMenuID, EffectUIHost::OnMenu)
|
||||
EVT_BUTTON(kBypassID, EffectUIHost::OnBypass)
|
||||
EVT_BUTTON(kPowerID, EffectUIHost::OnPower)
|
||||
EVT_BUTTON(kPlayID, EffectUIHost::OnPlay)
|
||||
EVT_BUTTON(kRewindID, EffectUIHost::OnRewind)
|
||||
EVT_BUTTON(kFFwdID, EffectUIHost::OnFFwd)
|
||||
@ -2077,6 +2098,8 @@ EffectUIHost::EffectUIHost(wxWindow *parent,
|
||||
|
||||
mInitialized = false;
|
||||
|
||||
mPowerOn = true;
|
||||
|
||||
mClient->SetUIHost(this);
|
||||
}
|
||||
|
||||
@ -2124,11 +2147,10 @@ bool EffectUIHost::Initialize()
|
||||
mOnBM = CreateBitmap(effect_on_xpm, true, false);
|
||||
mOffBM = CreateBitmap(effect_off_xpm, true, false);
|
||||
mOffDisabledBM = CreateBitmap(effect_off_disabled_xpm, true, false);
|
||||
mBypassBtn = new wxBitmapButton(bar, kBypassID, mOnBM);
|
||||
mBypassBtn->SetBitmapDisabled(mOffDisabledBM);
|
||||
SetLabelAndTip(mBypassBtn, _("B&ypass effect"));
|
||||
mOnToggle = true;
|
||||
bs->Add(mBypassBtn);
|
||||
mPowerBtn = new wxBitmapButton(bar, kPowerID, mOnBM);
|
||||
mPowerBtn->SetBitmapDisabled(mOffDisabledBM);
|
||||
SetLabelAndTip(mPowerBtn, _("P&ower On/Off"));
|
||||
bs->Add(mPowerBtn);
|
||||
|
||||
bs->Add(5, 5);
|
||||
|
||||
@ -2404,17 +2426,17 @@ void EffectUIHost::OnMenu(wxCommandEvent & evt)
|
||||
delete menu;
|
||||
}
|
||||
|
||||
void EffectUIHost::OnBypass(wxCommandEvent & WXUNUSED(evt))
|
||||
void EffectUIHost::OnPower(wxCommandEvent & WXUNUSED(evt))
|
||||
{
|
||||
EffectManager & em = EffectManager::Get();
|
||||
mPowerOn = !mPowerOn;
|
||||
|
||||
if (em.RealtimeIsSuspended())
|
||||
if (mPowerOn)
|
||||
{
|
||||
em.RealtimeResume();
|
||||
mEffect->RealtimeResume();
|
||||
}
|
||||
else
|
||||
{
|
||||
em.RealtimeSuspend();
|
||||
mEffect->RealtimeSuspend();
|
||||
}
|
||||
|
||||
UpdateControls();
|
||||
@ -2702,21 +2724,14 @@ void EffectUIHost::SetLabelAndTip(wxBitmapButton *btn, const wxString & label)
|
||||
void EffectUIHost::UpdateControls()
|
||||
{
|
||||
mApplyBtn->Enable(!mCapturing);
|
||||
mBypassBtn->Enable(!mCapturing);
|
||||
mPowerBtn->Enable(!mCapturing);
|
||||
mPlayBtn->Enable(!mCapturing);
|
||||
mRewindBtn->Enable(!mCapturing);
|
||||
mFFwdBtn->Enable(!mCapturing);
|
||||
|
||||
mOnToggle = !EffectManager::Get().RealtimeIsSuspended();
|
||||
if (mOnToggle && mCapturing)
|
||||
{
|
||||
mOnToggle = false;
|
||||
EffectManager::Get().RealtimeSuspend();
|
||||
}
|
||||
|
||||
mPlayBtn->SetBitmapLabel(mPlaying ? mStopBM : mPlayBM);
|
||||
mPlayBtn->SetBitmapDisabled(mPlaying ? mStopDisabledBM: mPlayDisabledBM);
|
||||
mBypassBtn->SetBitmapLabel(mOnToggle ? mOnBM : mOffBM);
|
||||
mPowerBtn->SetBitmapLabel(mPowerOn ? mOnBM : mOffBM);
|
||||
}
|
||||
|
||||
void EffectUIHost::LoadUserPresets()
|
||||
|
@ -35,6 +35,7 @@ class wxWindow;
|
||||
|
||||
class SelectedRegion;
|
||||
class TimeWarper;
|
||||
class EffectUIHost;
|
||||
|
||||
#define PLUGIN_EFFECT 0x0001
|
||||
#define BUILTIN_EFFECT 0x0002
|
||||
@ -278,6 +279,7 @@ class AUDACITY_DLL_API Effect : public EffectHostInterface
|
||||
float **inbuf,
|
||||
float **outbuf,
|
||||
sampleCount numSamples);
|
||||
bool IsRealtimeActive();
|
||||
|
||||
//
|
||||
// protected virtual methods
|
||||
@ -441,6 +443,9 @@ class AUDACITY_DLL_API Effect : public EffectHostInterface
|
||||
int mCurrentGroup;
|
||||
int mHighGroup;
|
||||
|
||||
wxCriticalSection mRealtimeSuspendLock;
|
||||
int mRealtimeSuspendCount;
|
||||
|
||||
friend class EffectManager;// so it can call PromptUser in support of batch commands.
|
||||
friend class EffectRack;
|
||||
};
|
||||
@ -496,7 +501,7 @@ private:
|
||||
void OnApply(wxCommandEvent & evt);
|
||||
void OnCancel(wxCommandEvent & evt);
|
||||
void OnMenu(wxCommandEvent & evt);
|
||||
void OnBypass(wxCommandEvent & evt);
|
||||
void OnPower(wxCommandEvent & evt);
|
||||
void OnPlay(wxCommandEvent & evt);
|
||||
void OnRewind(wxCommandEvent & evt);
|
||||
void OnFFwd(wxCommandEvent & evt);
|
||||
@ -527,7 +532,7 @@ private:
|
||||
wxButton *mApplyBtn;
|
||||
wxButton *mCloseBtn;
|
||||
wxBitmapButton *mMenuBtn;
|
||||
wxBitmapButton *mBypassBtn;
|
||||
wxBitmapButton *mPowerBtn;
|
||||
wxBitmapButton *mPlayBtn;
|
||||
wxBitmapButton *mRewindBtn;
|
||||
wxBitmapButton *mFFwdBtn;
|
||||
@ -537,7 +542,7 @@ private:
|
||||
wxBitmap mStopBM;
|
||||
wxBitmap mStopDisabledBM;
|
||||
|
||||
bool mOnToggle;
|
||||
bool mPowerOn;
|
||||
wxBitmap mOnBM;
|
||||
wxBitmap mOffBM;
|
||||
wxBitmap mOffDisabledBM;
|
||||
|
@ -645,9 +645,14 @@ sampleCount EffectManager::RealtimeProcess(int group, int chans, float rate, flo
|
||||
|
||||
// Now call each effect in the chain while swapping buffer pointers to feed the
|
||||
// output of one effect as the input to the next effect
|
||||
for (int i = 0, cnt = mRealtimeEffects.GetCount(); i < cnt; i++)
|
||||
size_t called = 0;
|
||||
for (size_t i = 0, cnt = mRealtimeEffects.GetCount(); i < cnt; i++)
|
||||
{
|
||||
mRealtimeEffects[i]->RealtimeProcess(group, chans, rate, ibuf, obuf, numSamples);
|
||||
if (mRealtimeEffects[i]->IsRealtimeActive())
|
||||
{
|
||||
mRealtimeEffects[i]->RealtimeProcess(group, chans, rate, ibuf, obuf, numSamples);
|
||||
called++;
|
||||
}
|
||||
|
||||
for (int j = 0; j < chans; j++)
|
||||
{
|
||||
@ -660,8 +665,9 @@ sampleCount EffectManager::RealtimeProcess(int group, int chans, float rate, flo
|
||||
|
||||
// Once we're done, we might wind up with the last effect storing its results
|
||||
// in the temporary buffers. If that's the case, we need to copy it over to
|
||||
// the caller's buffers. This happens when the number of effects is odd.
|
||||
if (mRealtimeEffects.GetCount() & 1)
|
||||
// the caller's buffers. This happens when the number of effects proccessed
|
||||
// is odd.
|
||||
if (called & 1)
|
||||
{
|
||||
for (int i = 0; i < chans; i++)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user