1 /* 2 * Strawberry Music Player 3 * This file was part of Amarok / Clementine 4 * Copyright 2003 Mark Kretschmann 5 * Copyright 2004 - 2005 Max Howell, <max.howell@methylblue.com> 6 * Copyright 2010 David Sansome <me@davidsansome.com> 7 * Copyright 2017-2021 Jonas Kvinge <jonas@jkvinge.net> 8 * 9 * Strawberry is free software: you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation, either version 3 of the License, or 12 * (at your option) any later version. 13 * 14 * Strawberry is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with Strawberry. If not, see <http://www.gnu.org/licenses/>. 21 * 22 */ 23 24 #ifndef ENGINEBASE_H 25 #define ENGINEBASE_H 26 27 #include "config.h" 28 29 #include <sys/types.h> 30 #include <cstdint> 31 #include <vector> 32 33 #include <QtGlobal> 34 #include <QObject> 35 #include <QList> 36 #include <QMetaType> 37 #include <QVariant> 38 #include <QString> 39 #include <QUrl> 40 41 #include "engine_fwd.h" 42 #include "enginetype.h" 43 #include "devicefinders.h" 44 #include "core/song.h" 45 46 namespace Engine { 47 48 struct SimpleMetaBundle; 49 50 typedef std::vector<int16_t> Scope; 51 52 class Base : public QObject { 53 Q_OBJECT 54 55 protected: 56 Base(const EngineType type = EngineType::None, QObject *parent = nullptr); 57 58 public: 59 ~Base() override; 60 61 struct OutputDetails { 62 QString name; 63 QString description; 64 QString iconname; 65 }; 66 typedef QList<OutputDetails> OutputDetailsList; 67 68 virtual bool Init() = 0; 69 virtual State state() const = 0; 70 virtual void StartPreloading(const QUrl&, const QUrl&, const bool, const qint64, const qint64) {} 71 virtual bool Load(const QUrl &stream_url, const QUrl &original_url, const TrackChangeFlags change, const bool force_stop_at_end, const quint64 beginning_nanosec, const qint64 end_nanosec); 72 virtual bool Play(const quint64 offset_nanosec) = 0; 73 virtual void Stop(const bool stop_after = false) = 0; 74 virtual void Pause() = 0; 75 virtual void Unpause() = 0; 76 virtual void Seek(const quint64 offset_nanosec) = 0; 77 virtual void SetVolumeSW(const uint percent) = 0; 78 79 virtual qint64 position_nanosec() const = 0; 80 virtual qint64 length_nanosec() const = 0; 81 82 virtual const Scope &scope(const int chunk_length) { Q_UNUSED(chunk_length); return scope_; } 83 84 // Sets new values for the beginning and end markers of the currently playing song. 85 // This doesn't change the state of engine or the stream's current position. 86 virtual void RefreshMarkers(const quint64 beginning_nanosec, const qint64 end_nanosec) { 87 beginning_nanosec_ = beginning_nanosec; 88 end_nanosec_ = end_nanosec; 89 } 90 91 virtual OutputDetailsList GetOutputsList() const = 0; 92 virtual bool ValidOutput(const QString &output) = 0; 93 virtual QString DefaultOutput() = 0; 94 virtual bool CustomDeviceSupport(const QString &output) = 0; 95 virtual bool ALSADeviceSupport(const QString &output) = 0; 96 97 // Plays a media stream represented with the URL 'u' from the given 'beginning' to the given 'end' (usually from 0 to a song's length). 98 // Both markers should be passed in nanoseconds. 'end' can be negative, indicating that the real length of 'u' stream is unknown. 99 bool Play(const QUrl &stream_url, const QUrl &original_url, const TrackChangeFlags flags, const bool force_stop_at_end, const quint64 beginning_nanosec, const qint64 end_nanosec, const quint64 offset_nanosec); 100 void SetVolume(const uint value); 101 static uint MakeVolumeLogarithmic(const uint volume); 102 103 public slots: 104 virtual void ReloadSettings(); 105 106 protected: 107 void EmitAboutToEnd(); 108 109 public: 110 111 // Simple accessors 112 EngineType type() const { return type_; } 113 bool volume_control() const { return volume_control_; } 114 inline uint volume() const { return volume_; } 115 116 bool is_fadeout_enabled() const { return fadeout_enabled_; } 117 bool is_crossfade_enabled() const { return crossfade_enabled_; } 118 bool is_autocrossfade_enabled() const { return autocrossfade_enabled_; } 119 bool crossfade_same_album() const { return crossfade_same_album_; } 120 bool IsEqualizerEnabled() { return equalizer_enabled_; } 121 122 static const int kScopeSize = 1024; 123 124 QVariant device() { return device_; } 125 126 public slots: 127 virtual void SetStereoBalancerEnabled(const bool) {} 128 virtual void SetStereoBalance(const float) {} 129 virtual void SetEqualizerEnabled(const bool) {} 130 virtual void SetEqualizerParameters(const int, const QList<int>&) {} 131 132 signals: 133 // Emitted when crossfading is enabled and the track is crossfade_duration_ away from finishing 134 void TrackAboutToEnd(); 135 136 void TrackEnded(); 137 138 void FadeoutFinishedSignal(); 139 140 void StatusText(QString text); 141 void Error(QString text); 142 143 // Emitted when there was a fatal error 144 void FatalError(); 145 // Emitted when Engine was unable to play a song with the given QUrl. 146 void InvalidSongRequested(QUrl url); 147 // Emitted when Engine successfully started playing a song with the given QUrl. 148 void ValidSongRequested(QUrl url); 149 150 void MetaData(Engine::SimpleMetaBundle); 151 152 // Signals that the engine's state has changed (a stream was stopped for example). 153 // Always use the state from event, because it's not guaranteed that immediate subsequent call to state() won't return a stale value. 154 void StateChanged(Engine::State); 155 156 protected: 157 158 struct PluginDetails { 159 QString name; 160 QString description; 161 QString iconname; 162 }; 163 typedef QList<PluginDetails> PluginDetailsList; 164 165 EngineType type_; 166 bool volume_control_; 167 uint volume_; 168 quint64 beginning_nanosec_; 169 qint64 end_nanosec_; 170 QUrl stream_url_; 171 QUrl original_url_; 172 Scope scope_; 173 bool buffering_; 174 bool equalizer_enabled_; 175 176 // Settings 177 QString output_; 178 QVariant device_; 179 180 // ReplayGain 181 bool rg_enabled_; 182 int rg_mode_; 183 double rg_preamp_; 184 double rg_fallbackgain_; 185 bool rg_compression_; 186 187 // Buffering 188 quint64 buffer_duration_nanosec_; 189 double buffer_low_watermark_; 190 double buffer_high_watermark_; 191 192 // Fadeout 193 bool fadeout_enabled_; 194 bool crossfade_enabled_; 195 bool autocrossfade_enabled_; 196 bool crossfade_same_album_; 197 bool fadeout_pause_enabled_; 198 qint64 fadeout_duration_; 199 qint64 fadeout_duration_nanosec_; 200 qint64 fadeout_pause_duration_; 201 qint64 fadeout_pause_duration_nanosec_; 202 203 // Proxy 204 QString proxy_address_; 205 bool proxy_authentication_; 206 QString proxy_user_; 207 QString proxy_pass_; 208 209 // Channels 210 bool channels_enabled_; 211 int channels_; 212 213 private: 214 bool about_to_end_emitted_; 215 Q_DISABLE_COPY(Base) 216 217 }; 218 219 struct SimpleMetaBundle { 220 SimpleMetaBundle() : type(Type_Any), length(-1), year(-1), track(-1), filetype(Song::FileType_Unknown), samplerate(-1), bitdepth(-1), bitrate(-1) {} 221 enum Type { 222 Type_Any, 223 Type_Current, 224 Type_Next, 225 }; 226 Type type; 227 QUrl url; 228 QUrl stream_url; 229 QString title; 230 QString artist; 231 QString album; 232 QString comment; 233 QString genre; 234 qint64 length; 235 int year; 236 int track; 237 Song::FileType filetype; 238 int samplerate; 239 int bitdepth; 240 qint64 bitrate; 241 QString lyrics; 242 }; 243 244 } // namespace Engine 245 246 Q_DECLARE_METATYPE(EngineBase::OutputDetails) 247 248 #endif // ENGINEBASE_H 249