1 /*************************************************************************** 2 PlaybackController.h - Interface for generic playback control 3 ------------------- 4 begin : Nov 15 2000 5 copyright : (C) 2000 by Thomas Eschenbacher 6 email : Thomas Eschenbacher <Thomas.Eschenbacher@gmx.de> 7 ***************************************************************************/ 8 9 /*************************************************************************** 10 * * 11 * This program is free software; you can redistribute it and/or modify * 12 * it under the terms of the GNU General Public License as published by * 13 * the Free Software Foundation; either version 2 of the License, or * 14 * (at your option) any later version. * 15 * * 16 ***************************************************************************/ 17 18 #ifndef PLAYBACK_CONTROLLER_H 19 #define PLAYBACK_CONTROLLER_H 20 21 #include "config.h" 22 23 #include <QtGlobal> 24 #include <QList> 25 #include <QMutex> 26 #include <QObject> 27 28 #include "libkwave/PlayBackParam.h" 29 #include "libkwave/Runnable.h" 30 #include "libkwave/Sample.h" 31 #include "libkwave/WorkerThread.h" 32 33 namespace Kwave 34 { 35 36 class PlayBackDevice; 37 class PlaybackDeviceFactory; 38 class SignalManager; 39 40 /** 41 * Provides a generic interface for classes that can contol playback 42 * with start, stop, pause and continue. This class is intended to be used 43 * or derived in a class that is able to control a playback device by 44 * simply startig or stopping playback and can be easily used by some 45 * other part of the program that has nothing to do directly with 46 * playback. The playback control functions all start with "playback" 47 * and are slots that are intended to be connected to some simple 48 * gui elements like toolbar buttons or menu entries. 49 * 50 * This class internally manages the logic and handling of the 51 * playback position. 52 */ 53 class Q_DECL_EXPORT PlaybackController: public QObject, 54 public Kwave::Runnable 55 { 56 Q_OBJECT 57 58 public: 59 60 /** Default constructor */ 61 explicit PlaybackController(Kwave::SignalManager &signal_manager); 62 63 /** Destructor */ 64 virtual ~PlaybackController() Q_DECL_OVERRIDE; 65 66 public: 67 68 /** resets start, current position, loop, pause and running flag */ 69 void reset(); 70 71 /** returns the loop mode flag */ 72 bool loop() const; 73 74 /** returns true if the playback is running */ 75 bool running() const; 76 77 /** returns true if the playback is paused */ 78 bool paused() const; 79 80 /** sets a new start position */ 81 void setStartPos(sample_index_t pos); 82 83 /** sets a new end position */ 84 void setEndPos(sample_index_t pos); 85 86 /** returns the position where the playback starts */ 87 sample_index_t startPos() const; 88 89 /** returns the position where the playback ends */ 90 sample_index_t endPos() const; 91 92 /** returns the current position of the playback pointer */ 93 sample_index_t currentPos() const; 94 95 /** 96 * Registers a PlaybackDeviceFactory 97 */ 98 void registerPlaybackDeviceFactory( 99 Kwave::PlaybackDeviceFactory *factory); 100 101 /** 102 * Unregisters a PlaybackDeviceFactory 103 */ 104 void unregisterPlaybackDeviceFactory( 105 Kwave::PlaybackDeviceFactory *factory); 106 107 /** 108 * Create a playback device matching the given playback method. 109 * 110 * @param method a playback_method_t (e.g. Pulse, ALSA, OSS...) 111 * @return a new PlayBackDevice or 0 if failed 112 */ 113 virtual Kwave::PlayBackDevice *createDevice( 114 Kwave::playback_method_t method); 115 116 /** 117 * Creates, opens and initializes a playback device. 118 * 119 * @param tracks number of tracks, 120 * if negative use the setting of playback_params 121 * @param playback_params points to a structure with playback 122 * parameters. If null, the default parameters 123 * of the current signal will be used 124 * @return a pointer to an opened PlayBackDevice or null if failed 125 * @see PlayBackDevice 126 */ 127 Kwave::PlayBackDevice *openDevice(int tracks, 128 const Kwave::PlayBackParam *playback_params); 129 130 /** 131 * Sets default playback parameters, for use next time playback 132 * is started 133 * @param params new playback parameters 134 */ 135 void setDefaultParams(const Kwave::PlayBackParam ¶ms); 136 137 /** 138 * Checks whether a playback method is supported and returns the 139 * next best match if not. 140 * @param method reference to a playback method, can be modified 141 */ 142 void checkMethod(Kwave::playback_method_t &method); 143 144 public slots: 145 146 /** 147 * (Re-)starts the playback. If playback has successfully been 148 * started, the signal sigPlaybackStarted() will be emitted. 149 */ 150 void playbackStart(); 151 152 /** 153 * (Re-)starts the playback in loop mode (like with playbackStart(). 154 * Also emitts sigPlaybackStarted() if playback has successfully 155 * been started. 156 */ 157 void playbackLoop(); 158 159 /** 160 * Pauses the playback. Causes sigPlaybackDone() to be emitted if 161 * the current buffer has played out. The current playback pointer 162 * will stay at it's current position. 163 */ 164 void playbackPause(); 165 166 /** 167 * Continues the playback at the position where it has been stopped 168 * by the playbackPause() command. If the last playback pointer 169 * has become invalid or is not available (less 0), this function 170 * will do the same as playbackStart(). This also emits the 171 * signal sigPlaybackStarted(). 172 */ 173 void playbackContinue(); 174 175 /** 176 * Stopps playback / loop. Like playbackPause(), but resets the 177 * playback pointer back to the start. 178 */ 179 void playbackStop(); 180 181 /** 182 * If playback is currently running, it will be paused and 183 * then restarted with current track and time selection. 184 */ 185 void reload(); 186 187 /** Seeks to a new position */ 188 void seekTo(sample_index_t pos); 189 190 /** Called when the seek has finished */ 191 void seekDone(sample_index_t pos); 192 193 /** Updates the current playback position */ 194 void updatePlaybackPos(sample_index_t pos); 195 196 /** Updates the status if playback is done */ 197 void playbackDone(); 198 199 signals: 200 201 /** 202 * Signals that playback has started. 203 */ 204 void sigPlaybackStarted(); 205 206 /** 207 * Signals that playback has been paused. 208 */ 209 void sigPlaybackPaused(); 210 211 /** 212 * Signals that playback has stopped. 213 */ 214 void sigPlaybackStopped(); 215 216 /** 217 * Emits the current position of the playback pointer 218 */ 219 void sigPlaybackPos(sample_index_t pos); 220 221 /** 222 * Emits the current position after a seek operation 223 */ 224 void sigSeekDone(sample_index_t pos); 225 226 /** 227 * Signals that playback has stopped (sent from worker thread). 228 */ 229 void sigDevicePlaybackDone(); 230 231 /** Emits the current playback position (from worker thread) */ 232 void sigDevicePlaybackPos(sample_index_t pos); 233 234 /** Emitted after a successful seek operation (from worker thread)*/ 235 void sigDeviceSeekDone(sample_index_t pos); 236 237 private slots: 238 239 /** 240 * Closes the playback device, deletes the instance of the 241 * PlayBackDevice and sets m_device to 0. 242 * @see m_device 243 * @see PlayBackDevice 244 */ 245 void closeDevice(); 246 247 /** updates the mixer matrix if the track selection has changed */ 248 void trackSelectionChanged(); 249 250 protected: 251 252 /** wrapper for our run() function, called from worker thread */ 253 virtual void run_wrapper(const QVariant ¶ms) Q_DECL_OVERRIDE; 254 255 private: 256 257 /** Starts playback device (and worker thread) */ 258 void startDevicePlayBack(); 259 260 /** Stops the playback device (and worker thread) */ 261 void stopDevicePlayBack(); 262 263 private: 264 265 /** Reference to our signal manager */ 266 Kwave::SignalManager &m_signal_manager; 267 268 /** 269 * Thread that executes the run() member function. 270 */ 271 Kwave::WorkerThread m_thread; 272 273 /** The playback device used for playback */ 274 Kwave::PlayBackDevice *m_device; 275 276 /** Mutex for locking access to the playback device */ 277 QMutex m_lock_device; 278 279 /** the parameters used for playback */ 280 Kwave::PlayBackParam m_playback_params; 281 282 /** 283 * Mutex for locking access to members that control the playback 284 * loop, like m_should_seek, m_seek_pos and m_mixer 285 */ 286 QMutex m_lock_playback; 287 288 /** if true, m_seek_pos is valid and a seek has been requested */ 289 bool m_should_seek; 290 291 /** position to seek to */ 292 sample_index_t m_seek_pos; 293 294 /** notification flag, true if the track selection has changed */ 295 bool m_track_selection_changed; 296 297 /** 298 * If true, we are in "reload" mode. In this mode the playback is 299 * paused and continued without emitting a sigPlaybackDone. This 300 * is useful if playback parameters or signal selection has changed 301 * during playback. 302 */ 303 bool m_reload_mode; 304 305 /** if set to true, the playback will be done in loop mode */ 306 bool m_loop_mode; 307 308 /** if true, playback is only paused and can be continued */ 309 bool m_paused; 310 311 /** is set to true if the playback has been started */ 312 bool m_playing; 313 314 /** the current play position */ 315 sample_index_t m_playback_position; 316 317 /** the start position for playback */ 318 sample_index_t m_playback_start; 319 320 /** the end position for playback */ 321 sample_index_t m_playback_end; 322 323 /** Start of the selection when playback started */ 324 sample_index_t m_old_first; 325 326 /** End of the selection when playback started */ 327 sample_index_t m_old_last; 328 329 /** list of playback device factories */ 330 QList<Kwave::PlaybackDeviceFactory *> m_playback_factories; 331 332 }; 333 } 334 335 #endif /* PLAYBACK_CONTROLLER_H */ 336 337 //*************************************************************************** 338 //*************************************************************************** 339