1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-07-04 14:39:08 +02:00

Free AudioIO from cycles, 24 files left in the big component

This commit is contained in:
Paul Licameli 2019-06-24 12:22:27 -04:00
commit b8838b38ed
10 changed files with 67 additions and 34 deletions

View File

@ -441,6 +441,7 @@ time warp info and AudioIOListener and whether the playback is looped.
#endif
#include <wx/app.h>
#include <wx/frame.h>
#include <wx/wxcrtvararg.h>
#include <wx/log.h>
#include <wx/textctrl.h>
@ -455,14 +456,12 @@ time warp info and AudioIOListener and whether the playback is looped.
#include "prefs/GUISettings.h"
#include "Prefs.h"
#include "Project.h"
#include "ProjectWindow.h"
#include "WaveTrack.h"
#include "AutoRecovery.h"
#include "effects/RealtimeEffectManager.h"
#include "prefs/QualityPrefs.h"
#include "prefs/RecordingPrefs.h"
#include "toolbars/ControlToolBar.h"
#include "widgets/MeterPanelBase.h"
#include "widgets/AudacityMessageBox.h"
#include "widgets/ErrorDialog.h"
@ -519,8 +518,6 @@ constexpr size_t TimeQueueGrainSize = 2000;
#ifdef EXPERIMENTAL_SCRUBBING_SUPPORT
#include "tracks/ui/Scrubbing.h"
#ifdef __WXGTK__
// Might #define this for a useful thing on Linux
#undef REALTIME_ALSA_THREAD
@ -1431,7 +1428,7 @@ void AudioIO::StartMonitoring( const AudioIOStartStreamOptions &options )
if (!success) {
wxString msg = wxString::Format(_("Error opening recording device.\nError code: %s"), Get()->LastPaErrorString());
ShowErrorDialog( ProjectWindow::Find( mOwningProject ),
ShowErrorDialog( FindProjectFrame( mOwningProject ),
_("Error"), msg, wxT("Error_opening_sound_device"));
return;
}
@ -1705,17 +1702,11 @@ int AudioIO::StartStream(const TransportTracks &tracks,
mAudioThreadShouldCallFillBuffersOnce = true;
while( mAudioThreadShouldCallFillBuffersOnce ) {
#ifndef USE_SCRUB_THREAD
// Yuck, we either have to poll "by hand" when scrub polling doesn't
// work with a thread, or else yield to timer messages, but that would
// execute too much else
if (mScrubState) {
Scrubber::Get( *mOwningProject ).ContinueScrubbingPoll();
wxMilliSleep( Scrubber::ScrubPollInterval_ms * 0.9 );
auto interval = 50ull;
if (options.playbackStreamPrimer) {
interval = options.playbackStreamPrimer();
}
else
#endif
wxMilliSleep( 50 );
wxMilliSleep( interval );
}
if(mNumPlaybackChannels > 0 || mNumCaptureChannels > 0) {
@ -2363,8 +2354,8 @@ void AudioIO::StopStream()
}
}
ControlToolBar &bar = ControlToolBar::Get( *mOwningProject );
bar.CommitRecording();
if (mListener)
mListener->OnCommitRecording();
}
}
@ -2545,7 +2536,7 @@ AudioThread::ExitCode AudioThread::Entry()
{
using Clock = std::chrono::steady_clock;
auto loopPassStart = Clock::now();
const auto interval = Scrubber::ScrubPollInterval_ms;
const auto interval = ScrubPollInterval_ms;
// Set LoopActive outside the tests to avoid race condition
gAudioIO->mAudioThreadFillBuffersLoopActive = true;
@ -3692,8 +3683,8 @@ void AudioIoCallback::CheckSoundActivatedRecordingLevel( const void *inputBuffer
bool bShouldBePaused = mInputMeter->GetMaxPeak() < mSilenceLevel;
if( bShouldBePaused != IsPaused())
{
auto &bar = ControlToolBar::Get( *mOwningProject );
bar.CallAfter(&ControlToolBar::Pause);
if ( mListener )
mListener->OnSoundActivationThreshold();
}
}

View File

@ -789,4 +789,6 @@ private:
void StartStreamCleanup(bool bOnlyBuffers = false);
};
static constexpr unsigned ScrubPollInterval_ms = 50;
#endif

View File

@ -16,6 +16,7 @@ Paul Licameli split from AudioIO.h
#include <atomic>
#include <cfloat>
#include <functional>
#include <memory>
#include <vector>
#include <wx/string.h>
@ -102,6 +103,11 @@ struct AudioIOStartStreamOptions
// contents may get swapped with empty vector
PRCrossfadeData *pCrossfadeData{};
// An unfortunate thing needed just to make scrubbing work on Linux when
// we can't use a separate polling thread.
// The return value is a number of milliseconds to sleep before calling again
std::function< unsigned long() > playbackStreamPrimer;
};
///\brief A singleton object supporting queries of the state of any active

View File

@ -28,6 +28,14 @@ public:
virtual void OnAudioIOStartRecording() = 0;
virtual void OnAudioIOStopRecording() = 0;
virtual void OnAudioIONewBlockFiles(const AutoSaveFile & blockFileLog) = 0;
// Commit the addition of temporary recording tracks into the project
virtual void OnCommitRecording() = 0;
// During recording, the threshold for sound activation has been crossed
// in either direction
virtual void OnSoundActivationThreshold() = 0;
};
#endif

View File

@ -175,6 +175,22 @@ void ProjectAudioManager::OnAudioIONewBlockFiles(
}
}
void ProjectAudioManager::OnCommitRecording()
{
const auto project = &mProject;
TrackList::Get( *project ).ApplyPendingTracks();
}
void ProjectAudioManager::OnSoundActivationThreshold()
{
auto &project = mProject;
auto gAudioIO = AudioIO::Get();
if ( gAudioIO && &project == gAudioIO->GetOwningProject() ) {
auto &bar = ControlToolBar::Get( project );
bar.CallAfter(&ControlToolBar::Pause);
}
}
AudioIOStartStreamOptions
DefaultPlayOptions( AudacityProject &project )
{

View File

@ -40,6 +40,8 @@ private:
void OnAudioIOStartRecording() override;
void OnAudioIOStopRecording() override;
void OnAudioIONewBlockFiles(const AutoSaveFile & blockFileLog) override;
void OnCommitRecording() override;
void OnSoundActivationThreshold() override;
AudacityProject &mProject;

View File

@ -1521,12 +1521,6 @@ void ControlToolBar::StopScrolling()
(ProjectWindow::PlaybackScroller::Mode::Off);
}
void ControlToolBar::CommitRecording()
{
const auto project = &mProject;
TrackList::Get( *project ).ApplyPendingTracks();
}
void ControlToolBar::CancelRecording()
{
const auto project = &mProject;

View File

@ -135,9 +135,6 @@ class ControlToolBar final : public ToolBar {
void StartScrolling();
void StopScrolling();
// Commit the addition of temporary recording tracks into the project
void CommitRecording();
// Cancel the addition of temporary recording tracks into the project
void CancelRecording();

View File

@ -56,8 +56,6 @@ enum {
ScrubSpeedStepsPerOctave = 4,
#endif
ScrubPollInterval_ms = 50,
kOneSecondCountdown = 1000 / ScrubPollInterval_ms,
};
@ -386,6 +384,16 @@ bool Scrubber::MaybeStartScrubbing(wxCoord xx)
mSpeedPlaying = false;
auto options =
DefaultPlayOptions( *mProject );
#ifndef USE_SCRUB_THREAD
// Yuck, we either have to poll "by hand" when scrub polling doesn't
// work with a thread, or else yield to timer messages, but that would
// execute too much else
options.playbackStreamPrimer = [this](){
ContinueScrubbingPoll();
return ScrubPollInterval_ms;
};
#endif
options.pScrubbingOptions = &mOptions;
options.envelope = nullptr;
mOptions.delay = (ScrubPollInterval_ms / 1000.0);
@ -487,6 +495,17 @@ bool Scrubber::StartSpeedPlay(double speed, double time0, double time1)
mDragging = false;
auto options = DefaultSpeedPlayOptions( *mProject );
#ifndef USE_SCRUB_THREAD
// Yuck, we either have to poll "by hand" when scrub polling doesn't
// work with a thread, or else yield to timer messages, but that would
// execute too much else
options.playbackStreamPrimer = [this](){
ContinueScrubbingPoll();
return ScrubPollInterval_ms;
};
#endif
options.pScrubbingOptions = &mOptions;
options.envelope = nullptr;
mOptions.delay = (ScrubPollInterval_ms / 1000.0);

View File

@ -40,9 +40,7 @@ class Scrubber final
: public wxEvtHandler
, public ClientData::Base
{
public:
static constexpr unsigned ScrubPollInterval_ms = 50;
public:
static Scrubber &Get( AudacityProject &project );
static const Scrubber &Get( const AudacityProject &project );