Loading...
Searching...
No Matches
SoundLibraryHandler.hpp
1#pragma once
2#include <Process/ExecutionContext.hpp>
3
4#include <Audio/AudioApplicationPlugin.hpp>
5#include <Audio/AudioPreviewExecutor.hpp>
6#include <Audio/Settings/Model.hpp>
7#include <Engine/ApplicationPlugin.hpp>
8#include <Library/LibraryInterface.hpp>
9#include <Media/MediaFileHandle.hpp>
10
11#include <score/tools/ThreadPool.hpp>
12#include <score/widgets/MarginLess.hpp>
13#include <score/widgets/Pixmap.hpp>
14
15#include <ossia/audio/audio_protocol.hpp>
16
17#include <ossia-qt/invoke.hpp>
18
19#include <QFileInfo>
20#include <QHBoxLayout>
21#include <QLabel>
22#include <QPushButton>
23
24namespace Media::Sound
25{
26
28 : public QWidget
29 , public Nano::Observer
30{
31 // W_OBJECT(AudioPreviewWidget)
32 AudioFile m_reader;
33
34public:
35 AudioPreviewWidget(const QString& path, QWidget* parent = nullptr)
36 : QWidget{parent}
37 {
38 // FIXME libav does not support rex2 format
39 if(path.endsWith("rx2"))
40 return;
41
42 auto lay = new score::MarginLess<QHBoxLayout>{this};
43 lay->setSpacing(8);
44 lay->addWidget(&m_playstop);
45 lay->addWidget(&m_name);
46 m_name.setText(QFileInfo{path}.fileName());
47 m_reader.on_finishedDecoding.connect<&AudioPreviewWidget::on_finishedDecoding>(
48 *this);
49 m_reader.load({path, path, DecodingMethod::Libav});
50
51 m_playPixmap = score::get_pixmap(":/icons/play_off.png");
52 m_stopPixmap = score::get_pixmap(":/icons/stop_off.png");
53
54 m_playstop.setIcon(m_playPixmap);
55
56 m_playstop.setMinimumWidth(24);
57 m_playstop.setMaximumWidth(24);
58
59 connect(&m_playstop, &QPushButton::clicked, this, [&]() {
60 if(!m_autoPlay)
61 {
62 setAutoPlay(true);
63 startPlayback();
64 }
65 else
66 {
67 stopPlayback();
68 setAutoPlay(false);
69 }
70 });
71 }
72
73 void on_finishedDecoding()
74 {
75 if(m_autoPlay)
76 {
77 m_playstop.setChecked(false);
78 startPlayback();
79 }
80 }
81
82 bool autoPlay() const noexcept { return m_autoPlay; }
83 void setAutoPlay(bool b)
84 {
85 if(b != m_autoPlay)
86 {
87 m_autoPlay = b;
88 }
89 }
90
91 void startPlayback()
92 {
93 auto& audio = score::GUIAppContext().settings<Audio::Settings::Model>();
94 int rate = audio.getRate();
95
96 auto& inst = Audio::AudioPreviewExecutor::instance();
97 auto reader = m_reader.unsafe_handle().target<AudioFile::libav_ptr>();
98 SCORE_ASSERT(reader);
99 SCORE_ASSERT((*reader)->handle);
100 inst.queue.enqueue({(*reader)->handle, (int)m_reader.channels(), (int)rate});
101
102 m_playstop.setIcon(m_stopPixmap);
103 }
104
105 void stopPlayback()
106 {
107 auto& inst = Audio::AudioPreviewExecutor::instance();
108 inst.queue.enqueue({});
109
110 m_playstop.setIcon(m_playPixmap);
111 }
112
113private:
114 QPushButton m_playstop{this};
115 QLabel m_name{this};
116 QPixmap m_playPixmap;
117 QPixmap m_stopPixmap;
118
119 static inline bool m_autoPlay{false};
120};
121
123{
124 SCORE_CONCRETE("7d735f7f-d474-404d-8984-ba627e12f08c")
125
126 QSet<QString> acceptedFiles() const noexcept override
127 {
128 return {"wav", "mp3", "m4a", "ogg", "flac", "aif",
129 "aiff", "w64", "ape", "wv", "wma"};
130 }
131
132 QWidget* previewWidget(const QString& path, QWidget* parent) const noexcept override
133 {
134 return new AudioPreviewWidget{path, parent};
135 }
136};
137
138}
Definition score-plugin-audio/Audio/Settings/Model.hpp:22
Definition LibraryInterface.hpp:22
Definition SoundLibraryHandler.hpp:30
Definition SoundLibraryHandler.hpp:123
The MarginLess class.
Definition MarginLess.hpp:14
Definition MediaFileHandle.hpp:74
T & settings() const
Access a specific Settings model instance.
Definition ApplicationContext.hpp:40