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 
24 namespace Media::Sound
25 {
26 
28  : public QWidget
29  , public Nano::Observer
30 {
31  // W_OBJECT(AudioPreviewWidget)
32  AudioFile m_reader;
33 
34 public:
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 
113 private:
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
Definition: MediaFileHandle.hpp:74
T & settings() const
Access a specific Settings model instance.
Definition: ApplicationContext.hpp:40