mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 13:32:45 +00:00 
			
		
		
		
	SoundPlayer: Add samplerate variable to visualizations
also fix conflict
This commit is contained in:
		
							parent
							
								
									2e28b8ebcc
								
							
						
					
					
						commit
						fd126578d9
					
				
					 12 changed files with 51 additions and 311 deletions
				
			
		|  | @ -49,8 +49,7 @@ void BarsVisualizationWidget::paint_event(GUI::PaintEvent& event) | |||
|     fft(m_sample_buffer, false); | ||||
|     double max = sqrt(m_sample_count * 2); | ||||
| 
 | ||||
|     //TODO: don't hardcode this!
 | ||||
|     double freq_bin = 44100 / m_sample_count; | ||||
|     double freq_bin = m_samplerate / m_sample_count; | ||||
| 
 | ||||
|     constexpr int group_count = 60; | ||||
|     Vector<double, group_count> groups; | ||||
|  | @ -73,7 +72,7 @@ void BarsVisualizationWidget::paint_event(GUI::PaintEvent& event) | |||
| 
 | ||||
|     const int horizontal_margin = 30; | ||||
|     const int top_vertical_margin = 15; | ||||
|     const int pixels_inbetween_groups = 5; | ||||
|     const int pixels_inbetween_groups = frame_inner_rect().width() > 350 ? 5 : 2; | ||||
|     int pixel_per_group_width = (frame_inner_rect().width() - horizontal_margin * 2 - pixels_inbetween_groups * (group_count - 1)) / group_count; | ||||
|     int max_height = frame_inner_rect().height() - top_vertical_margin; | ||||
|     int current_xpos = horizontal_margin; | ||||
|  | @ -146,3 +145,7 @@ void BarsVisualizationWidget::mousedown_event(GUI::MouseEvent& event) | |||
|     } | ||||
| } | ||||
| 
 | ||||
| void BarsVisualizationWidget::set_samplerate(int samplerate) | ||||
| { | ||||
|     m_samplerate = samplerate; | ||||
| } | ||||
|  |  | |||
|  | @ -38,10 +38,12 @@ class BarsVisualizationWidget final : public GUI::Frame | |||
| public: | ||||
|     ~BarsVisualizationWidget() override; | ||||
|     void set_buffer(RefPtr<Audio::Buffer> buffer) override; | ||||
|     void set_samplerate(int samplerate) override; | ||||
| 
 | ||||
| private: | ||||
|     void set_buffer(RefPtr<Audio::Buffer> buffer, int samples_to_use); | ||||
|     BarsVisualizationWidget(); | ||||
|     void set_buffer(RefPtr<Audio::Buffer> buffer, int samples_to_use); | ||||
| 
 | ||||
|     void paint_event(GUI::PaintEvent&) override; | ||||
|     void mousedown_event(GUI::MouseEvent& event) override; | ||||
| 
 | ||||
|  | @ -49,6 +51,7 @@ private: | |||
|     Vector<int> m_gfx_falling_bars; | ||||
|     int m_last_id; | ||||
|     int m_sample_count; | ||||
|     int m_samplerate; | ||||
|     bool m_is_using_last; | ||||
|     bool m_adjust_frequencies; | ||||
|     RefPtr<GUI::Menu> m_context_menu; | ||||
|  |  | |||
|  | @ -2,7 +2,6 @@ set(SOURCES | |||
|     main.cpp | ||||
|     PlaybackManager.cpp | ||||
|     SampleWidget.cpp | ||||
|     SoundPlayerWidget.cpp | ||||
|     SoundPlayerWidgetAdvancedView.cpp | ||||
|     BarsVisualizationWidget.cpp | ||||
|     AudioAlgorithms.cpp | ||||
|  |  | |||
|  | @ -28,10 +28,10 @@ | |||
| 
 | ||||
| #include <LibGUI/Slider.h> | ||||
| 
 | ||||
| class Slider final : public GUI::Slider { | ||||
|     C_OBJECT(Slider) | ||||
| class AutoSlider final : public GUI::Slider { | ||||
|     C_OBJECT(AutoSlider) | ||||
| public: | ||||
|     ~Slider() override = default; | ||||
|     ~AutoSlider() override = default; | ||||
|     Function<void(int)> on_knob_released; | ||||
|     void set_value(int value) | ||||
|     { | ||||
|  | @ -40,7 +40,7 @@ public: | |||
|     } | ||||
| 
 | ||||
| protected: | ||||
|     Slider(Orientation orientation) | ||||
|     AutoSlider(Orientation orientation) | ||||
|         : GUI::Slider(orientation) | ||||
|     { | ||||
|     } | ||||
|  |  | |||
|  | @ -172,13 +172,10 @@ void PlaybackManager::next_buffer() | |||
|     remove_dead_buffers(); | ||||
|     if (!m_next_buffer) { | ||||
|         if (!m_connection->get_remaining_samples() && !m_paused) { | ||||
|             dbgln("Exhausted samples :^)"); | ||||
|             if (m_loop) | ||||
|                 seek(0); | ||||
|             else | ||||
|                 stop(); | ||||
|             stop(); | ||||
|             if (on_finished_playing) | ||||
|                 on_finished_playing(); | ||||
|         } | ||||
| 
 | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -57,6 +57,7 @@ public: | |||
| 
 | ||||
|     Function<void()> on_update; | ||||
|     Function<void(Audio::Buffer&)> on_load_sample_buffer; | ||||
|     Function<void()> on_finished_playing; | ||||
| 
 | ||||
| private: | ||||
|     void next_buffer(); | ||||
|  |  | |||
|  | @ -1,206 +0,0 @@ | |||
| /*
 | ||||
|  * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> | ||||
|  * All rights reserved. | ||||
|  * | ||||
|  * Redistribution and use in source and binary forms, with or without | ||||
|  * modification, are permitted provided that the following conditions are met: | ||||
|  * | ||||
|  * 1. Redistributions of source code must retain the above copyright notice, this | ||||
|  *    list of conditions and the following disclaimer. | ||||
|  * | ||||
|  * 2. Redistributions in binary form must reproduce the above copyright notice, | ||||
|  *    this list of conditions and the following disclaimer in the documentation | ||||
|  *    and/or other materials provided with the distribution. | ||||
|  * | ||||
|  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||||
|  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||||
|  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||||
|  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE | ||||
|  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||||
|  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | ||||
|  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||||
|  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | ||||
|  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||||
|  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
|  */ | ||||
| 
 | ||||
| #include "SoundPlayerWidget.h" | ||||
| #include "Common.h" | ||||
| #include <AK/StringBuilder.h> | ||||
| #include <LibCore/MimeData.h> | ||||
| #include <LibGUI/BoxLayout.h> | ||||
| #include <LibGUI/Button.h> | ||||
| #include <LibGUI/Label.h> | ||||
| #include <LibGUI/MessageBox.h> | ||||
| 
 | ||||
| SoundPlayerWidget::SoundPlayerWidget(GUI::Window& window, PlayerState& state) | ||||
|     : Player(state) | ||||
|     , m_window(window) | ||||
| { | ||||
|     window.set_resizable(false); | ||||
|     window.resize(350, 140); | ||||
| 
 | ||||
|     set_fill_with_background_color(true); | ||||
|     set_layout<GUI::VerticalBoxLayout>(); | ||||
|     layout()->set_margins({ 2, 2, 2, 2 }); | ||||
| 
 | ||||
|     auto& status_widget = add<GUI::Widget>(); | ||||
|     status_widget.set_fill_with_background_color(true); | ||||
|     status_widget.set_layout<GUI::HorizontalBoxLayout>(); | ||||
| 
 | ||||
|     m_elapsed = status_widget.add<GUI::Label>(); | ||||
|     m_elapsed->set_frame_shape(Gfx::FrameShape::Container); | ||||
|     m_elapsed->set_frame_shadow(Gfx::FrameShadow::Sunken); | ||||
|     m_elapsed->set_frame_thickness(2); | ||||
|     m_elapsed->set_fixed_width(80); | ||||
| 
 | ||||
|     auto& sample_widget_container = status_widget.add<GUI::Widget>(); | ||||
|     sample_widget_container.set_layout<GUI::HorizontalBoxLayout>(); | ||||
| 
 | ||||
|     m_sample_widget = sample_widget_container.add<SampleWidget>(); | ||||
| 
 | ||||
|     m_remaining = status_widget.add<GUI::Label>(); | ||||
|     m_remaining->set_frame_shape(Gfx::FrameShape::Container); | ||||
|     m_remaining->set_frame_shadow(Gfx::FrameShadow::Sunken); | ||||
|     m_remaining->set_frame_thickness(2); | ||||
|     m_remaining->set_fixed_width(80); | ||||
| 
 | ||||
|     m_slider = add<Slider>(Orientation::Horizontal); | ||||
|     m_slider->set_min(0); | ||||
|     m_slider->set_enabled(has_loaded_file()); | ||||
|     m_slider->on_knob_released = [&](int value) { manager().seek(denormalize_rate(value)); }; | ||||
| 
 | ||||
|     auto& control_widget = add<GUI::Widget>(); | ||||
|     control_widget.set_fill_with_background_color(true); | ||||
|     control_widget.set_layout<GUI::HorizontalBoxLayout>(); | ||||
|     control_widget.set_fixed_height(30); | ||||
|     control_widget.layout()->set_margins({ 10, 2, 10, 2 }); | ||||
|     control_widget.layout()->set_spacing(10); | ||||
| 
 | ||||
|     m_play = control_widget.add<GUI::Button>(); | ||||
|     m_play->set_icon(has_loaded_file() ? *m_play_icon : *m_pause_icon); | ||||
|     m_play->set_enabled(has_loaded_file()); | ||||
|     m_play->on_click = [this](auto) { | ||||
|         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->set_enabled(has_loaded_file()); | ||||
|     m_stop->set_icon(Gfx::Bitmap::load_from_file("/res/icons/16x16/stop.png")); | ||||
|     m_stop->on_click = [this](auto) { | ||||
|         manager().stop(); | ||||
|         set_stopped(true); | ||||
|     }; | ||||
| 
 | ||||
|     m_status = add<GUI::Label>(); | ||||
|     m_status->set_frame_shape(Gfx::FrameShape::Box); | ||||
|     m_status->set_frame_shadow(Gfx::FrameShadow::Raised); | ||||
|     m_status->set_frame_thickness(4); | ||||
|     m_status->set_text_alignment(Gfx::TextAlignment::CenterLeft); | ||||
|     m_status->set_fixed_height(18); | ||||
|     m_status->set_text(has_loaded_file() ? loaded_filename() : "No file open!"); | ||||
| 
 | ||||
|     update_position(0); | ||||
| 
 | ||||
|     manager().on_update = [&]() { update_ui(); }; | ||||
| } | ||||
| 
 | ||||
| SoundPlayerWidget::~SoundPlayerWidget() | ||||
| { | ||||
| } | ||||
| 
 | ||||
| void SoundPlayerWidget::open_file(StringView path) | ||||
| { | ||||
|     NonnullRefPtr<Audio::Loader> loader = Audio::Loader::create(path); | ||||
|     if (loader->has_error() || !loader->sample_rate()) { | ||||
|         const String error_string = loader->error_string(); | ||||
|         GUI::MessageBox::show(window(), | ||||
|             String::formatted("Failed to load audio file: {} ({})", path, error_string.is_null() ? "Unknown error" : error_string), | ||||
|             "Filetype error", GUI::MessageBox::Type::Error); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     m_sample_ratio = PLAYBACK_MANAGER_RATE / static_cast<float>(loader->sample_rate()); | ||||
| 
 | ||||
|     m_slider->set_max(normalize_rate(static_cast<int>(loader->total_samples()))); | ||||
|     m_slider->set_enabled(true); | ||||
|     m_play->set_enabled(true); | ||||
|     m_stop->set_enabled(true); | ||||
| 
 | ||||
|     m_window.set_title(String::formatted("{} - SoundPlayer", loader->file()->filename())); | ||||
|     m_status->set_text(String::formatted( | ||||
|         "Sample rate {}Hz, {} channel(s), {} bits per sample", | ||||
|         loader->sample_rate(), | ||||
|         loader->num_channels(), | ||||
|         loader->bits_per_sample())); | ||||
| 
 | ||||
|     manager().set_loader(move(loader)); | ||||
|     update_position(0); | ||||
|     set_has_loaded_file(true); | ||||
|     set_loaded_filename(path); | ||||
| } | ||||
| 
 | ||||
| void SoundPlayerWidget::drop_event(GUI::DropEvent& event) | ||||
| { | ||||
|     event.accept(); | ||||
|     window()->move_to_front(); | ||||
| 
 | ||||
|     if (event.mime_data().has_urls()) { | ||||
|         auto urls = event.mime_data().urls(); | ||||
|         if (urls.is_empty()) | ||||
|             return; | ||||
|         open_file(urls.first().path()); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| int SoundPlayerWidget::normalize_rate(int rate) const | ||||
| { | ||||
|     return static_cast<int>(rate * m_sample_ratio); | ||||
| } | ||||
| 
 | ||||
| int SoundPlayerWidget::denormalize_rate(int rate) const | ||||
| { | ||||
|     return static_cast<int>(rate / m_sample_ratio); | ||||
| } | ||||
| 
 | ||||
| void SoundPlayerWidget::update_ui() | ||||
| { | ||||
|     m_sample_widget->set_buffer(manager().current_buffer()); | ||||
|     m_play->set_icon(manager().is_paused() ? *m_play_icon : *m_pause_icon); | ||||
|     update_position(manager().connection()->get_played_samples()); | ||||
| } | ||||
| 
 | ||||
| void SoundPlayerWidget::update_position(const int position) | ||||
| { | ||||
|     int total_norm_samples = position + normalize_rate(manager().last_seek()); | ||||
|     float seconds = (total_norm_samples / static_cast<float>(PLAYBACK_MANAGER_RATE)); | ||||
|     float remaining_seconds = manager().total_length() - seconds; | ||||
| 
 | ||||
|     m_elapsed->set_text(String::formatted( | ||||
|         "Elapsed:\n{}:{:02}.{:02}", | ||||
|         static_cast<int>(seconds / 60), | ||||
|         static_cast<int>(seconds) % 60, | ||||
|         static_cast<int>(seconds * 100) % 100)); | ||||
| 
 | ||||
|     m_remaining->set_text(String::formatted( | ||||
|         "Remaining:\n{}:{:02}.{:02}", | ||||
|         static_cast<int>(remaining_seconds / 60), | ||||
|         static_cast<int>(remaining_seconds) % 60, | ||||
|         static_cast<int>(remaining_seconds * 100) % 100)); | ||||
| 
 | ||||
|     m_slider->set_value(total_norm_samples); | ||||
| } | ||||
| 
 | ||||
| void SoundPlayerWidget::hide_scope(bool hide) | ||||
| { | ||||
|     m_sample_widget->set_visible(!hide); | ||||
| } | ||||
| 
 | ||||
| void SoundPlayerWidget::play() | ||||
| { | ||||
|     manager().play(); | ||||
|     set_paused(false); | ||||
|     set_stopped(false); | ||||
| } | ||||
|  | @ -1,70 +0,0 @@ | |||
| /*
 | ||||
|  * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> | ||||
|  * All rights reserved. | ||||
|  * | ||||
|  * Redistribution and use in source and binary forms, with or without | ||||
|  * modification, are permitted provided that the following conditions are met: | ||||
|  * | ||||
|  * 1. Redistributions of source code must retain the above copyright notice, this | ||||
|  *    list of conditions and the following disclaimer. | ||||
|  * | ||||
|  * 2. Redistributions in binary form must reproduce the above copyright notice, | ||||
|  *    this list of conditions and the following disclaimer in the documentation | ||||
|  *    and/or other materials provided with the distribution. | ||||
|  * | ||||
|  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||||
|  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||||
|  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||||
|  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE | ||||
|  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||||
|  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | ||||
|  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||||
|  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | ||||
|  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||||
|  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
|  */ | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include "Common.h" | ||||
| #include "PlaybackManager.h" | ||||
| #include "Player.h" | ||||
| #include "SampleWidget.h" | ||||
| #include <AK/NonnullRefPtr.h> | ||||
| #include <LibGUI/Button.h> | ||||
| #include <LibGUI/Label.h> | ||||
| #include <LibGUI/Widget.h> | ||||
| #include <LibGUI/Window.h> | ||||
| 
 | ||||
| class SoundPlayerWidget final : public GUI::Widget | ||||
|     , public Player { | ||||
|     C_OBJECT(SoundPlayerWidget) | ||||
| public: | ||||
|     ~SoundPlayerWidget() override; | ||||
|     void open_file(StringView path) override; | ||||
|     void play() override; | ||||
|     void hide_scope(bool); | ||||
| 
 | ||||
| private: | ||||
|     explicit SoundPlayerWidget(GUI::Window& window, PlayerState& state); | ||||
| 
 | ||||
|     void drop_event(GUI::DropEvent&) override; | ||||
| 
 | ||||
|     void update_position(const int position); | ||||
|     void update_ui(); | ||||
|     int normalize_rate(int) const; | ||||
|     int denormalize_rate(int) const; | ||||
| 
 | ||||
|     GUI::Window& m_window; | ||||
| 
 | ||||
|     float m_sample_ratio { 1.0 }; | ||||
|     RefPtr<GUI::Label> m_status; | ||||
|     RefPtr<GUI::Label> m_elapsed; | ||||
|     RefPtr<GUI::Label> m_remaining; | ||||
|     RefPtr<Slider> m_slider; | ||||
|     RefPtr<SampleWidget> m_sample_widget; | ||||
|     RefPtr<Gfx::Bitmap> m_play_icon { Gfx::Bitmap::load_from_file("/res/icons/16x16/play.png") }; | ||||
|     RefPtr<Gfx::Bitmap> m_pause_icon { Gfx::Bitmap::load_from_file("/res/icons/16x16/pause.png") }; | ||||
|     RefPtr<GUI::Button> m_play; | ||||
|     RefPtr<GUI::Button> m_stop; | ||||
| }; | ||||
|  | @ -37,6 +37,7 @@ | |||
| #include <LibGUI/Label.h> | ||||
| #include <LibGUI/MessageBox.h> | ||||
| #include <LibGUI/Slider.h> | ||||
| #include <LibGUI/Splitter.h> | ||||
| #include <LibGUI/ToolBar.h> | ||||
| #include <LibGUI/ToolBarContainer.h> | ||||
| #include <LibGUI/Window.h> | ||||
|  | @ -212,10 +213,14 @@ void SoundPlayerWidgetAdvancedView::open_file(StringView path) | |||
|     m_playback_progress_slider->set_max(loader->total_samples()); | ||||
|     m_playback_progress_slider->set_enabled(true); | ||||
|     m_play_button->set_enabled(true); | ||||
|     m_play_button->set_icon(*m_pause_icon); | ||||
|     m_stop_button->set_enabled(true); | ||||
|     m_playback_progress_slider->set_max(loader->total_samples()); | ||||
|     manager().set_loader(move(loader)); | ||||
|     set_has_loaded_file(true); | ||||
|     set_loaded_file_samplerate(loader->sample_rate()); | ||||
|     set_loaded_filename(path); | ||||
|     play(); | ||||
| } | ||||
| 
 | ||||
| void SoundPlayerWidgetAdvancedView::set_nonlinear_volume_slider(bool nonlinear) | ||||
|  |  | |||
|  | @ -27,11 +27,12 @@ | |||
| #pragma once | ||||
| 
 | ||||
| #include "BarsVisualizationWidget.h" | ||||
| #include "Common.h" | ||||
| #include "PlaybackManager.h" | ||||
| #include "Player.h" | ||||
| #include "SoundPlayerWidget.h" | ||||
| #include <AK/NonnullRefPtr.h> | ||||
| #include <LibAudio/ClientConnection.h> | ||||
| #include <LibGUI/Splitter.h> | ||||
| #include <LibGUI/Widget.h> | ||||
| 
 | ||||
| class SoundPlayerWidgetAdvancedView final : public GUI::Widget | ||||
|  | @ -45,6 +46,9 @@ public: | |||
|     void open_file(StringView path) override; | ||||
|     void read_playlist(StringView path); | ||||
|     void play() override; | ||||
|     void set_nonlinear_volume_slider(bool nonlinear); | ||||
|     void set_playlist_visible(bool visible); | ||||
|     void try_fill_missing_info(Vector<M3UEntry>& entries, StringView playlist_p); | ||||
| 
 | ||||
|     template<typename T> | ||||
|     void set_visualization() | ||||
|  | @ -52,12 +56,10 @@ public: | |||
|         m_visualization->remove_from_parent(); | ||||
|         update(); | ||||
|         auto new_visualization = T::construct(); | ||||
|         insert_child_before(new_visualization, *static_cast<Core::Object*>(m_playback_progress_slider.ptr())); | ||||
|         m_player_view->insert_child_before(new_visualization, *static_cast<Core::Object*>(m_playback_progress_slider.ptr())); | ||||
|         m_visualization = new_visualization; | ||||
|     } | ||||
| 
 | ||||
|     void set_nonlinear_volume_slider(bool nonlinear); | ||||
| 
 | ||||
| private: | ||||
|     void drop_event(GUI::DropEvent& event) override; | ||||
|     GUI::Window& m_window; | ||||
|  | @ -77,7 +79,7 @@ private: | |||
|     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<AutoSlider> m_playback_progress_slider; | ||||
|     RefPtr<GUI::Label> m_volume_label; | ||||
| 
 | ||||
|     bool m_nonlinear_volume_slider; | ||||
|  |  | |||
|  | @ -31,4 +31,5 @@ | |||
| class Visualization { | ||||
| public: | ||||
|     virtual void set_buffer(RefPtr<Audio::Buffer> buffer) = 0; | ||||
|     virtual void set_samplerate(int) { } | ||||
| }; | ||||
|  |  | |||
|  | @ -26,7 +26,7 @@ | |||
| 
 | ||||
| #include "NoVisualizationWidget.h" | ||||
| #include "Player.h" | ||||
| #include "SoundPlayerWidget.h" | ||||
| #include "SampleWidget.h" | ||||
| #include "SoundPlayerWidgetAdvancedView.h" | ||||
| #include <LibAudio/ClientConnection.h> | ||||
| #include <LibGUI/Action.h> | ||||
|  | @ -54,21 +54,24 @@ int main(int argc, char** argv) | |||
| 
 | ||||
|     auto audio_client = Audio::ClientConnection::construct(); | ||||
|     audio_client->handshake(); | ||||
|     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) { | ||||
|         perror("pledge"); | ||||
|         return 1; | ||||
|     } | ||||
| 
 | ||||
|     PlaybackManager playback_manager(audio_client); | ||||
|     PlayerState initial_player_state { true, | ||||
|         true, | ||||
|         false, | ||||
|         false, | ||||
|         false, | ||||
|         44100, | ||||
|         1.0, | ||||
|         audio_client, | ||||
|         playback_manager, | ||||
|         "" }; | ||||
| 
 | ||||
|     auto app_icon = GUI::Icon::default_icon("app-sound-player"); | ||||
| 
 | ||||
|     auto window = GUI::Window::construct(); | ||||
|  | @ -78,12 +81,14 @@ int main(int argc, char** argv) | |||
|     auto menubar = GUI::MenuBar::construct(); | ||||
| 
 | ||||
|     auto& app_menu = menubar->add_menu("File"); | ||||
|     // start in simple view by default
 | ||||
|     Player* player = &window->set_main_widget<SoundPlayerWidget>(window, initial_player_state); | ||||
| 
 | ||||
|     auto& playlist_menu = menubar->add_menu("Playlist"); | ||||
| 
 | ||||
|     String path = argv[1]; | ||||
|     // start in advanced view by default
 | ||||
|     Player* player = &window->set_main_widget<SoundPlayerWidgetAdvancedView>(window, initial_player_state); | ||||
|     if (argc > 1) { | ||||
|         String path = argv[1]; | ||||
|         player->open_file(path); | ||||
|         player->play(); | ||||
|     } | ||||
| 
 | ||||
|     app_menu.add_action(GUI::CommonActions::make_open_action([&](auto&) { | ||||
|  | @ -119,7 +124,7 @@ int main(int argc, char** argv) | |||
|     auto& playback_menu = menubar->add_menu("Playback"); | ||||
| 
 | ||||
|     auto loop = GUI::Action::create_checkable("Loop", { Mod_Ctrl, Key_R }, [&](auto& action) { | ||||
|         player->set_looping(action.is_checked()); | ||||
|         player->set_looping_file(action.is_checked()); | ||||
|     }); | ||||
| 
 | ||||
|     playback_menu.add_action(move(loop)); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Cesar Torres
						Cesar Torres