mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 09:02:43 +00:00 
			
		
		
		
	AudioPlayer: Further decouple the player from the GUI
This commit is contained in:
		
							parent
							
								
									f9e4bff487
								
							
						
					
					
						commit
						e4d6a56a28
					
				
					 6 changed files with 136 additions and 76 deletions
				
			
		|  | @ -28,11 +28,48 @@ | ||||||
| 
 | 
 | ||||||
| #include "PlaybackManager.h" | #include "PlaybackManager.h" | ||||||
| #include "VisualizationBase.h" | #include "VisualizationBase.h" | ||||||
|  | #include <AK/RefPtr.h> | ||||||
|  | 
 | ||||||
|  | struct PlayerState { | ||||||
|  |     bool is_paused; | ||||||
|  |     bool is_stopped; | ||||||
|  |     bool has_loaded_file; | ||||||
|  |     bool is_looping; | ||||||
|  |     double volume; | ||||||
|  |     Audio::ClientConnection& connection; | ||||||
|  |     PlaybackManager& manager; | ||||||
|  |     StringView loaded_filename; | ||||||
|  | }; | ||||||
| 
 | 
 | ||||||
| class Player { | class Player { | ||||||
| public: | public: | ||||||
|     explicit Player() = default; |     explicit Player(PlayerState& state) | ||||||
|  |         : m_player_state(state) {}; | ||||||
|     virtual void open_file(StringView path) = 0; |     virtual void open_file(StringView path) = 0; | ||||||
|     virtual Audio::ClientConnection& client_connection() = 0; |     virtual void play() = 0; | ||||||
|     virtual PlaybackManager& playback_manager() = 0; | 
 | ||||||
|  |     PlayerState& get_player_state() { return m_player_state; } | ||||||
|  |     bool is_stopped() const { return m_player_state.is_stopped; } | ||||||
|  |     bool is_paused() const { return m_player_state.is_paused; } | ||||||
|  |     bool has_loaded_file() const { return m_player_state.has_loaded_file; } | ||||||
|  |     double volume() const { return m_player_state.volume; } | ||||||
|  |     bool looping() const { return m_player_state.is_looping; } | ||||||
|  |     StringView& loaded_filename() { return m_player_state.loaded_filename; } | ||||||
|  | 
 | ||||||
|  |     virtual void set_stopped(bool stopped) { m_player_state.is_stopped = stopped; } | ||||||
|  |     virtual void set_paused(bool paused) { m_player_state.is_paused = paused; } | ||||||
|  |     virtual void set_has_loaded_file(bool loaded) { m_player_state.has_loaded_file = loaded; } | ||||||
|  |     virtual void set_volume(double volume) { m_player_state.volume = volume; } | ||||||
|  |     virtual void set_looping(bool loop) | ||||||
|  |     { | ||||||
|  |         m_player_state.is_looping = loop; | ||||||
|  |         manager().loop(loop); | ||||||
|  |     } | ||||||
|  |     virtual void set_loaded_filename(StringView& filename) { m_player_state.loaded_filename = filename; } | ||||||
|  | 
 | ||||||
|  |     Audio::ClientConnection& client_connection() { return m_player_state.connection; } | ||||||
|  |     PlaybackManager& manager() { return m_player_state.manager; } | ||||||
|  | 
 | ||||||
|  | protected: | ||||||
|  |     PlayerState m_player_state; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | @ -33,10 +33,9 @@ | ||||||
| #include <LibGUI/Label.h> | #include <LibGUI/Label.h> | ||||||
| #include <LibGUI/MessageBox.h> | #include <LibGUI/MessageBox.h> | ||||||
| 
 | 
 | ||||||
| SoundPlayerWidget::SoundPlayerWidget(GUI::Window& window, Audio::ClientConnection& connection, PlaybackManager& manager) | SoundPlayerWidget::SoundPlayerWidget(GUI::Window& window, PlayerState& state) | ||||||
|     : m_window(window) |     : Player(state) | ||||||
|     , m_connection(connection) |     , m_window(window) | ||||||
|     , m_manager(manager) |  | ||||||
| { | { | ||||||
|     window.set_resizable(false); |     window.set_resizable(false); | ||||||
|     window.resize(350, 140); |     window.resize(350, 140); | ||||||
|  | @ -68,8 +67,8 @@ SoundPlayerWidget::SoundPlayerWidget(GUI::Window& window, Audio::ClientConnectio | ||||||
| 
 | 
 | ||||||
|     m_slider = add<Slider>(Orientation::Horizontal); |     m_slider = add<Slider>(Orientation::Horizontal); | ||||||
|     m_slider->set_min(0); |     m_slider->set_min(0); | ||||||
|     m_slider->set_enabled(false); |     m_slider->set_enabled(has_loaded_file()); | ||||||
|     m_slider->on_knob_released = [&](int value) { m_manager.seek(denormalize_rate(value)); }; |     m_slider->on_knob_released = [&](int value) { manager().seek(denormalize_rate(value)); }; | ||||||
| 
 | 
 | ||||||
|     auto& control_widget = add<GUI::Widget>(); |     auto& control_widget = add<GUI::Widget>(); | ||||||
|     control_widget.set_fill_with_background_color(true); |     control_widget.set_fill_with_background_color(true); | ||||||
|  | @ -79,16 +78,21 @@ SoundPlayerWidget::SoundPlayerWidget(GUI::Window& window, Audio::ClientConnectio | ||||||
|     control_widget.layout()->set_spacing(10); |     control_widget.layout()->set_spacing(10); | ||||||
| 
 | 
 | ||||||
|     m_play = control_widget.add<GUI::Button>(); |     m_play = control_widget.add<GUI::Button>(); | ||||||
|     m_play->set_icon(*m_pause_icon); |     m_play->set_icon(has_loaded_file() ? *m_play_icon : *m_pause_icon); | ||||||
|     m_play->set_enabled(false); |     m_play->set_enabled(has_loaded_file()); | ||||||
|     m_play->on_click = [this](auto) { |     m_play->on_click = [this](auto) { | ||||||
|         m_play->set_icon(m_manager.toggle_pause() ? *m_play_icon : *m_pause_icon); |         bool paused = manager().toggle_pause(); | ||||||
|  |         set_paused(paused); | ||||||
|  |         m_play->set_icon(paused ? *m_play_icon : *m_pause_icon); | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     m_stop = control_widget.add<GUI::Button>(); |     m_stop = control_widget.add<GUI::Button>(); | ||||||
|     m_stop->set_enabled(false); |     m_stop->set_enabled(has_loaded_file()); | ||||||
|     m_stop->set_icon(Gfx::Bitmap::load_from_file("/res/icons/16x16/stop.png")); |     m_stop->set_icon(Gfx::Bitmap::load_from_file("/res/icons/16x16/stop.png")); | ||||||
|     m_stop->on_click = [this](auto) { m_manager.stop(); }; |     m_stop->on_click = [this](auto) { | ||||||
|  |         manager().stop(); | ||||||
|  |         set_stopped(true); | ||||||
|  |     }; | ||||||
| 
 | 
 | ||||||
|     m_status = add<GUI::Label>(); |     m_status = add<GUI::Label>(); | ||||||
|     m_status->set_frame_shape(Gfx::FrameShape::Box); |     m_status->set_frame_shape(Gfx::FrameShape::Box); | ||||||
|  | @ -96,11 +100,11 @@ SoundPlayerWidget::SoundPlayerWidget(GUI::Window& window, Audio::ClientConnectio | ||||||
|     m_status->set_frame_thickness(4); |     m_status->set_frame_thickness(4); | ||||||
|     m_status->set_text_alignment(Gfx::TextAlignment::CenterLeft); |     m_status->set_text_alignment(Gfx::TextAlignment::CenterLeft); | ||||||
|     m_status->set_fixed_height(18); |     m_status->set_fixed_height(18); | ||||||
|     m_status->set_text("No file open!"); |     m_status->set_text(has_loaded_file() ? loaded_filename() : "No file open!"); | ||||||
| 
 | 
 | ||||||
|     update_position(0); |     update_position(0); | ||||||
| 
 | 
 | ||||||
|     m_manager.on_update = [&]() { update_ui(); }; |     manager().on_update = [&]() { update_ui(); }; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| SoundPlayerWidget::~SoundPlayerWidget() | SoundPlayerWidget::~SoundPlayerWidget() | ||||||
|  | @ -132,8 +136,10 @@ void SoundPlayerWidget::open_file(StringView path) | ||||||
|         loader->num_channels(), |         loader->num_channels(), | ||||||
|         loader->bits_per_sample())); |         loader->bits_per_sample())); | ||||||
| 
 | 
 | ||||||
|     m_manager.set_loader(move(loader)); |     manager().set_loader(move(loader)); | ||||||
|     update_position(0); |     update_position(0); | ||||||
|  |     set_has_loaded_file(true); | ||||||
|  |     set_loaded_filename(path); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void SoundPlayerWidget::drop_event(GUI::DropEvent& event) | void SoundPlayerWidget::drop_event(GUI::DropEvent& event) | ||||||
|  | @ -161,16 +167,16 @@ int SoundPlayerWidget::denormalize_rate(int rate) const | ||||||
| 
 | 
 | ||||||
| void SoundPlayerWidget::update_ui() | void SoundPlayerWidget::update_ui() | ||||||
| { | { | ||||||
|     m_sample_widget->set_buffer(m_manager.current_buffer()); |     m_sample_widget->set_buffer(manager().current_buffer()); | ||||||
|     m_play->set_icon(m_manager.is_paused() ? *m_play_icon : *m_pause_icon); |     m_play->set_icon(manager().is_paused() ? *m_play_icon : *m_pause_icon); | ||||||
|     update_position(m_manager.connection()->get_played_samples()); |     update_position(manager().connection()->get_played_samples()); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void SoundPlayerWidget::update_position(const int position) | void SoundPlayerWidget::update_position(const int position) | ||||||
| { | { | ||||||
|     int total_norm_samples = position + normalize_rate(m_manager.last_seek()); |     int total_norm_samples = position + normalize_rate(manager().last_seek()); | ||||||
|     float seconds = (total_norm_samples / static_cast<float>(PLAYBACK_MANAGER_RATE)); |     float seconds = (total_norm_samples / static_cast<float>(PLAYBACK_MANAGER_RATE)); | ||||||
|     float remaining_seconds = m_manager.total_length() - seconds; |     float remaining_seconds = manager().total_length() - seconds; | ||||||
| 
 | 
 | ||||||
|     m_elapsed->set_text(String::formatted( |     m_elapsed->set_text(String::formatted( | ||||||
|         "Elapsed:\n{}:{:02}.{:02}", |         "Elapsed:\n{}:{:02}.{:02}", | ||||||
|  | @ -191,3 +197,10 @@ void SoundPlayerWidget::hide_scope(bool hide) | ||||||
| { | { | ||||||
|     m_sample_widget->set_visible(!hide); |     m_sample_widget->set_visible(!hide); | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | void SoundPlayerWidget::play() | ||||||
|  | { | ||||||
|  |     manager().play(); | ||||||
|  |     set_paused(false); | ||||||
|  |     set_stopped(false); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -40,16 +40,15 @@ class SoundPlayerWidget final : public GUI::Widget | ||||||
|     , public Player { |     , public Player { | ||||||
|     C_OBJECT(SoundPlayerWidget) |     C_OBJECT(SoundPlayerWidget) | ||||||
| public: | public: | ||||||
|     virtual ~SoundPlayerWidget() override; |     ~SoundPlayerWidget() override; | ||||||
|     void open_file(StringView path) override; |     void open_file(StringView path) override; | ||||||
|  |     void play() override; | ||||||
|     void hide_scope(bool); |     void hide_scope(bool); | ||||||
|     Audio::ClientConnection& client_connection() override { return m_connection; } |  | ||||||
|     PlaybackManager& playback_manager() override { return m_manager; } |  | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|     explicit SoundPlayerWidget(GUI::Window& window, Audio::ClientConnection& connection, PlaybackManager& manager); |     explicit SoundPlayerWidget(GUI::Window& window, PlayerState& state); | ||||||
| 
 | 
 | ||||||
|     virtual void drop_event(GUI::DropEvent&) override; |     void drop_event(GUI::DropEvent&) override; | ||||||
| 
 | 
 | ||||||
|     void update_position(const int position); |     void update_position(const int position); | ||||||
|     void update_ui(); |     void update_ui(); | ||||||
|  | @ -57,8 +56,6 @@ private: | ||||||
|     int denormalize_rate(int) const; |     int denormalize_rate(int) const; | ||||||
| 
 | 
 | ||||||
|     GUI::Window& m_window; |     GUI::Window& m_window; | ||||||
|     Audio::ClientConnection& m_connection; |  | ||||||
|     PlaybackManager& m_manager; |  | ||||||
| 
 | 
 | ||||||
|     float m_sample_ratio { 1.0 }; |     float m_sample_ratio { 1.0 }; | ||||||
|     RefPtr<GUI::Label> m_status; |     RefPtr<GUI::Label> m_status; | ||||||
|  |  | ||||||
|  | @ -41,12 +41,10 @@ | ||||||
| #include <LibGUI/Window.h> | #include <LibGUI/Window.h> | ||||||
| #include <LibGfx/Bitmap.h> | #include <LibGfx/Bitmap.h> | ||||||
| 
 | 
 | ||||||
| SoundPlayerWidgetAdvancedView::SoundPlayerWidgetAdvancedView(GUI::Window& window, Audio::ClientConnection& connection, PlaybackManager& manager) | SoundPlayerWidgetAdvancedView::SoundPlayerWidgetAdvancedView(GUI::Window& window, PlayerState& state) | ||||||
|     : m_window(window) |     : Player(state) | ||||||
|     , m_connection(connection) |     , m_window(window) | ||||||
|     , m_manager(manager) |  | ||||||
| { | { | ||||||
| 
 |  | ||||||
|     window.resize(455, 350); |     window.resize(455, 350); | ||||||
|     window.set_minimum_size(440, 130); |     window.set_minimum_size(440, 130); | ||||||
|     window.set_resizable(true); |     window.set_resizable(true); | ||||||
|  | @ -65,9 +63,9 @@ SoundPlayerWidgetAdvancedView::SoundPlayerWidgetAdvancedView(GUI::Window& window | ||||||
|     m_playback_progress_slider = add<Slider>(Orientation::Horizontal); |     m_playback_progress_slider = add<Slider>(Orientation::Horizontal); | ||||||
|     m_playback_progress_slider->set_fixed_height(20); |     m_playback_progress_slider->set_fixed_height(20); | ||||||
|     m_playback_progress_slider->set_min(0); |     m_playback_progress_slider->set_min(0); | ||||||
|     m_playback_progress_slider->set_max(m_manager.total_length() * 44100); //this value should be set when we load a new file
 |     m_playback_progress_slider->set_max(this->manager().total_length() * 44100); //this value should be set when we load a new file
 | ||||||
|     m_playback_progress_slider->on_knob_released = [&](int value) { |     m_playback_progress_slider->on_knob_released = [&](int value) { | ||||||
|         m_manager.seek(value); |         this->manager().seek(value); | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     auto& toolbar_container = add<GUI::ToolBarContainer>(); |     auto& toolbar_container = add<GUI::ToolBarContainer>(); | ||||||
|  | @ -75,20 +73,22 @@ SoundPlayerWidgetAdvancedView::SoundPlayerWidgetAdvancedView(GUI::Window& window | ||||||
|     auto& menubar = toolbar_container.add<GUI::ToolBar>(); |     auto& menubar = toolbar_container.add<GUI::ToolBar>(); | ||||||
| 
 | 
 | ||||||
|     m_play_button = menubar.add<GUI::Button>(); |     m_play_button = menubar.add<GUI::Button>(); | ||||||
|     m_play_button->set_icon(*m_play_icon); |     m_play_button->set_icon(is_paused() ? (!has_loaded_file() ? *m_play_icon : *m_pause_icon) : *m_pause_icon); | ||||||
|     m_play_button->set_fixed_width(50); |     m_play_button->set_fixed_width(50); | ||||||
| 
 |     m_play_button->set_enabled(has_loaded_file()); | ||||||
|     m_play_button->on_click = [&](unsigned) { |     m_play_button->on_click = [&](unsigned) { | ||||||
|         bool paused = m_manager.toggle_pause(); |         bool paused = this->manager().toggle_pause(); | ||||||
|  |         set_paused(paused); | ||||||
|         m_play_button->set_icon(paused ? *m_play_icon : *m_pause_icon); |         m_play_button->set_icon(paused ? *m_play_icon : *m_pause_icon); | ||||||
|         m_stop_button->set_enabled(!paused); |  | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     m_stop_button = menubar.add<GUI::Button>(); |     m_stop_button = menubar.add<GUI::Button>(); | ||||||
|     m_stop_button->set_icon(*m_stop_icon); |     m_stop_button->set_icon(*m_stop_icon); | ||||||
|     m_stop_button->set_fixed_width(50); |     m_stop_button->set_fixed_width(50); | ||||||
|  |     m_stop_button->set_enabled(has_loaded_file()); | ||||||
|     m_stop_button->on_click = [&](unsigned) { |     m_stop_button->on_click = [&](unsigned) { | ||||||
|         m_manager.stop(); |         this->manager().stop(); | ||||||
|  |         set_stopped(true); | ||||||
|         m_play_button->set_icon(*m_play_icon); |         m_play_button->set_icon(*m_play_icon); | ||||||
|         m_stop_button->set_enabled(false); |         m_stop_button->set_enabled(false); | ||||||
|     }; |     }; | ||||||
|  | @ -100,13 +100,15 @@ SoundPlayerWidgetAdvancedView::SoundPlayerWidgetAdvancedView(GUI::Window& window | ||||||
|     // filler_label
 |     // filler_label
 | ||||||
|     menubar.add<GUI::Label>(); |     menubar.add<GUI::Label>(); | ||||||
| 
 | 
 | ||||||
|     auto& back_button = menubar.add<GUI::Button>(); |     m_back_button = menubar.add<GUI::Button>(); | ||||||
|     back_button.set_fixed_width(50); |     m_back_button->set_fixed_width(50); | ||||||
|     back_button.set_icon(*m_back_icon); |     m_back_button->set_icon(*m_back_icon); | ||||||
|  |     m_back_button->set_enabled(has_loaded_file()); | ||||||
| 
 | 
 | ||||||
|     auto& next_button = menubar.add<GUI::Button>(); |     m_next_button = menubar.add<GUI::Button>(); | ||||||
|     next_button.set_fixed_width(50); |     m_next_button->set_fixed_width(50); | ||||||
|     next_button.set_icon(*m_next_icon); |     m_next_button->set_icon(*m_next_icon); | ||||||
|  |     m_next_button->set_enabled(has_loaded_file()); | ||||||
| 
 | 
 | ||||||
|     m_volume_label = &menubar.add<GUI::Label>(); |     m_volume_label = &menubar.add<GUI::Label>(); | ||||||
|     m_volume_label->set_fixed_width(30); |     m_volume_label->set_fixed_width(30); | ||||||
|  | @ -127,41 +129,36 @@ SoundPlayerWidgetAdvancedView::SoundPlayerWidgetAdvancedView(GUI::Window& window | ||||||
|     set_volume(1.); |     set_volume(1.); | ||||||
|     set_nonlinear_volume_slider(false); |     set_nonlinear_volume_slider(false); | ||||||
| 
 | 
 | ||||||
|     m_manager.on_update = [&]() { |     manager().on_update = [&]() { | ||||||
|         //TODO: make this program support other sample rates
 |         //TODO: make this program support other sample rates
 | ||||||
|         int samples_played = m_connection.get_played_samples() + m_manager.last_seek(); |         int samples_played = client_connection().get_played_samples() + this->manager().last_seek(); | ||||||
|         int current_second = samples_played / 44100; |         int current_second = samples_played / 44100; | ||||||
|         timestamp_label.set_text(String::formatted("Elapsed: {:02}:{:02}:{:02}", current_second / 3600, current_second / 60, current_second % 60)); |         timestamp_label.set_text(String::formatted("Elapsed: {:02}:{:02}:{:02}", current_second / 3600, current_second / 60, current_second % 60)); | ||||||
|         m_playback_progress_slider->set_value(samples_played); |         m_playback_progress_slider->set_value(samples_played); | ||||||
| 
 | 
 | ||||||
|         dynamic_cast<Visualization*>(m_visualization.ptr())->set_buffer(m_manager.current_buffer()); |         dynamic_cast<Visualization*>(m_visualization.ptr())->set_buffer(this->manager().current_buffer()); | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     m_manager.on_load_sample_buffer = [&](Audio::Buffer& buffer) { |     this->manager().on_load_sample_buffer = [&](Audio::Buffer& buffer) { | ||||||
|         if (m_volume == 1.) |         if (volume() == 1.) | ||||||
|             return; |             return; | ||||||
|         auto sample_count = buffer.sample_count(); |         auto sample_count = buffer.sample_count(); | ||||||
|         if (sample_count % 4 == 0) { |         if (sample_count % 4 == 0) { | ||||||
|             const int total_iter = sample_count / (sizeof(AK::SIMD::f64x4) / sizeof(double) / 2); |             const int total_iter = sample_count / (sizeof(AK::SIMD::f64x4) / sizeof(double) / 2); | ||||||
|             AK::SIMD::f64x4* sample_ptr = const_cast<AK::SIMD::f64x4*>(reinterpret_cast<const AK::SIMD::f64x4*>((buffer.data()))); |             AK::SIMD::f64x4* sample_ptr = const_cast<AK::SIMD::f64x4*>(reinterpret_cast<const AK::SIMD::f64x4*>((buffer.data()))); | ||||||
|             for (int i = 0; i < total_iter; ++i) { |             for (int i = 0; i < total_iter; ++i) { | ||||||
|                 sample_ptr[i] = sample_ptr[i] * m_volume; |                 sample_ptr[i] = sample_ptr[i] * volume(); | ||||||
|             } |             } | ||||||
|         } else { |         } else { | ||||||
|             const int total_iter = sample_count / (sizeof(AK::SIMD::f64x2) / sizeof(double) / 2); |             const int total_iter = sample_count / (sizeof(AK::SIMD::f64x2) / sizeof(double) / 2); | ||||||
|             AK::SIMD::f64x2* sample_ptr = const_cast<AK::SIMD::f64x2*>(reinterpret_cast<const AK::SIMD::f64x2*>((buffer.data()))); |             AK::SIMD::f64x2* sample_ptr = const_cast<AK::SIMD::f64x2*>(reinterpret_cast<const AK::SIMD::f64x2*>((buffer.data()))); | ||||||
|             for (int i = 0; i < total_iter; ++i) { |             for (int i = 0; i < total_iter; ++i) { | ||||||
|                 sample_ptr[i] = sample_ptr[i] * m_volume; |                 sample_ptr[i] = sample_ptr[i] * volume(); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     }; |     }; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void SoundPlayerWidgetAdvancedView::set_volume(double value) |  | ||||||
| { |  | ||||||
|     m_volume = value; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void SoundPlayerWidgetAdvancedView::open_file(StringView path) | void SoundPlayerWidgetAdvancedView::open_file(StringView path) | ||||||
| { | { | ||||||
|     NonnullRefPtr<Audio::Loader> loader = Audio::Loader::create(path); |     NonnullRefPtr<Audio::Loader> loader = Audio::Loader::create(path); | ||||||
|  | @ -173,7 +170,12 @@ void SoundPlayerWidgetAdvancedView::open_file(StringView path) | ||||||
|     } |     } | ||||||
|     m_window.set_title(String::formatted("{} - SoundPlayer", loader->file()->filename())); |     m_window.set_title(String::formatted("{} - SoundPlayer", loader->file()->filename())); | ||||||
|     m_playback_progress_slider->set_max(loader->total_samples()); |     m_playback_progress_slider->set_max(loader->total_samples()); | ||||||
|     m_manager.set_loader(move(loader)); |     m_playback_progress_slider->set_enabled(true); | ||||||
|  |     m_play_button->set_enabled(true); | ||||||
|  |     m_stop_button->set_enabled(true); | ||||||
|  |     manager().set_loader(move(loader)); | ||||||
|  |     set_has_loaded_file(true); | ||||||
|  |     set_loaded_filename(path); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void SoundPlayerWidgetAdvancedView::set_nonlinear_volume_slider(bool nonlinear) | void SoundPlayerWidgetAdvancedView::set_nonlinear_volume_slider(bool nonlinear) | ||||||
|  | @ -196,5 +198,13 @@ void SoundPlayerWidgetAdvancedView::drop_event(GUI::DropEvent& event) | ||||||
| 
 | 
 | ||||||
| SoundPlayerWidgetAdvancedView::~SoundPlayerWidgetAdvancedView() | SoundPlayerWidgetAdvancedView::~SoundPlayerWidgetAdvancedView() | ||||||
| { | { | ||||||
|     m_manager.on_load_sample_buffer = nullptr; |     manager().on_load_sample_buffer = nullptr; | ||||||
|  |     manager().on_update = nullptr; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void SoundPlayerWidgetAdvancedView::play() | ||||||
|  | { | ||||||
|  |     manager().play(); | ||||||
|  |     set_paused(false); | ||||||
|  |     set_stopped(false); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -39,12 +39,11 @@ class SoundPlayerWidgetAdvancedView final : public GUI::Widget | ||||||
|     C_OBJECT(SoundPlayerWidgetAdvancedView) |     C_OBJECT(SoundPlayerWidgetAdvancedView) | ||||||
| 
 | 
 | ||||||
| public: | public: | ||||||
|     explicit SoundPlayerWidgetAdvancedView(GUI::Window& window, Audio::ClientConnection& connection, PlaybackManager& manager); |     explicit SoundPlayerWidgetAdvancedView(GUI::Window& window, PlayerState& state); | ||||||
|     ~SoundPlayerWidgetAdvancedView() override; |     ~SoundPlayerWidgetAdvancedView() override; | ||||||
| 
 | 
 | ||||||
|     void open_file(StringView path) override; |     void open_file(StringView path) override; | ||||||
|     Audio::ClientConnection& client_connection() override { return m_connection; } |     void play() override; | ||||||
|     PlaybackManager& playback_manager() override { return m_manager; } |  | ||||||
| 
 | 
 | ||||||
|     template<typename T> |     template<typename T> | ||||||
|     void set_visualization() |     void set_visualization() | ||||||
|  | @ -58,14 +57,9 @@ public: | ||||||
| 
 | 
 | ||||||
|     void set_nonlinear_volume_slider(bool nonlinear); |     void set_nonlinear_volume_slider(bool nonlinear); | ||||||
| 
 | 
 | ||||||
|     void set_volume(double value); |  | ||||||
| 
 |  | ||||||
| private: | private: | ||||||
|     void drop_event(GUI::DropEvent& event) override; |     void drop_event(GUI::DropEvent& event) override; | ||||||
| 
 |  | ||||||
|     GUI::Window& m_window; |     GUI::Window& m_window; | ||||||
|     Audio::ClientConnection& m_connection; |  | ||||||
|     PlaybackManager& m_manager; |  | ||||||
| 
 | 
 | ||||||
|     RefPtr<GUI::Widget> m_visualization; |     RefPtr<GUI::Widget> m_visualization; | ||||||
| 
 | 
 | ||||||
|  | @ -77,9 +71,10 @@ private: | ||||||
| 
 | 
 | ||||||
|     RefPtr<GUI::Button> m_play_button; |     RefPtr<GUI::Button> m_play_button; | ||||||
|     RefPtr<GUI::Button> m_stop_button; |     RefPtr<GUI::Button> m_stop_button; | ||||||
|  |     RefPtr<GUI::Button> m_back_button; | ||||||
|  |     RefPtr<GUI::Button> m_next_button; | ||||||
|     RefPtr<Slider> m_playback_progress_slider; |     RefPtr<Slider> m_playback_progress_slider; | ||||||
|     RefPtr<GUI::Label> m_volume_label; |     RefPtr<GUI::Label> m_volume_label; | ||||||
| 
 | 
 | ||||||
|     double m_volume; |  | ||||||
|     bool m_nonlinear_volume_slider; |     bool m_nonlinear_volume_slider; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | @ -54,8 +54,15 @@ int main(int argc, char** argv) | ||||||
| 
 | 
 | ||||||
|     auto audio_client = Audio::ClientConnection::construct(); |     auto audio_client = Audio::ClientConnection::construct(); | ||||||
|     audio_client->handshake(); |     audio_client->handshake(); | ||||||
| 
 |  | ||||||
|     PlaybackManager playback_manager(audio_client); |     PlaybackManager playback_manager(audio_client); | ||||||
|  |     PlayerState initial_player_state { true, | ||||||
|  |         true, | ||||||
|  |         false, | ||||||
|  |         false, | ||||||
|  |         1.0, | ||||||
|  |         audio_client, | ||||||
|  |         playback_manager, | ||||||
|  |         "" }; | ||||||
| 
 | 
 | ||||||
|     if (pledge("stdio recvfd sendfd accept rpath thread", nullptr) < 0) { |     if (pledge("stdio recvfd sendfd accept rpath thread", nullptr) < 0) { | ||||||
|         perror("pledge"); |         perror("pledge"); | ||||||
|  | @ -72,11 +79,11 @@ int main(int argc, char** argv) | ||||||
| 
 | 
 | ||||||
|     auto& app_menu = menubar->add_menu("File"); |     auto& app_menu = menubar->add_menu("File"); | ||||||
|     // start in simple view by default
 |     // start in simple view by default
 | ||||||
|     Player* player = &window->set_main_widget<SoundPlayerWidget>(window, audio_client, playback_manager); |     Player* player = &window->set_main_widget<SoundPlayerWidget>(window, initial_player_state); | ||||||
|     if (argc > 1) { |     if (argc > 1) { | ||||||
|         String path = argv[1]; |         String path = argv[1]; | ||||||
|         player->open_file(path); |         player->open_file(path); | ||||||
|         player->playback_manager().play(); |         player->play(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     app_menu.add_action(GUI::CommonActions::make_open_action([&](auto&) { |     app_menu.add_action(GUI::CommonActions::make_open_action([&](auto&) { | ||||||
|  | @ -89,12 +96,13 @@ int main(int argc, char** argv) | ||||||
|     RefPtr<GUI::Action> hide_scope; |     RefPtr<GUI::Action> hide_scope; | ||||||
| 
 | 
 | ||||||
|     auto advanced_view_check = GUI::Action::create_checkable("Advanced view", { Mod_Ctrl, Key_A }, [&](auto& action) { |     auto advanced_view_check = GUI::Action::create_checkable("Advanced view", { Mod_Ctrl, Key_A }, [&](auto& action) { | ||||||
|  |         PlayerState state = player->get_player_state(); | ||||||
|         window->close(); |         window->close(); | ||||||
|         if (action.is_checked()) { |         if (action.is_checked()) { | ||||||
|             player = &window->set_main_widget<SoundPlayerWidgetAdvancedView>(window, audio_client, playback_manager); |             player = &window->set_main_widget<SoundPlayerWidgetAdvancedView>(window, state); | ||||||
|             hide_scope->set_checkable(false); |             hide_scope->set_checkable(false); | ||||||
|         } else { |         } else { | ||||||
|             player = &window->set_main_widget<SoundPlayerWidget>(window, audio_client, playback_manager); |             player = &window->set_main_widget<SoundPlayerWidget>(window, state); | ||||||
|             hide_scope->set_checkable(true); |             hide_scope->set_checkable(true); | ||||||
|         } |         } | ||||||
|         window->show(); |         window->show(); | ||||||
|  | @ -123,7 +131,7 @@ int main(int argc, char** argv) | ||||||
|     auto& playback_menu = menubar->add_menu("Playback"); |     auto& playback_menu = menubar->add_menu("Playback"); | ||||||
| 
 | 
 | ||||||
|     auto loop = GUI::Action::create_checkable("Loop", { Mod_Ctrl, Key_R }, [&](auto& action) { |     auto loop = GUI::Action::create_checkable("Loop", { Mod_Ctrl, Key_R }, [&](auto& action) { | ||||||
|         player->playback_manager().loop(action.is_checked()); |         player->set_looping(action.is_checked()); | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|     playback_menu.add_action(move(loop)); |     playback_menu.add_action(move(loop)); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Cesar Torres
						Cesar Torres