From 3345797ff682192ef7004c4ddb28bd5bc66229f8 Mon Sep 17 00:00:00 2001 From: Thomas Goyne Date: Wed, 8 Dec 2010 08:09:16 +0000 Subject: [PATCH] Use signals in AudioController and AudioTimingController Originally committed to SVN as r4907. --- aegisub/src/ass_exporter.cpp | 1 - aegisub/src/audio_box.cpp | 18 +- aegisub/src/audio_box.h | 9 +- aegisub/src/audio_controller.cpp | 186 ++++----------- aegisub/src/audio_controller.h | 261 ++++++++-------------- aegisub/src/audio_display.cpp | 51 +---- aegisub/src/audio_display.h | 21 +- aegisub/src/audio_player_alsa.cpp | 1 - aegisub/src/audio_player_dsound.cpp | 1 - aegisub/src/audio_player_openal.cpp | 1 - aegisub/src/audio_player_oss.cpp | 1 - aegisub/src/audio_provider_hd.cpp | 1 - aegisub/src/audio_provider_ram.cpp | 1 - aegisub/src/audio_timing.h | 22 +- aegisub/src/audio_timing_dialogue.cpp | 26 +-- aegisub/src/base_grid.cpp | 1 - aegisub/src/dialog_detached_video.cpp | 1 - aegisub/src/dialog_fonts_collector.cpp | 1 - aegisub/src/dialog_search_replace.cpp | 1 - aegisub/src/dialog_spellchecker.cpp | 1 - aegisub/src/dialog_styling_assistant.cpp | 2 +- aegisub/src/dialog_translation.cpp | 2 +- aegisub/src/drop.cpp | 1 - aegisub/src/ffmpegsource_common.cpp | 1 - aegisub/src/frame_main.cpp | 3 +- aegisub/src/frame_main.h | 15 +- aegisub/src/frame_main_events.cpp | 31 +-- aegisub/src/main.cpp | 1 - aegisub/src/subtitles_provider_libass.cpp | 1 - aegisub/src/video_box.cpp | 1 - aegisub/src/video_context.cpp | 6 +- 31 files changed, 222 insertions(+), 448 deletions(-) diff --git a/aegisub/src/ass_exporter.cpp b/aegisub/src/ass_exporter.cpp index 0589ba0df..b9087db35 100644 --- a/aegisub/src/ass_exporter.cpp +++ b/aegisub/src/ass_exporter.cpp @@ -39,7 +39,6 @@ #include "ass_export_filter.h" #include "ass_exporter.h" #include "ass_file.h" -#include "audio_controller.h" #include "frame_main.h" /// @brief Constructor diff --git a/aegisub/src/audio_box.cpp b/aegisub/src/audio_box.cpp index 38d1029b1..a9ab9aceb 100644 --- a/aegisub/src/audio_box.cpp +++ b/aegisub/src/audio_box.cpp @@ -255,7 +255,7 @@ AudioBox::AudioBox(wxWindow *parent, AudioController *_controller, SelectionCont SetSizer(MainSizer); SetKaraokeButtons(); // Decide which one to show or hide. - + timing_controller_dialogue = CreateDialogueTimingController(controller, selection_controller); controller->SetTimingController(timing_controller_dialogue); } @@ -425,8 +425,8 @@ void AudioBox::OnPrev(wxCommandEvent &event) { /// @param event /// void AudioBox::OnPlay500Before(wxCommandEvent &event) { - AudioController::SampleRange times(controller->GetPrimaryPlaybackRange()); - controller->PlayRange(AudioController::SampleRange( + SampleRange times(controller->GetPrimaryPlaybackRange()); + controller->PlayRange(SampleRange( times.begin() - controller->SamplesFromMilliseconds(500), times.begin())); } @@ -437,8 +437,8 @@ void AudioBox::OnPlay500Before(wxCommandEvent &event) { /// @param event /// void AudioBox::OnPlay500After(wxCommandEvent &event) { - AudioController::SampleRange times(controller->GetPrimaryPlaybackRange()); - controller->PlayRange(AudioController::SampleRange( + SampleRange times(controller->GetPrimaryPlaybackRange()); + controller->PlayRange(SampleRange( times.end(), times.end() + controller->SamplesFromMilliseconds(500))); } @@ -449,8 +449,8 @@ void AudioBox::OnPlay500After(wxCommandEvent &event) { /// @param event /// void AudioBox::OnPlay500First(wxCommandEvent &event) { - AudioController::SampleRange times(controller->GetPrimaryPlaybackRange()); - controller->PlayRange(AudioController::SampleRange( + SampleRange times(controller->GetPrimaryPlaybackRange()); + controller->PlayRange(SampleRange( times.begin(), times.begin() + std::min( controller->SamplesFromMilliseconds(500), @@ -463,8 +463,8 @@ void AudioBox::OnPlay500First(wxCommandEvent &event) { /// @param event /// void AudioBox::OnPlay500Last(wxCommandEvent &event) { - AudioController::SampleRange times(controller->GetPrimaryPlaybackRange()); - controller->PlayRange(AudioController::SampleRange( + SampleRange times(controller->GetPrimaryPlaybackRange()); + controller->PlayRange(SampleRange( times.end() - std::min( controller->SamplesFromMilliseconds(500), times.length()), diff --git a/aegisub/src/audio_box.h b/aegisub/src/audio_box.h index 363f8e73e..42f0b6b87 100644 --- a/aegisub/src/audio_box.h +++ b/aegisub/src/audio_box.h @@ -54,14 +54,11 @@ #include #endif -#ifndef AGI_AUDIO_CONTROLLER_INCLUDED -#error You must include "audio_controller.h" before "audio_box.h" -#endif - - ////////////// // Prototypes +class AudioController; class AssDialogue; +class AudioTimingController; class AudioDisplay; class AudioKaraoke; class FrameMain; @@ -80,7 +77,7 @@ class AudioBox : public wxPanel { /// Selection controller used for timing controllers SelectionController *selection_controller; - /// The regular dalogue timing controller + /// The regular dialogue timing controller AudioTimingController *timing_controller_dialogue; /// DOCME diff --git a/aegisub/src/audio_controller.cpp b/aegisub/src/audio_controller.cpp index acfbbab98..1fe946d53 100644 --- a/aegisub/src/audio_controller.cpp +++ b/aegisub/src/audio_controller.cpp @@ -74,71 +74,51 @@ bool operator < (int64_t a, const AudioMarkerKeyframe &b) { return a < b.GetPosi bool operator < (const AudioMarkerKeyframe &a, int64_t b) { return a.GetPosition() < b; } wxPen AudioMarkerKeyframe::style; -class AudioMarkerProviderKeyframes : public AudioMarkerProvider, private AudioControllerAudioEventListener { - // GetMarkers needs to be const but still needs to modify this state, which is really - // just a cache... use the mutable "hack". - mutable int last_keyframes_revision; - mutable std::vector keyframe_samples; - AudioController *controller; - int64_t samplerate; +class AudioMarkerProviderKeyframes : public AudioMarkerProvider { + VideoContext *vc; - void ReloadKeyframes() const + agi::signal::Connection keyframe_slot; + agi::signal::Connection audio_open_slot; + + std::vector keyframe_samples; + AudioController *controller; + + void OnKeyframesOpen(std::vector const& raw_keyframes) { keyframe_samples.clear(); - - VideoContext *vc = VideoContext::Get(); - if (!vc) return; - - last_keyframes_revision = vc->GetKeyframesRevision(); - const std::vector &raw_keyframes = vc->GetKeyFrames(); keyframe_samples.reserve(raw_keyframes.size()); for (size_t i = 0; i < raw_keyframes.size(); ++i) { keyframe_samples.push_back(AudioMarkerKeyframe( - vc->TimeAtFrame(raw_keyframes[i]) * samplerate / 1000)); + controller->SamplesFromMilliseconds(vc->TimeAtFrame(raw_keyframes[i])))); } std::sort(keyframe_samples.begin(), keyframe_samples.end()); + AnnounceMarkerMoved(); } private: // AudioControllerAudioEventListener implementation - virtual void OnAudioOpen(AudioProvider *provider) + void OnAudioOpen(AudioProvider *) { - samplerate = provider->GetSampleRate(); - ReloadKeyframes(); + OnKeyframesOpen(vc->GetKeyFrames()); } - virtual void OnAudioClose() { } - virtual void OnPlaybackPosition(int64_t sample_position) { } - virtual void OnPlaybackStop() { } public: AudioMarkerProviderKeyframes(AudioController *controller) - : controller(controller) + : vc(VideoContext::Get()) + , keyframe_slot(vc->AddKeyframesOpenListener(&AudioMarkerProviderKeyframes::OnKeyframesOpen, this)) + , audio_open_slot(controller->AddAudioOpenListener(&AudioMarkerProviderKeyframes::OnAudioOpen, this)) + , controller(controller) { - // Assume that a video context with keyframes revision 0 never has keyframes loaded - last_keyframes_revision = 0; - samplerate = 44100; - controller->AddAudioListener(this); + OnKeyframesOpen(vc->GetKeyFrames()); } - virtual ~AudioMarkerProviderKeyframes() + void GetMarkers(const SampleRange &range, AudioMarkerVector &out) const { - controller->RemoveAudioListener(this); - } - - void GetMarkers(const AudioController::SampleRange &range, AudioMarkerVector &out) const - { - VideoContext *vc = VideoContext::Get(); - if (!vc) return; - - // Re-read keyframe data if the revision number changed, the keyframe data probably did too - if (vc->GetKeyframesRevision() != last_keyframes_revision) - ReloadKeyframes(); - // Find first and last keyframes inside the range - std::vector::iterator a = std::lower_bound( + std::vector::const_iterator a = std::lower_bound( keyframe_samples.begin(), keyframe_samples.end(), range.begin()); - std::vector::iterator b = std::upper_bound( + std::vector::const_iterator b = std::upper_bound( keyframe_samples.begin(), keyframe_samples.end(), range.end()); // Place pointers to the markers in the output vector @@ -147,22 +127,9 @@ public: } }; - -/// Type of the audio event listener container in AudioController -typedef std::set AudioEventListenerSet; -/// Type of the timing event listener container in AudioController -typedef std::set TimingEventListenerSet; - -/// Macro to iterate audio event listeners in AudioController implementation -#define AUDIO_LISTENERS(listener) for (AudioEventListenerSet::iterator listener = audio_event_listeners.begin(); listener != audio_event_listeners.end(); ++listener) -/// Macro to iterate audio event listeners in AudioController implementation -#define TIMING_LISTENERS(listener) for (TimingEventListenerSet::iterator listener = timing_event_listeners.begin(); listener != timing_event_listeners.end(); ++listener) - - AudioController::AudioController() : player(0) , provider(0) -, timing_controller(0) , keyframes_marker_provider(new AudioMarkerProviderKeyframes(this)) , playback_mode(PM_NotPlaying) , playback_timer(this) @@ -195,10 +162,7 @@ void AudioController::OnPlaybackTimer(wxTimerEvent &event) } else { - AUDIO_LISTENERS(l) - { - (*l)->OnPlaybackPosition(pos); - } + AnnouncePlaybackPosition(pos); } } @@ -312,10 +276,7 @@ void AudioController::OpenAudio(const wxString &url) } // Tell listeners about this. - AUDIO_LISTENERS(l) - { - (*l)->OnAudioOpen(provider); - } + AnnounceAudioOpen(provider); } @@ -328,10 +289,7 @@ void AudioController::CloseAudio() player = 0; provider = 0; - AUDIO_LISTENERS(l) - { - (*l)->OnAudioClose(); - } + AnnounceAudioClose(); } @@ -347,90 +305,37 @@ wxString AudioController::GetAudioURL() const return _T(""); } - - -void AudioController::AddAudioListener(AudioControllerAudioEventListener *listener) -{ - audio_event_listeners.insert(listener); -} - - -void AudioController::RemoveAudioListener(AudioControllerAudioEventListener *listener) -{ - audio_event_listeners.erase(listener); -} - - -void AudioController::AddTimingListener(AudioControllerTimingEventListener *listener) -{ - timing_event_listeners.insert(listener); -} - - -void AudioController::RemoveTimingListener(AudioControllerTimingEventListener *listener) -{ - timing_event_listeners.erase(listener); -} - - - void AudioController::SetTimingController(AudioTimingController *new_controller) { - delete timing_controller; - timing_controller = new_controller; - - TIMING_LISTENERS(l) - { - (*l)->OnTimingControllerChanged(); + if (timing_controller.get() != new_controller) { + timing_controller.reset(new_controller); + timing_controller->AddMarkerMovedListener(std::tr1::bind(std::tr1::ref(AnnounceMarkerMoved))); + timing_controller->AddUpdatedPrimaryRangeListener(&AudioController::OnTimingControllerUpdatedPrimaryRange, this); + timing_controller->AddUpdatedStyleRangesListener(&AudioController::OnTimingControllerUpdatedStyleRanges, this); } + + AnnounceTimingControllerChanged(); } -void AudioController::OnTimingControllerUpdatedPrimaryRange(AudioTimingController *sending_controller) +void AudioController::OnTimingControllerUpdatedPrimaryRange() { - assert(sending_controller != 0); - if (sending_controller != timing_controller) - return; - if (playback_mode == PM_PrimaryRange) { player->SetEndPosition(timing_controller->GetPrimaryPlaybackRange().end()); } - TIMING_LISTENERS(l) - { - (*l)->OnSelectionChanged(); - } + AnnounceSelectionChanged(); } -void AudioController::OnTimingControllerUpdatedStyleRanges(AudioTimingController *sending_controller) +void AudioController::OnTimingControllerUpdatedStyleRanges() { - assert(sending_controller != 0); - if (sending_controller != timing_controller) - return; - /// @todo redraw and stuff, probably } - -void AudioController::OnTimingControllerMarkerMoved(AudioTimingController *sending_controller, AudioMarker *marker) -{ - assert(sending_controller != 0); - if (sending_controller != timing_controller) - return; - - /// @todo shouldn't this be more detailed? - TIMING_LISTENERS(l) - { - (*l)->OnMarkersMoved(); - } -} - - - -void AudioController::PlayRange(const AudioController::SampleRange &range) +void AudioController::PlayRange(const SampleRange &range) { if (!IsAudioOpen()) return; @@ -438,10 +343,7 @@ void AudioController::PlayRange(const AudioController::SampleRange &range) playback_mode = PM_Range; playback_timer.Start(20); - AUDIO_LISTENERS(l) - { - (*l)->OnPlaybackPosition(range.begin()); - } + AnnouncePlaybackPosition(range.begin()); } @@ -461,10 +363,7 @@ void AudioController::PlayToEnd(int64_t start_sample) playback_mode = PM_ToEnd; playback_timer.Start(20); - AUDIO_LISTENERS(l) - { - (*l)->OnPlaybackPosition(start_sample); - } + AnnouncePlaybackPosition(start_sample); } @@ -476,10 +375,7 @@ void AudioController::Stop() playback_mode = PM_NotPlaying; playback_timer.Stop(); - AUDIO_LISTENERS(l) - { - (*l)->OnPlaybackStop(); - } + AnnouncePlaybackStop(); } @@ -505,9 +401,9 @@ void AudioController::ResyncPlaybackPosition(int64_t new_position) } -AudioController::SampleRange AudioController::GetPrimaryPlaybackRange() const +SampleRange AudioController::GetPrimaryPlaybackRange() const { - if (timing_controller != 0) + if (timing_controller.get()) { return timing_controller->GetPrimaryPlaybackRange(); } @@ -522,6 +418,7 @@ void AudioController::GetMarkers(const SampleRange &range, AudioMarkerVector &ma { /// @todo Find all sources of markers keyframes_marker_provider->GetMarkers(range, markers); + if (timing_controller.get()) timing_controller->GetMarkers(range, markers); } @@ -565,4 +462,3 @@ int64_t AudioController::MillisecondsFromSamples(int64_t samples) const return millisamples / sr; } - diff --git a/aegisub/src/audio_controller.h b/aegisub/src/audio_controller.h index 90db3015e..b3f615de3 100644 --- a/aegisub/src/audio_controller.h +++ b/aegisub/src/audio_controller.h @@ -48,9 +48,8 @@ #endif #include - -#define AGI_AUDIO_CONTROLLER_INCLUDED 1 - +#include +#include class AudioPlayer; class AudioProvider; @@ -62,15 +61,78 @@ class AudioTimingController; class AudioMarker; class AudioMarkerProvider; - typedef std::vector AudioMarkerVector; +/// @class SampleRange +/// @brief Represents an immutable range of audio samples +class SampleRange { + int64_t _begin; + int64_t _end; + +public: + /// @brief Constructor + /// @param begin Index of the first sample to include in the range + /// @param end Index of one past the last sample to include in the range + SampleRange(int64_t begin, int64_t end) + : _begin(begin) + , _end(end) + { + assert(end >= begin); + } + + /// @brief Copy constructor, optionally adjusting the range + /// @param src The range to duplicate + /// @param begin_adjust Number of samples to add to the start of the range + /// @param end_adjust Number of samples to add to the end of the range + SampleRange(const SampleRange &src, int64_t begin_adjust = 0, int64_t end_adjust = 0) + { + _begin = src._begin + begin_adjust; + _end = src._end + end_adjust; + assert(_end >= _begin); + } + + /// Get the number of samples in the range + int64_t length() const { return _end - _begin; } + /// Get the index of the first sample in the range + int64_t begin() const { return _begin; } + /// Get the index of one past the last sample in the range + int64_t end() const { return _end; } + + /// Determine whether the range contains a given sample index + bool contains(int64_t sample) const { return sample >= begin() && sample < end(); } + + /// Determine whether there is an overlap between two ranges + bool overlaps(const SampleRange &other) const + { + return other.contains(_begin) + || other.contains(_end) + || contains(other._begin) + || contains(other._end); + } +}; + +/// @class AudioMarkerProvider +/// @brief Abstract interface for audio marker providers +class AudioMarkerProvider { +protected: + /// One or more of the markers provided by this object have changed + agi::signal::Signal<> AnnounceMarkerMoved; +public: + /// Virtual destructor, does nothing + virtual ~AudioMarkerProvider() { } + + /// @brief Return markers in a sample range + virtual void GetMarkers(const SampleRange &range, AudioMarkerVector &out) const = 0; + + DEFINE_SIGNAL_ADDERS(AnnounceMarkerMoved, AddMarkerMovedListener) +}; + /// @class AudioController /// @brief Manage an open audio stream and UI state for it /// /// Keeps track of the UI interaction state of the open audio for a project, ie. what the current -/// selection is, what moveable markers are on the audio, and any secondary non-moveable markers +/// selection is, what movable markers are on the audio, and any secondary non-movable markers /// that are present. /// /// Changes in interaction are broadcast to all managed audio displays so they can redraw, and @@ -85,65 +147,25 @@ typedef std::vector AudioMarkerVector; /// There is not supposed to be a way to get direct access to the audio providers or players owned /// by a controller. If some operation that isn't possible in the existing design is needed, the /// controller should be extended in some way to allow it. -class AudioController : public wxEvtHandler { -public: - - /// @class SampleRange - /// @brief Represents an immutable range of audio samples - class SampleRange { - int64_t _begin; - int64_t _end; - - public: - /// @brief Constructor - /// @param begin Index of the first sample to include in the range - /// @param end Index of one past the last sample to include in the range - SampleRange(int64_t begin, int64_t end) - : _begin(begin) - , _end(end) - { - assert(end >= begin); - } - - /// @brief Copy constructor, optionally adjusting the range - /// @param src The range to duplicate - /// @param begin_adjust Number of samples to add to the start of the range - /// @param end_adjust Number of samples to add to the end of the range - SampleRange(const SampleRange &src, int64_t begin_adjust = 0, int64_t end_adjust = 0) - { - _begin = src._begin + begin_adjust; - _end = src._end + end_adjust; - assert(_end >= _begin); - } - - /// Get the number of samples in the range - int64_t length() const { return _end - _begin; } - /// Get the index of the first sample in the range - int64_t begin() const { return _begin; } - /// Get the index of one past the last sample in the range - int64_t end() const { return _end; } - - /// Determine whether the range contains a given sample index - bool contains(int64_t sample) const { return sample >= begin() && sample < end(); } - - /// Determine whether there is an overlap between two ranges - bool overlaps(const SampleRange &other) const - { - return other.contains(_begin) - || other.contains(_end) - || contains(other._begin) - || contains(other._end); - } - }; - - +class AudioController : public wxEvtHandler, public AudioMarkerProvider { private: + /// A new audio stream was opened (and any previously open was closed) + agi::signal::Signal AnnounceAudioOpen; - /// Listeners for audio-related events - std::set audio_event_listeners; + /// The current audio stream was closed + agi::signal::Signal<> AnnounceAudioClose; - /// Listeners for timing-related events - std::set timing_event_listeners; + /// Playback is in progress and the current position was updated + agi::signal::Signal AnnouncePlaybackPosition; + + /// Playback has stopped + agi::signal::Signal<> AnnouncePlaybackStop; + + /// The timing controller was replaced + agi::signal::Signal<> AnnounceTimingControllerChanged; + + /// The selected time range changed + agi::signal::Signal<> AnnounceSelectionChanged; /// The audio output object AudioPlayer *player; @@ -152,10 +174,10 @@ private: AudioProvider *provider; /// The current timing mode, if any; owned by the audio controller - AudioTimingController *timing_controller; + agi::scoped_ptr timing_controller; /// Provide keyframe data for audio displays - std::auto_ptr keyframes_marker_provider; + agi::scoped_ptr keyframes_marker_provider; enum PlaybackMode { @@ -174,6 +196,11 @@ private: /// Event handler for the playback timer void OnPlaybackTimer(wxTimerEvent &event); + /// @brief Timing controller signals primary playback range changed + void OnTimingControllerUpdatedPrimaryRange(); + + /// @brief Timing controller signals that the rendering style ranges have changed + void OnTimingControllerUpdatedStyleRanges(); #ifdef wxHAS_POWER_EVENTS /// Handle computer going into suspend mode by stopping audio and closing device @@ -182,7 +209,6 @@ private: void OnComputerResuming(wxPowerEvent &event); #endif - public: /// @brief Constructor @@ -213,23 +239,6 @@ public: wxString GetAudioURL() const; - /// @brief Add an audio event listener - /// @param listener The listener to add - void AddAudioListener(AudioControllerAudioEventListener *listener); - - /// @brief Remove an audio event listener - /// @param listener The listener to remove - void RemoveAudioListener(AudioControllerAudioEventListener *listener); - - /// @brief Add a timing event listener - /// @param listener The listener to add - void AddTimingListener(AudioControllerTimingEventListener *listener); - - /// @brief Remove a timing event listener - /// @param listener The listener to remove - void RemoveTimingListener(AudioControllerTimingEventListener *listener); - - /// @brief Start or restart audio playback, playing a range /// @param range The range of audio to play back /// @@ -279,12 +288,9 @@ public: /// @return An immutable SampleRange object SampleRange GetPrimaryPlaybackRange() const; - /// @brief Get all static markers inside a range + /// @brief Get all markers inside a range /// @param range The sample range to retrieve markers for /// @param markers Vector to fill found markers into - /// - /// The markers retrieved are static markers the user can't interact with. - /// Markers for user interaction are obtained through the timing controller. void GetMarkers(const SampleRange &range, AudioMarkerVector &markers) const; @@ -304,7 +310,7 @@ public: /// @brief Return the current timing controller /// @return The current timing controller or 0 - AudioTimingController * GetTimingController() const { return timing_controller; } + AudioTimingController * GetTimingController() const { return timing_controller.get(); } /// @brief Change the current timing controller /// @param new_mode The new timing controller or 0. This may be the same object as @@ -312,31 +318,6 @@ public: /// the object being timed, eg. changed to a new dialogue line. void SetTimingController(AudioTimingController *new_controller); - - /// @brief Timing controller signals primary playback range changed - /// @param timing_controller The timing controller sending this notification - /// - /// Only timing controllers should call this function. This function must be called - /// when the primary playback range is changed in the timing controller, usually - /// as a result of user interaction. - void OnTimingControllerUpdatedPrimaryRange(AudioTimingController *timing_controller); - - /// @brief Timing controller signals that the rendering style ranges have changed - /// @param timing_controller The timing controller sending this notification - /// - /// Only timing controllers should call this function. This function must be called - /// when one or more rendering style ranges have changed in the timing controller. - void OnTimingControllerUpdatedStyleRanges(AudioTimingController *timing_controller); - - /// @brief Timing controller signals that an audio marker has moved - /// @param timing_controller The timing controller sending this notification - /// @param marker The marker that was moved - /// - /// Only timing controllers should call this function. This function must be called - /// when a marker owned by the timing controller has been updated in some way. - void OnTimingControllerMarkerMoved(AudioTimingController *timing_controller, AudioMarker *marker); - - /// @brief Convert a count of audio samples to a time in milliseconds /// @param samples Sample count to convert /// @return The number of milliseconds equivalent to the sample-count, rounded down @@ -346,57 +327,15 @@ public: /// @param ms Time in milliseconds to convert /// @return The index of the first sample that is wholly inside the millisecond int64_t SamplesFromMilliseconds(int64_t ms) const; + + DEFINE_SIGNAL_ADDERS(AnnounceAudioOpen, AddAudioOpenListener) + DEFINE_SIGNAL_ADDERS(AnnounceAudioClose, AddAudioCloseListener) + DEFINE_SIGNAL_ADDERS(AnnouncePlaybackPosition, AddPlaybackPositionListener) + DEFINE_SIGNAL_ADDERS(AnnouncePlaybackStop, AddPlaybackStopListener) + DEFINE_SIGNAL_ADDERS(AnnounceTimingControllerChanged, AddTimingControllerListener) + DEFINE_SIGNAL_ADDERS(AnnounceSelectionChanged, AddSelectionChangedListener) }; - - -/// @class AudioControllerAudioEventListener -/// @brief Abstract interface for objects that want audio events -class AudioControllerAudioEventListener { -public: - /// A new audio stream was opened (and any previously open was closed) - virtual void OnAudioOpen(AudioProvider *) = 0; - - /// The current audio stream was closed - virtual void OnAudioClose() = 0; - - /// Playback is in progress and ths current position was updated - virtual void OnPlaybackPosition(int64_t sample_position) = 0; - - /// Playback has stopped - virtual void OnPlaybackStop() = 0; -}; - - -/// @class AudioControllerTimingEventListener -/// @brief Abstract interface for objects that want audio timing events -class AudioControllerTimingEventListener { -public: - /// One or more moveable markers were moved - virtual void OnMarkersMoved() = 0; - - /// The selection was changed - virtual void OnSelectionChanged() = 0; - - /// The timing controller was replaced - virtual void OnTimingControllerChanged() = 0; -}; - - - -/// @class AudioMarkerProvider -/// @brief Abstract interface for audio marker providers -class AudioMarkerProvider { -public: - /// Virtual destructor, does nothing - virtual ~AudioMarkerProvider() { } - - /// @brief Return markers in a sample range - virtual void GetMarkers(const AudioController::SampleRange &range, AudioMarkerVector &out) const = 0; -}; - - - /// @class AudioMarker /// @brief A marker on the audio display class AudioMarker { @@ -431,8 +370,6 @@ public: virtual bool CanSnap() const = 0; }; - - namespace agi { DEFINE_BASE_EXCEPTION(AudioControllerError, Exception); DEFINE_SIMPLE_EXCEPTION(AudioOpenError, AudioControllerError, "audio_controller/open_failed"); diff --git a/aegisub/src/audio_display.cpp b/aegisub/src/audio_display.cpp index acadb2fe8..3ee66f7ae 100644 --- a/aegisub/src/audio_display.cpp +++ b/aegisub/src/audio_display.cpp @@ -496,7 +496,7 @@ public: if (marker->CanSnap() && (default_snap != event.ShiftDown())) { - AudioController::SampleRange snap_sample_range( + SampleRange snap_sample_range( display->SamplesFromRelativeX(event.GetPosition().x - snap_range), display->SamplesFromRelativeX(event.GetPosition().x + snap_range)); const AudioMarker *snap_marker = 0; @@ -546,8 +546,13 @@ AudioDisplay::AudioDisplay(wxWindow *parent, AudioController *controller) track_cursor_pos = -1; - controller->AddAudioListener(this); - controller->AddTimingListener(this); + slots.push_back(controller->AddAudioOpenListener(&AudioDisplay::OnAudioOpen, this)); + slots.push_back(controller->AddAudioCloseListener(&AudioDisplay::OnAudioOpen, this, (AudioProvider*)0)); + slots.push_back(controller->AddPlaybackPositionListener(&AudioDisplay::OnPlaybackPosition, this)); + slots.push_back(controller->AddPlaybackStopListener(&AudioDisplay::RemoveTrackCursor, this)); + slots.push_back(controller->AddTimingControllerListener(&AudioDisplay::Refresh, this, true, (const wxRect*)0)); + slots.push_back(controller->AddMarkerMovedListener(&AudioDisplay::Refresh, this, true, (const wxRect*)0)); + slots.push_back(controller->AddSelectionChangedListener(&AudioDisplay::OnSelectionChanged, this)); OPT_SUB("Audio/Spectrum", &AudioDisplay::ReloadRenderingSettings, this); @@ -564,8 +569,6 @@ AudioDisplay::AudioDisplay(wxWindow *parent, AudioController *controller) AudioDisplay::~AudioDisplay() { - controller->RemoveAudioListener(this); - controller->RemoveTimingListener(this); } @@ -614,7 +617,7 @@ void AudioDisplay::ScrollSampleToCenter(int64_t sample_position) } -void AudioDisplay::ScrollSampleRangeInView(const AudioController::SampleRange &range) +void AudioDisplay::ScrollSampleRangeInView(const SampleRange &range) { int client_width = GetClientRect().GetWidth(); int range_begin = AbsoluteXFromSamples(range.begin()); @@ -810,7 +813,7 @@ void AudioDisplay::OnPaint(wxPaintEvent& event) bool redraw_timeline = false; /// @todo Get rendering style ranges from timing controller instead - AudioController::SampleRange sel_samples(controller->GetPrimaryPlaybackRange()); + SampleRange sel_samples(controller->GetPrimaryPlaybackRange()); int selection_start = AbsoluteXFromSamples(sel_samples.begin()); int selection_end = AbsoluteXFromSamples(sel_samples.end()); @@ -856,12 +859,10 @@ void AudioDisplay::OnPaint(wxPaintEvent& event) // Draw markers on top of it all AudioMarkerVector markers; const int foot_size = 6; - AudioController::SampleRange updrectsamples( + SampleRange updrectsamples( SamplesFromRelativeX(updrect.x - foot_size), SamplesFromRelativeX(updrect.x + updrect.width + foot_size)); controller->GetMarkers(updrectsamples, markers); - if (controller->GetTimingController()) - controller->GetTimingController()->GetMarkers(updrectsamples, markers); wxDCPenChanger pen_retainer(dc, wxPen()); wxDCBrushChanger brush_retainer(dc, wxBrush()); for (AudioMarkerVector::iterator marker_i = markers.begin(); marker_i != markers.end(); ++marker_i) @@ -1184,35 +1185,15 @@ void AudioDisplay::OnAudioOpen(AudioProvider *_provider) Refresh(); } - -void AudioDisplay::OnAudioClose() -{ - OnAudioOpen(0); -} - - void AudioDisplay::OnPlaybackPosition(int64_t sample_position) { SetTrackCursor(AbsoluteXFromSamples(sample_position), false); } - -void AudioDisplay::OnPlaybackStop() -{ - RemoveTrackCursor(); -} - - -void AudioDisplay::OnMarkersMoved() -{ - Refresh(); -} - - void AudioDisplay::OnSelectionChanged() { /// @todo Handle rendering style ranges from timing controller instead - AudioController::SampleRange sel(controller->GetPrimaryPlaybackRange()); + SampleRange sel(controller->GetPrimaryPlaybackRange()); scrollbar->SetSelection(AbsoluteXFromSamples(sel.begin()), AbsoluteXFromSamples(sel.length())); if (sel.overlaps(old_selection)) @@ -1242,11 +1223,3 @@ void AudioDisplay::OnSelectionChanged() old_selection = sel; } - - -void AudioDisplay::OnTimingControllerChanged() -{ - Refresh(); - /// @todo Do something more about the new timing controller? -} - diff --git a/aegisub/src/audio_display.h b/aegisub/src/audio_display.h index 086560c37..24c8cde5f 100644 --- a/aegisub/src/audio_display.h +++ b/aegisub/src/audio_display.h @@ -38,6 +38,7 @@ #pragma once #ifndef AGI_PRE +#include #include #include @@ -47,6 +48,7 @@ #endif #include +#include class AudioRenderer; @@ -108,8 +110,9 @@ public: /// The audio display is the common view that allows the user to interact with the active /// timing controller. The audio display also renders audio according to the audio controller /// and the timing controller, using an audio renderer instance. -class AudioDisplay: public wxWindow, private AudioControllerAudioEventListener, private AudioControllerTimingEventListener { +class AudioDisplay: public wxWindow { private: + std::list slots; /// The audio renderer manager agi::scoped_ptr audio_renderer; @@ -178,9 +181,8 @@ private: /// @brief Remove the tracking cursor from the display void RemoveTrackCursor(); - - /// Previous audio selection for optimising redraw when selection changes - AudioController::SampleRange old_selection; + /// Previous audio selection for optimizing redraw when selection changes + SampleRange old_selection; /// @brief Reload all rendering settings from Options and reset caches /// @@ -197,19 +199,10 @@ private: /// wxWidgets input focus changed event void OnFocus(wxFocusEvent &event); - -private: // AudioControllerAudioEventListener implementation virtual void OnAudioOpen(AudioProvider *provider); - virtual void OnAudioClose(); virtual void OnPlaybackPosition(int64_t sample_position); - virtual void OnPlaybackStop(); - - // AudioControllerTimingEventListener implementation - virtual void OnMarkersMoved(); virtual void OnSelectionChanged(); - virtual void OnTimingControllerChanged(); - public: @@ -261,7 +254,7 @@ public: /// closer to the edge of the display than the margin. The edge that is not ensured to /// be in view might be outside of view or might be closer to the display edge than the /// margin. - void ScrollSampleRangeInView(const AudioController::SampleRange &range); + void ScrollSampleRangeInView(const SampleRange &range); /// @brief Change the zoom level diff --git a/aegisub/src/audio_player_alsa.cpp b/aegisub/src/audio_player_alsa.cpp index 4b7ddcd7f..ae5ab6c9d 100644 --- a/aegisub/src/audio_player_alsa.cpp +++ b/aegisub/src/audio_player_alsa.cpp @@ -40,7 +40,6 @@ #include -#include "audio_controller.h" #include "audio_player_alsa.h" #include "main.h" #include "compat.h" diff --git a/aegisub/src/audio_player_dsound.cpp b/aegisub/src/audio_player_dsound.cpp index 14ad47965..2fe021c1b 100644 --- a/aegisub/src/audio_player_dsound.cpp +++ b/aegisub/src/audio_player_dsound.cpp @@ -40,7 +40,6 @@ #include -#include "audio_controller.h" #include "audio_player_dsound.h" #include "frame_main.h" #include "main.h" diff --git a/aegisub/src/audio_player_openal.cpp b/aegisub/src/audio_player_openal.cpp index 443e7fb96..f87c11cd7 100644 --- a/aegisub/src/audio_player_openal.cpp +++ b/aegisub/src/audio_player_openal.cpp @@ -40,7 +40,6 @@ #include -#include "audio_controller.h" #include "audio_player_openal.h" #include "frame_main.h" #include "utils.h" diff --git a/aegisub/src/audio_player_oss.cpp b/aegisub/src/audio_player_oss.cpp index c9187371b..c9cfec9cb 100644 --- a/aegisub/src/audio_player_oss.cpp +++ b/aegisub/src/audio_player_oss.cpp @@ -38,7 +38,6 @@ #include -#include "audio_controller.h" #include "audio_player_oss.h" #include "frame_main.h" #include "compat.h" diff --git a/aegisub/src/audio_provider_hd.cpp b/aegisub/src/audio_provider_hd.cpp index db41eb909..c88664aec 100644 --- a/aegisub/src/audio_provider_hd.cpp +++ b/aegisub/src/audio_provider_hd.cpp @@ -41,7 +41,6 @@ #include #endif -#include "audio_controller.h" #include "audio_provider_hd.h" #include "compat.h" #include "dialog_progress.h" diff --git a/aegisub/src/audio_provider_ram.cpp b/aegisub/src/audio_provider_ram.cpp index 927c26f30..36df8824e 100644 --- a/aegisub/src/audio_provider_ram.cpp +++ b/aegisub/src/audio_provider_ram.cpp @@ -36,7 +36,6 @@ #include "config.h" -#include "audio_controller.h" #include "audio_provider_ram.h" #include "dialog_progress.h" #include "frame_main.h" diff --git a/aegisub/src/audio_timing.h b/aegisub/src/audio_timing.h index a1d0dc39e..49c66afa0 100644 --- a/aegisub/src/audio_timing.h +++ b/aegisub/src/audio_timing.h @@ -38,17 +38,27 @@ class AssDialogue; class AudioController; +#include /// @class AudioTimingController /// @brief Base class for objects controlling audio timing /// /// There is just one active audio timing controller at a time per audio controller. /// The timing controller manages the timing mode and supplies markers that can be -/// manupulated to the audio display, as well as the current selection. +/// manipulated to the audio display, as well as the current selection. /// /// The timing controller must then be sent the marker drag events as well as clicks /// in empty areas of the audio display. class AudioTimingController : public AudioMarkerProvider { +protected: + /// The primary playback range has changed, usually as a result of user interaction. + agi::signal::Signal<> AnnounceUpdatedPrimaryRange; + + /// One or more rendering style ranges have changed in the timing controller. + agi::signal::Signal<> AnnounceUpdatedStyleRanges; + + /// A marker has been updated in some way. + agi::signal::Signal AnnounceMarkerMoved; public: /// @brief Get any warning message to show in the audio display /// @return The warning message to show, may be empty if there is none @@ -58,13 +68,13 @@ public: /// @return A sample range /// /// This is used for "bring working area into view" operations. - virtual AudioController::SampleRange GetIdealVisibleSampleRange() const = 0; + virtual SampleRange GetIdealVisibleSampleRange() const = 0; /// @brief Get the primary playback range /// @return A sample range /// /// Get the sample range the user is most likely to want to play back currently. - virtual AudioController::SampleRange GetPrimaryPlaybackRange() const = 0; + virtual SampleRange GetPrimaryPlaybackRange() const = 0; /// @brief Does this timing mode have labels on the audio display? /// @return True if this timing mode needs labels on the audio display. @@ -122,9 +132,11 @@ public: virtual void OnMarkerDrag(AudioMarker *marker, int64_t new_position) = 0; /// @brief Destructor - /// - /// Does nothing in the base class, only present for virtual destruction. virtual ~AudioTimingController() { } + + DEFINE_SIGNAL_ADDERS(AnnounceUpdatedPrimaryRange, AddUpdatedPrimaryRangeListener) + DEFINE_SIGNAL_ADDERS(AnnounceUpdatedStyleRanges, AddUpdatedStyleRangesListener) + DEFINE_SIGNAL_ADDERS(AnnounceMarkerMoved, AddMarkerMovedListener) }; diff --git a/aegisub/src/audio_timing_dialogue.cpp b/aegisub/src/audio_timing_dialogue.cpp index a7687073e..df18274ce 100644 --- a/aegisub/src/audio_timing_dialogue.cpp +++ b/aegisub/src/audio_timing_dialogue.cpp @@ -143,12 +143,12 @@ private: public: // AudioMarkerProvider interface - virtual void GetMarkers(const AudioController::SampleRange &range, AudioMarkerVector &out_markers) const; + virtual void GetMarkers(const SampleRange &range, AudioMarkerVector &out_markers) const; // AudioTimingController interface virtual wxString GetWarningMessage() const; - virtual AudioController::SampleRange GetIdealVisibleSampleRange() const; - virtual AudioController::SampleRange GetPrimaryPlaybackRange() const; + virtual SampleRange GetIdealVisibleSampleRange() const; + virtual SampleRange GetPrimaryPlaybackRange() const; virtual bool HasLabels() const; virtual void Next(); virtual void Prev(); @@ -270,7 +270,7 @@ const AudioMarkerDialogueTiming *AudioTimingControllerDialogue::GetRightMarker() -void AudioTimingControllerDialogue::GetMarkers(const AudioController::SampleRange &range, AudioMarkerVector &out_markers) const +void AudioTimingControllerDialogue::GetMarkers(const SampleRange &range, AudioMarkerVector &out_markers) const { if (range.contains(markers[0].GetPosition())) out_markers.push_back(&markers[0]); @@ -303,16 +303,16 @@ wxString AudioTimingControllerDialogue::GetWarningMessage() const -AudioController::SampleRange AudioTimingControllerDialogue::GetIdealVisibleSampleRange() const +SampleRange AudioTimingControllerDialogue::GetIdealVisibleSampleRange() const { return GetPrimaryPlaybackRange(); } -AudioController::SampleRange AudioTimingControllerDialogue::GetPrimaryPlaybackRange() const +SampleRange AudioTimingControllerDialogue::GetPrimaryPlaybackRange() const { - return AudioController::SampleRange( + return SampleRange( GetLeftMarker()->GetPosition(), GetRightMarker()->GetPosition()); } @@ -396,7 +396,7 @@ void AudioTimingControllerDialogue::Revert() bool AudioTimingControllerDialogue::IsNearbyMarker(int64_t sample, int sensitivity) const { - AudioController::SampleRange range(sample-sensitivity, sample+sensitivity); + SampleRange range(sample-sensitivity, sample+sensitivity); return range.contains(markers[0].GetPosition()) || range.contains(markers[1].GetPosition()); } @@ -419,7 +419,7 @@ AudioMarker * AudioTimingControllerDialogue::OnLeftClick(int64_t sample, int sen // Clicked near the left marker: // Insta-move it and start dragging it left->SetPosition(sample); - audio_controller->OnTimingControllerMarkerMoved(this, left); + AnnounceMarkerMoved(left); timing_modified = true; UpdateSelection(); return left; @@ -436,7 +436,7 @@ AudioMarker * AudioTimingControllerDialogue::OnLeftClick(int64_t sample, int sen // Insta-set the left marker to the clicked position and return the right as the dragged one, // such that if the user does start dragging, he will create a new selection from scratch left->SetPosition(sample); - audio_controller->OnTimingControllerMarkerMoved(this, left); + AnnounceMarkerMoved(left); timing_modified = true; UpdateSelection(); return right; @@ -449,7 +449,7 @@ AudioMarker * AudioTimingControllerDialogue::OnRightClick(int64_t sample, int se AudioMarkerDialogueTiming *right = GetRightMarker(); right->SetPosition(sample); - audio_controller->OnTimingControllerMarkerMoved(this, right); + AnnounceMarkerMoved(right); timing_modified = true; UpdateSelection(); return right; @@ -462,7 +462,7 @@ void AudioTimingControllerDialogue::OnMarkerDrag(AudioMarker *marker, int64_t ne assert(marker == &markers[0] || marker == &markers[1]); static_cast(marker)->SetPosition(new_position); - audio_controller->OnTimingControllerMarkerMoved(this, marker); + AnnounceMarkerMoved(marker); timing_modified = true; UpdateSelection(); @@ -472,7 +472,7 @@ void AudioTimingControllerDialogue::OnMarkerDrag(AudioMarker *marker, int64_t ne void AudioTimingControllerDialogue::UpdateSelection() { - audio_controller->OnTimingControllerUpdatedPrimaryRange(this); + AnnounceUpdatedPrimaryRange(); } diff --git a/aegisub/src/base_grid.cpp b/aegisub/src/base_grid.cpp index 588ed91e2..71d4218b5 100644 --- a/aegisub/src/base_grid.cpp +++ b/aegisub/src/base_grid.cpp @@ -50,7 +50,6 @@ #include "ass_dialogue.h" #include "ass_file.h" #include "ass_style.h" -#include "audio_controller.h" #include "selection_controller.h" #include "compat.h" #include "frame_main.h" diff --git a/aegisub/src/dialog_detached_video.cpp b/aegisub/src/dialog_detached_video.cpp index 028c8107c..138711f1d 100644 --- a/aegisub/src/dialog_detached_video.cpp +++ b/aegisub/src/dialog_detached_video.cpp @@ -42,7 +42,6 @@ #include /// Must be included last. #endif -#include "audio_controller.h" #include "dialog_detached_video.h" #include "frame_main.h" #include "main.h" diff --git a/aegisub/src/dialog_fonts_collector.cpp b/aegisub/src/dialog_fonts_collector.cpp index 5e2a31de4..2143effd3 100644 --- a/aegisub/src/dialog_fonts_collector.cpp +++ b/aegisub/src/dialog_fonts_collector.cpp @@ -51,7 +51,6 @@ #include "ass_file.h" #include "ass_override.h" #include "ass_style.h" -#include "audio_controller.h" #include "compat.h" #include "dialog_fonts_collector.h" #include "font_file_lister.h" diff --git a/aegisub/src/dialog_search_replace.cpp b/aegisub/src/dialog_search_replace.cpp index d1be828a0..a4cdc9226 100644 --- a/aegisub/src/dialog_search_replace.cpp +++ b/aegisub/src/dialog_search_replace.cpp @@ -47,7 +47,6 @@ #include "compat.h" #include "ass_dialogue.h" #include "ass_file.h" -#include "audio_controller.h" #include "dialog_search_replace.h" #include "frame_main.h" #include "main.h" diff --git a/aegisub/src/dialog_spellchecker.cpp b/aegisub/src/dialog_spellchecker.cpp index d4c48d4af..703a7daae 100644 --- a/aegisub/src/dialog_spellchecker.cpp +++ b/aegisub/src/dialog_spellchecker.cpp @@ -44,7 +44,6 @@ #include "ass_dialogue.h" #include "ass_file.h" -#include "audio_controller.h" #include "compat.h" #include "dialog_spellchecker.h" #include "frame_main.h" diff --git a/aegisub/src/dialog_styling_assistant.cpp b/aegisub/src/dialog_styling_assistant.cpp index d65cdd258..b6c8f0d91 100644 --- a/aegisub/src/dialog_styling_assistant.cpp +++ b/aegisub/src/dialog_styling_assistant.cpp @@ -379,7 +379,7 @@ void DialogStyling::OnPlayVideoButton(wxCommandEvent &event) { /// @param event /// void DialogStyling::OnPlayAudioButton(wxCommandEvent &event) { - audio->PlayRange(AudioController::SampleRange( + audio->PlayRange(SampleRange( audio->SamplesFromMilliseconds(line->Start.GetMS()), audio->SamplesFromMilliseconds(line->End.GetMS()))); TypeBox->SetFocus(); diff --git a/aegisub/src/dialog_translation.cpp b/aegisub/src/dialog_translation.cpp index a5a6e3797..c2cf9e8df 100644 --- a/aegisub/src/dialog_translation.cpp +++ b/aegisub/src/dialog_translation.cpp @@ -444,7 +444,7 @@ void DialogTranslation::OnPlayVideoButton(wxCommandEvent &event) { /// @param event /// void DialogTranslation::OnPlayAudioButton(wxCommandEvent &event) { - audio->PlayRange(AudioController::SampleRange( + audio->PlayRange(SampleRange( audio->SamplesFromMilliseconds(current->Start.GetMS()), audio->SamplesFromMilliseconds(current->End.GetMS()))); TransText->SetFocus(); diff --git a/aegisub/src/drop.cpp b/aegisub/src/drop.cpp index 90c7a4fc1..a7cebb7c4 100644 --- a/aegisub/src/drop.cpp +++ b/aegisub/src/drop.cpp @@ -43,7 +43,6 @@ #include #endif -#include "audio_controller.h" #include "drop.h" #include "frame_main.h" diff --git a/aegisub/src/ffmpegsource_common.cpp b/aegisub/src/ffmpegsource_common.cpp index 678a71aa9..e4b474c69 100644 --- a/aegisub/src/ffmpegsource_common.cpp +++ b/aegisub/src/ffmpegsource_common.cpp @@ -48,7 +48,6 @@ #include -#include "audio_controller.h" #include "compat.h" #include "ffmpegsource_common.h" #include "frame_main.h" diff --git a/aegisub/src/frame_main.cpp b/aegisub/src/frame_main.cpp index 81cb710a6..088d20893 100644 --- a/aegisub/src/frame_main.cpp +++ b/aegisub/src/frame_main.cpp @@ -132,7 +132,8 @@ FrameMain::FrameMain (wxArrayString args) // Contexts and controllers audioController = new AudioController; - audioController->AddAudioListener(this); + audioController->AddAudioOpenListener(&FrameMain::OnAudioOpen, this); + audioController->AddAudioCloseListener(&FrameMain::OnAudioClose, this); // Create menu and tool bars StartupLog(_T("Apply saved Maximized state")); diff --git a/aegisub/src/frame_main.h b/aegisub/src/frame_main.h index 960a0c663..daed37ff5 100644 --- a/aegisub/src/frame_main.h +++ b/aegisub/src/frame_main.h @@ -47,10 +47,6 @@ #include #endif -#ifndef AGI_AUDIO_CONTROLLER_INCLUDED -#error You must include "audio_controller.h" before "frame_main.h" -#endif - class AssFile; class VideoDisplay; class VideoSlider; @@ -63,6 +59,7 @@ class DialogDetachedVideo; class DialogStyling; class AegisubFileDropTarget; class AudioController; +class AudioProvider; namespace Automation4 { class FeatureMacro; class ScriptManager; } @@ -73,7 +70,7 @@ namespace Automation4 { class FeatureMacro; class ScriptManager; } /// @brief DOCME /// /// DOCME -class FrameMain: public wxFrame, private AudioControllerAudioEventListener { +class FrameMain: public wxFrame { friend class AegisubFileDropTarget; friend class AegisubApp; friend class SubtitlesGrid; @@ -327,13 +324,9 @@ private: void RebuildRecentList(wxString listName,wxMenu *menu,int startID); void SynchronizeProject(bool FromSubs=false); - -private: // AudioControllerAudioEventListener implementation - virtual void OnAudioOpen(AudioProvider *provider); - virtual void OnAudioClose(); - virtual void OnPlaybackPosition(int64_t sample_position); - virtual void OnPlaybackStop(); + void OnAudioOpen(AudioProvider *provider); + void OnAudioClose(); void OnSubtitlesFileChanged(); diff --git a/aegisub/src/frame_main_events.cpp b/aegisub/src/frame_main_events.cpp index 964d13a56..4d3f6d623 100644 --- a/aegisub/src/frame_main_events.cpp +++ b/aegisub/src/frame_main_events.cpp @@ -1517,8 +1517,8 @@ void FrameMain::OnMedusaStop(wxCommandEvent &) { // Otherwise, play the last 500 ms else { - AudioController::SampleRange sel(audioController->GetPrimaryPlaybackRange()); - audioController->PlayRange(AudioController::SampleRange( + SampleRange sel(audioController->GetPrimaryPlaybackRange()); + audioController->PlayRange(SampleRange( sel.end() - audioController->SamplesFromMilliseconds(500), sel.end()));; } @@ -1526,7 +1526,7 @@ void FrameMain::OnMedusaStop(wxCommandEvent &) { /// @brief DOCME void FrameMain::OnMedusaShiftStartForward(wxCommandEvent &) { - AudioController::SampleRange newsel( + SampleRange newsel( audioController->GetPrimaryPlaybackRange(), audioController->SamplesFromMilliseconds(10), 0); @@ -1536,7 +1536,7 @@ void FrameMain::OnMedusaShiftStartForward(wxCommandEvent &) { /// @brief DOCME void FrameMain::OnMedusaShiftStartBack(wxCommandEvent &) { - AudioController::SampleRange newsel( + SampleRange newsel( audioController->GetPrimaryPlaybackRange(), -audioController->SamplesFromMilliseconds(10), 0); @@ -1546,7 +1546,7 @@ void FrameMain::OnMedusaShiftStartBack(wxCommandEvent &) { /// @brief DOCME void FrameMain::OnMedusaShiftEndForward(wxCommandEvent &) { - AudioController::SampleRange newsel( + SampleRange newsel( audioController->GetPrimaryPlaybackRange(), 0, audioController->SamplesFromMilliseconds(10)); @@ -1556,7 +1556,7 @@ void FrameMain::OnMedusaShiftEndForward(wxCommandEvent &) { /// @brief DOCME void FrameMain::OnMedusaShiftEndBack(wxCommandEvent &) { - AudioController::SampleRange newsel( + SampleRange newsel( audioController->GetPrimaryPlaybackRange(), 0, -audioController->SamplesFromMilliseconds(10)); @@ -1566,16 +1566,16 @@ void FrameMain::OnMedusaShiftEndBack(wxCommandEvent &) { /// @brief DOCME void FrameMain::OnMedusaPlayBefore(wxCommandEvent &) { - AudioController::SampleRange sel(audioController->GetPrimaryPlaybackRange()); - audioController->PlayRange(AudioController::SampleRange( + SampleRange sel(audioController->GetPrimaryPlaybackRange()); + audioController->PlayRange(SampleRange( sel.begin() - audioController->SamplesFromMilliseconds(500), sel.begin()));; } /// @brief DOCME void FrameMain::OnMedusaPlayAfter(wxCommandEvent &) { - AudioController::SampleRange sel(audioController->GetPrimaryPlaybackRange()); - audioController->PlayRange(AudioController::SampleRange( + SampleRange sel(audioController->GetPrimaryPlaybackRange()); + audioController->PlayRange(SampleRange( sel.end(), sel.end() + audioController->SamplesFromMilliseconds(500)));; } @@ -1623,16 +1623,6 @@ void FrameMain::OnAudioClose() SetDisplayMode(-1, 0); } -void FrameMain::OnPlaybackPosition(int64_t sample_position) -{ - // do nothing -} - -void FrameMain::OnPlaybackStop() -{ - // do nothing -} - void FrameMain::OnSubtitlesFileChanged() { if (OPT_GET("App/Auto/Save on Every Change")->GetBool()) { if (ass->IsModified() && !ass->filename.empty()) SaveSubtitles(false); @@ -1640,4 +1630,3 @@ void FrameMain::OnSubtitlesFileChanged() { UpdateTitle(); } - diff --git a/aegisub/src/main.cpp b/aegisub/src/main.cpp index 427465bc7..95a9a0b90 100644 --- a/aegisub/src/main.cpp +++ b/aegisub/src/main.cpp @@ -55,7 +55,6 @@ #include "ass_file.h" #include "ass_time.h" #include "selection_controller.h" -#include "audio_controller.h" #include "audio_box.h" #ifdef WITH_AUTOMATION #include "auto4_base.h" diff --git a/aegisub/src/subtitles_provider_libass.cpp b/aegisub/src/subtitles_provider_libass.cpp index abdc658ef..5e32a0ced 100644 --- a/aegisub/src/subtitles_provider_libass.cpp +++ b/aegisub/src/subtitles_provider_libass.cpp @@ -50,7 +50,6 @@ #include -#include "audio_controller.h" #include "ass_file.h" #include "dialog_progress.h" #include "frame_main.h" diff --git a/aegisub/src/video_box.cpp b/aegisub/src/video_box.cpp index a58eac78c..260135821 100644 --- a/aegisub/src/video_box.cpp +++ b/aegisub/src/video_box.cpp @@ -45,7 +45,6 @@ #include "ass_dialogue.h" #include "ass_file.h" -#include "audio_controller.h" #include "frame_main.h" #include "help_button.h" #include "libresrc/libresrc.h" diff --git a/aegisub/src/video_context.cpp b/aegisub/src/video_context.cpp index 58de11457..67eac055f 100644 --- a/aegisub/src/video_context.cpp +++ b/aegisub/src/video_context.cpp @@ -308,7 +308,7 @@ void VideoContext::PlayNextFrame() { JumpToFrame(frame_n + 1); // Start playing audio if (playAudioOnStep->GetBool()) { - audio->PlayRange(AudioController::SampleRange( + audio->PlayRange(SampleRange( audio->SamplesFromMilliseconds(TimeAtFrame(thisFrame)), audio->SamplesFromMilliseconds(TimeAtFrame(thisFrame + 1)))); } @@ -322,7 +322,7 @@ void VideoContext::PlayPrevFrame() { JumpToFrame(frame_n -1); // Start playing audio if (playAudioOnStep->GetBool()) { - audio->PlayRange(AudioController::SampleRange( + audio->PlayRange(SampleRange( audio->SamplesFromMilliseconds(TimeAtFrame(thisFrame - 1)), audio->SamplesFromMilliseconds(TimeAtFrame(thisFrame)))); } @@ -355,7 +355,7 @@ void VideoContext::PlayLine() { if (!curline) return; // Start playing audio - audio->PlayRange(AudioController::SampleRange( + audio->PlayRange(SampleRange( audio->SamplesFromMilliseconds(curline->Start.GetMS()), audio->SamplesFromMilliseconds(curline->End.GetMS())));