kwave  18.07.70
Kwave::PlaybackController Class Reference

#include <PlaybackController.h>

Inheritance diagram for Kwave::PlaybackController:
Inheritance graph
Collaboration diagram for Kwave::PlaybackController:
Collaboration graph

Public Slots

void playbackStart ()
 
void playbackLoop ()
 
void playbackPause ()
 
void playbackContinue ()
 
void playbackStop ()
 
void reload ()
 
void seekTo (sample_index_t pos)
 
void seekDone (sample_index_t pos)
 
void updatePlaybackPos (sample_index_t pos)
 
void playbackDone ()
 

Signals

void sigPlaybackStarted ()
 
void sigPlaybackPaused ()
 
void sigPlaybackStopped ()
 
void sigPlaybackPos (sample_index_t pos)
 
void sigSeekDone (sample_index_t pos)
 
void sigDevicePlaybackDone ()
 
void sigDevicePlaybackPos (sample_index_t pos)
 
void sigDeviceSeekDone (sample_index_t pos)
 

Public Member Functions

 PlaybackController (Kwave::SignalManager &signal_manager)
 
virtual ~PlaybackController () Q_DECL_OVERRIDE
 
void reset ()
 
bool loop () const
 
bool running () const
 
bool paused () const
 
void setStartPos (sample_index_t pos)
 
void setEndPos (sample_index_t pos)
 
sample_index_t startPos () const
 
sample_index_t endPos () const
 
sample_index_t currentPos () const
 
void registerPlaybackDeviceFactory (Kwave::PlaybackDeviceFactory *factory)
 
void unregisterPlaybackDeviceFactory (Kwave::PlaybackDeviceFactory *factory)
 
virtual Kwave::PlayBackDevicecreateDevice (Kwave::playback_method_t method)
 
Kwave::PlayBackDeviceopenDevice (int tracks, const Kwave::PlayBackParam *playback_params)
 
void setDefaultParams (const Kwave::PlayBackParam &params)
 
void checkMethod (Kwave::playback_method_t &method)
 
- Public Member Functions inherited from Kwave::Runnable
virtual ~Runnable ()
 

Protected Member Functions

virtual void run_wrapper (const QVariant &params) Q_DECL_OVERRIDE
 

Private Slots

void closeDevice ()
 
void trackSelectionChanged ()
 

Private Member Functions

void startDevicePlayBack ()
 
void stopDevicePlayBack ()
 

Private Attributes

Kwave::SignalManagerm_signal_manager
 
Kwave::WorkerThread m_thread
 
Kwave::PlayBackDevicem_device
 
QMutex m_lock_device
 
Kwave::PlayBackParam m_playback_params
 
QMutex m_lock_playback
 
bool m_should_seek
 
sample_index_t m_seek_pos
 
bool m_track_selection_changed
 
bool m_reload_mode
 
bool m_loop_mode
 
bool m_paused
 
bool m_playing
 
sample_index_t m_playback_position
 
sample_index_t m_playback_start
 
sample_index_t m_playback_end
 
sample_index_t m_old_first
 
sample_index_t m_old_last
 
QList< Kwave::PlaybackDeviceFactory * > m_playback_factories
 

Detailed Description

Provides a generic interface for classes that can contol playback with start, stop, pause and continue. This class is intended to be used or derived in a class that is able to control a playback device by simply startig or stopping playback and can be easily used by some other part of the program that has nothing to do directly with playback. The playback control functions all start with "playback" and are slots that are intended to be connected to some simple gui elements like toolbar buttons or menu entries.

This class internally manages the logic and handling of the playback position.

Definition at line 53 of file PlaybackController.h.

Constructor & Destructor Documentation

◆ PlaybackController()

Kwave::PlaybackController::PlaybackController ( Kwave::SignalManager signal_manager)
explicit

Default constructor

Definition at line 42 of file PlaybackController.cpp.

References closeDevice(), Kwave::connect(), m_signal_manager, playbackDone(), sigDevicePlaybackDone(), and trackSelectionChanged().

45  :m_signal_manager(signal_manager), m_thread(this, QVariant()),
46  m_device(Q_NULLPTR), m_lock_device(), m_playback_params(),
49  m_reload_mode(false), m_loop_mode(false), m_paused(false),
53 {
54 
55  connect(this, SIGNAL(sigDevicePlaybackDone()),
56  this, SLOT(playbackDone()));
57  connect(this, SIGNAL(sigDevicePlaybackDone()),
58  this, SLOT(closeDevice()),
59  Qt::QueuedConnection);
60  connect(&m_signal_manager, SIGNAL(sigTrackSelectionChanged(bool)),
61  this, SLOT(trackSelectionChanged()));
62 
63 }
Kwave::SignalManager & m_signal_manager
QList< Kwave::PlaybackDeviceFactory * > m_playback_factories
bool connect(Kwave::StreamObject &source, const char *output, Kwave::StreamObject &sink, const char *input)
Definition: Connect.cpp:48
Kwave::PlayBackDevice * m_device
Kwave::PlayBackParam m_playback_params
Kwave::WorkerThread m_thread
Here is the call graph for this function:

◆ ~PlaybackController()

Kwave::PlaybackController::~PlaybackController ( )
virtual

Destructor

Definition at line 66 of file PlaybackController.cpp.

References playbackStop().

67 {
68  playbackStop();
69 }
Here is the call graph for this function:

Member Function Documentation

◆ checkMethod()

void Kwave::PlaybackController::checkMethod ( Kwave::playback_method_t method)

Checks whether a playback method is supported and returns the next best match if not.

Parameters
methodreference to a playback method, can be modified

Definition at line 556 of file PlaybackController.cpp.

References DBG, Kwave::TypesMap< IDX, DATA >::findFromData(), m_playback_factories, Kwave::TypesMap< IDX, DATA >::name(), Kwave::PLAYBACK_INVALID, Kwave::PLAYBACK_NONE, and Kwave::PlaybackDeviceFactory::supportedMethods().

Referenced by openDevice(), and Kwave::PlayBackDialog::setMethod().

557 {
558  QList<Kwave::playback_method_t> all_methods;
559 
560  // create a list of all supported playback methods
562  QList<Kwave::playback_method_t> methods = f->supportedMethods();
563 
564  // return immediately on a direct match
565  if (methods.contains(method)) return;
566 
567  // otherwise accumulate all found methods
568  foreach (Kwave::playback_method_t m, methods)
569  if (!all_methods.contains(m))
570  all_methods.append(m);
571  }
572 
573  // no direct match found: take the best match (lowest number)
575  foreach (Kwave::playback_method_t m, all_methods) {
576  if (m == Kwave::PLAYBACK_NONE) continue; // not a valid selection
577  if (m < best) best = m;
578  }
579 
581  qDebug("playback method '%s' (%d) not supported "
582  "-> falling back to '%s' (%d)",
583  DBG(map.name(map.findFromData(method))), static_cast<int>(method),
584  DBG(map.name(map.findFromData(best))), static_cast<int>(best)
585  );
586 
587  method = best;
588 }
QList< Kwave::PlaybackDeviceFactory * > m_playback_factories
playback_method_t
Definition: PlayBackParam.h:31
virtual QList< Kwave::playback_method_t > supportedMethods()=0
QString name(IDX type) const
Definition: TypesMap.h:117
#define DBG(qs)
Definition: String.h:55
IDX findFromData(const DATA &data) const
Definition: TypesMap.h:89
Here is the call graph for this function:
Here is the caller graph for this function:

◆ closeDevice

void Kwave::PlaybackController::closeDevice ( )
privateslot

Closes the playback device, deletes the instance of the PlayBackDevice and sets m_device to 0.

See also
m_device
PlayBackDevice

Definition at line 542 of file PlaybackController.cpp.

References m_device, and m_lock_device.

Referenced by PlaybackController(), and stopDevicePlayBack().

543 {
544  Kwave::PlayBackDevice *dev = Q_NULLPTR;
545  if (m_device) {
546  // NOTE: we could get a recursion here if we delete with the lock
547  // held, if the device calls processEvents during shutdown
548  QMutexLocker lock_for_delete(&m_lock_device);
549  dev = m_device;
550  m_device = Q_NULLPTR;
551  }
552  delete dev;
553 }
Kwave::PlayBackDevice * m_device
Here is the caller graph for this function:

◆ createDevice()

Kwave::PlayBackDevice * Kwave::PlaybackController::createDevice ( Kwave::playback_method_t  method)
virtual

Create a playback device matching the given playback method.

Parameters
methoda playback_method_t (e.g. Pulse, ALSA, OSS...)
Returns
a new PlayBackDevice or 0 if failed

Definition at line 591 of file PlaybackController.cpp.

References Kwave::PlaybackDeviceFactory::createDevice(), m_playback_factories, and Kwave::PlaybackDeviceFactory::supportedMethods().

Referenced by openDevice(), and Kwave::PlayBackDialog::setMethod().

593 {
594  // locate the corresponding playback device factory (plugin)
595  Kwave::PlaybackDeviceFactory *factory = Q_NULLPTR;
597  Q_ASSERT(f);
598  if (f && f->supportedMethods().contains(method)) {
599  factory = f;
600  break;
601  }
602  }
603  if (!factory) return Q_NULLPTR;
604 
605  // create a new device instance, using the given method
606  return factory->createDevice(method);
607 }
QList< Kwave::PlaybackDeviceFactory * > m_playback_factories
virtual QList< Kwave::playback_method_t > supportedMethods()=0
virtual Kwave::PlayBackDevice * createDevice(Kwave::playback_method_t method)=0
Here is the call graph for this function:
Here is the caller graph for this function:

◆ currentPos()

sample_index_t Kwave::PlaybackController::currentPos ( ) const

returns the current position of the playback pointer

Definition at line 303 of file PlaybackController.cpp.

References m_playback_position.

Referenced by startDevicePlayBack().

304 {
305  return m_playback_position;
306 }
Here is the caller graph for this function:

◆ endPos()

sample_index_t Kwave::PlaybackController::endPos ( ) const

returns the position where the playback ends

Definition at line 297 of file PlaybackController.cpp.

References m_playback_end.

298 {
299  return m_playback_end;
300 }

◆ loop()

bool Kwave::PlaybackController::loop ( ) const

returns the loop mode flag

Definition at line 261 of file PlaybackController.cpp.

References m_loop_mode.

262 {
263  return m_loop_mode;
264 }

◆ openDevice()

Kwave::PlayBackDevice * Kwave::PlaybackController::openDevice ( int  tracks,
const Kwave::PlayBackParam playback_params 
)

Creates, opens and initializes a playback device.

Parameters
tracksnumber of tracks, if negative use the setting of playback_params
playback_paramspoints to a structure with playback parameters. If null, the default parameters of the current signal will be used
Returns
a pointer to an opened PlayBackDevice or null if failed
See also
PlayBackDevice

Definition at line 610 of file PlaybackController.cpp.

References Kwave::PlayBackParam::bits_per_sample, Kwave::PlayBackParam::bufbase, Kwave::PlayBackParam::channels, checkMethod(), createDevice(), Kwave::PlayBackParam::device, Kwave::MessageBox::error(), Kwave::SignalManager::isClosed(), Kwave::SignalManager::isEmpty(), m_playback_params, m_signal_manager, Kwave::PlayBackParam::method, Kwave::PlayBackDevice::open(), Kwave::SignalManager::parentWidget(), Kwave::PLAYBACK_NONE, Kwave::PlayBackParam::rate, Kwave::SignalManager::rate(), and Kwave::SignalManager::selectedTracks().

Referenced by Kwave::PluginManager::openMultiTrackPlayback(), and startDevicePlayBack().

613 {
614  // take playback parameters if given,
615  // otherwise fall back to current defaults
616  Kwave::PlayBackParam params = (playback_params) ?
617  *playback_params : m_playback_params;
618 
619  // if no playback parameters specified or no method selected:
620  // -> auto-detect best
621  if (!playback_params || (params.method == PLAYBACK_NONE))
622  checkMethod(params.method);
623 
624  if (!playback_params) {
626  params.rate = m_signal_manager.rate();
627  params.channels = m_signal_manager.selectedTracks().count();
628  }
629  }
630 
631  // try to create a new device, using the given playback method
632  Kwave::PlayBackDevice *device = createDevice(params.method);
633  if (!device) return Q_NULLPTR;
634 
635  // override the number of tracks if not negative
636  if (tracks > 0) params.channels = tracks;
637 
638  // open the playback device with it's default parameters
639  // open and initialize the device
640  QString result = device->open(
641  params.device,
642  params.rate,
643  params.channels,
644  params.bits_per_sample,
645  params.bufbase
646  );
647  if (result.length()) {
648  qWarning("PlayBackPlugin::openDevice(): opening the device failed.");
649 
650  // delete the device if it did not open
651  delete device;
652  device = Q_NULLPTR;
653 
654  // show an error message box
656  i18n("Unable to open '%1'",
657  params.device.section(QLatin1Char('|'), 0, 0)));
658  }
659 
660 
661  return device;
662 }
QWidget * parentWidget() const
Kwave::SignalManager & m_signal_manager
unsigned int channels
Definition: PlayBackParam.h:66
unsigned int bits_per_sample
Definition: PlayBackParam.h:69
void checkMethod(Kwave::playback_method_t &method)
unsigned int bufbase
Definition: PlayBackParam.h:75
static int error(QWidget *widget, QString message, QString caption=QString())
Definition: MessageBox.cpp:126
double rate() const
Kwave::playback_method_t method
Definition: PlayBackParam.h:78
const QList< unsigned int > selectedTracks()
virtual Kwave::PlayBackDevice * createDevice(Kwave::playback_method_t method)
virtual QString open(const QString &device, double rate, unsigned int channels, unsigned int bits, unsigned int bufbase)=0
Kwave::PlayBackParam m_playback_params
Here is the call graph for this function:
Here is the caller graph for this function:

◆ paused()

bool Kwave::PlaybackController::paused ( ) const

returns true if the playback is paused

Definition at line 273 of file PlaybackController.cpp.

References m_paused.

274 {
275  return m_paused;
276 }

◆ playbackContinue

void Kwave::PlaybackController::playbackContinue ( )
slot

Continues the playback at the position where it has been stopped by the playbackPause() command. If the last playback pointer has become invalid or is not available (less 0), this function will do the same as playbackStart(). This also emits the signal sigPlaybackStarted().

Definition at line 135 of file PlaybackController.cpp.

References m_paused, m_playing, m_reload_mode, playbackStart(), sigPlaybackStarted(), and startDevicePlayBack().

136 {
137  // leave the reload mode in any case
138  m_reload_mode = false;
139 
140  // if not paused, do the same as start
141  if (!m_paused) {
142  playbackStart();
143  return;
144  }
145 
146  // else reset the paused flag and start from current position
148 
149  m_paused = false;
150  m_playing = true;
151 
152  emit sigPlaybackStarted();
153 }
Here is the call graph for this function:

◆ playbackDone

void Kwave::PlaybackController::playbackDone ( )
slot

Updates the status if playback is done

Definition at line 207 of file PlaybackController.cpp.

References m_old_first, m_old_last, m_paused, m_playback_position, m_playing, m_reload_mode, sigPlaybackPaused(), sigPlaybackPos(), sigPlaybackStopped(), and startDevicePlayBack().

Referenced by PlaybackController().

208 {
209  if (m_reload_mode) {
210  // if we were in the reload mode, reset the
211  // paused flag and start again from current position
213  m_paused = false;
214  m_playing = true;
215 
216  // leave the "reload" mode
217  m_reload_mode = false;
218  return;
219  }
220 
221  m_playing = false;
222  if (m_paused)
223  emit sigPlaybackPaused();
224  else {
226  emit sigPlaybackStopped();
227  }
228 
229  m_old_first = 0;
230  m_old_last = 0;
231 }
void sigPlaybackPos(sample_index_t pos)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ playbackLoop

void Kwave::PlaybackController::playbackLoop ( )
slot

(Re-)starts the playback in loop mode (like with playbackStart(). Also emitts sigPlaybackStarted() if playback has successfully been started.

Definition at line 96 of file PlaybackController.cpp.

References m_loop_mode, m_paused, m_playback_position, m_playback_start, m_playing, m_reload_mode, sigPlaybackPos(), sigPlaybackStarted(), sigPlaybackStopped(), startDevicePlayBack(), and stopDevicePlayBack().

97 {
98  // leave the reload mode in any case
99  m_reload_mode = false;
100 
101  if (m_playing) {
102  // first stop playback
104  m_playing = false;
105  emit sigPlaybackStopped();
106  }
107 
108  // (re)start from beginning without loop mode
111 
112  m_loop_mode = true;
113  m_paused = false;
115 
116  m_playing = true;
117  emit sigPlaybackStarted();
118 }
void sigPlaybackPos(sample_index_t pos)
Here is the call graph for this function:

◆ playbackPause

void Kwave::PlaybackController::playbackPause ( )
slot

Pauses the playback. Causes sigPlaybackDone() to be emitted if the current buffer has played out. The current playback pointer will stay at it's current position.

Definition at line 121 of file PlaybackController.cpp.

References m_paused, m_playing, m_reload_mode, and stopDevicePlayBack().

122 {
123  // leave the reload mode in any case
124  m_reload_mode = false;
125 
126  if (!m_playing) return; // no effect if not playing
127 
128  m_paused = true;
129 
130  // stop playback for now and set the paused flag
132 }
Here is the call graph for this function:

◆ playbackStart

void Kwave::PlaybackController::playbackStart ( )
slot

(Re-)starts the playback. If playback has successfully been started, the signal sigPlaybackStarted() will be emitted.

Definition at line 72 of file PlaybackController.cpp.

References m_loop_mode, m_paused, m_playback_position, m_playback_start, m_playing, m_reload_mode, sigPlaybackPos(), sigPlaybackStarted(), sigPlaybackStopped(), startDevicePlayBack(), and stopDevicePlayBack().

Referenced by Kwave::SignalManager::executeCommand(), and playbackContinue().

73 {
74  // leave the reload mode in any case
75  m_reload_mode = false;
76 
77  if (m_playing) {
78  // first stop playback
80  emit sigPlaybackStopped();
81  }
82 
83  // (re)start from beginning without loop mode
86 
87  m_loop_mode = false;
88  m_paused = false;
89  m_playing = true;
90  emit sigPlaybackStarted();
91 
93 }
void sigPlaybackPos(sample_index_t pos)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ playbackStop

void Kwave::PlaybackController::playbackStop ( )
slot

Stopps playback / loop. Like playbackPause(), but resets the playback pointer back to the start.

Definition at line 156 of file PlaybackController.cpp.

References m_paused, m_playing, m_reload_mode, sigPlaybackStopped(), and stopDevicePlayBack().

Referenced by Kwave::SignalManager::close(), and ~PlaybackController().

157 {
158  // leave the reload mode in any case
159  m_reload_mode = false;
160 
161  // stopped in pause state
162  if (m_paused) {
163  m_playing = false;
164  m_paused = false;
165  emit sigPlaybackStopped();
166  }
167  if (!m_playing) return; // already stopped
169 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ registerPlaybackDeviceFactory()

void Kwave::PlaybackController::registerPlaybackDeviceFactory ( Kwave::PlaybackDeviceFactory factory)

Registers a PlaybackDeviceFactory

Definition at line 672 of file PlaybackController.cpp.

References m_playback_factories.

Referenced by Kwave::PlayBackPlugin::load().

674 {
675  m_playback_factories.append(factory);
676 }
QList< Kwave::PlaybackDeviceFactory * > m_playback_factories
Here is the caller graph for this function:

◆ reload

void Kwave::PlaybackController::reload ( )
slot

If playback is currently running, it will be paused and then restarted with current track and time selection.

Definition at line 234 of file PlaybackController.cpp.

References m_paused, m_playing, m_reload_mode, and stopDevicePlayBack().

235 {
236  if (!m_playing || m_paused) return; // no effect if not playing or paused
237 
238  // enter the "reload" mode
239  m_reload_mode = true;
240 
241  // stop playback for now and set the paused flag
242  m_paused = true;
244 }
Here is the call graph for this function:

◆ reset()

void Kwave::PlaybackController::reset ( )

resets start, current position, loop, pause and running flag

Definition at line 247 of file PlaybackController.cpp.

References m_loop_mode, m_paused, m_playback_position, m_playback_start, m_playing, m_reload_mode, sigPlaybackPos(), and sigPlaybackStopped().

Referenced by Kwave::SignalManager::close().

248 {
249  m_playback_start = 0;
251  m_loop_mode = false;
252  m_playing = false;
253  m_paused = false;
254  m_reload_mode = false;
255 
256  emit sigPlaybackPos(0);
257  emit sigPlaybackStopped();
258 }
void sigPlaybackPos(sample_index_t pos)
Here is the caller graph for this function:

◆ run_wrapper()

void Kwave::PlaybackController::run_wrapper ( const QVariant &  params)
protectedvirtual

wrapper for our run() function, called from worker thread

Implements Kwave::Runnable.

Definition at line 399 of file PlaybackController.cpp.

References Kwave::SignalManager::allTracks(), Kwave::WorkerThread::cancel(), Kwave::PlayBackParam::channels, Kwave::SampleReader::eof(), Kwave::FullSnapshot, m_device, m_lock_device, m_lock_playback, m_loop_mode, m_playback_end, m_playback_params, m_playback_position, m_playback_start, m_seek_pos, m_should_seek, m_signal_manager, m_thread, m_track_selection_changed, Kwave::PlayBackParam::rate, Kwave::MultiTrackReader::reset(), SCREEN_REFRESHES_PER_SECOND, Kwave::MultiTrackReader::seek(), seekDone(), Kwave::SignalManager::selectedTracks(), Kwave::WorkerThread::shouldStop(), sigDevicePlaybackDone(), Kwave::MultiTrackReader::skip(), startPos(), Kwave::toUint(), updatePlaybackPos(), and Kwave::PlayBackDevice::write().

400 {
401  Q_UNUSED(params);
402 
403  Kwave::MixerMatrix *mixer = Q_NULLPTR;
406  unsigned int out_channels = m_playback_params.channels;
407 
408  QList<unsigned int> all_tracks = m_signal_manager.allTracks();
409  unsigned int tracks = all_tracks.count();
410  QList<unsigned int> audible_tracks = m_signal_manager.selectedTracks();
411  unsigned int audible_count = audible_tracks.count();
412 
413  // get the list of selected channels
414  if (!tracks || !m_device) {
415  // not even one selected track or no (open) device
416  qDebug("PlaybackController::run(): no audible track(s) !");
417  emit sigDevicePlaybackDone();
418  return;
419  }
420 
421  // set up a set of sample reader (streams)
424  m_signal_manager, all_tracks, first, last);
425 
426  // create a new translation matrix for mixing up/down to the desired
427  // number of output channels
429 
430  // loop until process is stopped
431  // or run once if not in loop mode
432  Kwave::SampleArray in_samples(tracks);
433  Kwave::SampleArray out_samples(out_channels);
435  updatePlaybackPos(pos);
436 
437  // counter for refresh of the playback position
438  unsigned int pos_countdown = 0;
439 
440  do {
441 
442  // if current position is after start -> skip the passed
443  // samples (this happens when resuming after a pause)
444  if (pos > first) input.skip(pos - first);
445 
446  while ((pos++ <= last) && !m_thread.shouldStop()) {
447  unsigned int x;
448  unsigned int y;
449  bool seek_again = false;
450  bool seek_done = false;
451 
452  {
453  QMutexLocker _lock(&m_lock_playback);
454 
455  // check for track selection change (need for new mixer)
457  if (mixer) delete mixer;
458  mixer = Q_NULLPTR;
460  }
461 
462  if (!mixer) {
463  audible_tracks = m_signal_manager.selectedTracks();
464  audible_count = audible_tracks.count();
465  mixer = new Kwave::MixerMatrix(audible_count, out_channels);
466  Q_ASSERT(mixer);
467  if (!mixer) break;
468  seek_again = true; // re-synchronize all reader positions
469  }
470 
471  // check for seek requests
472  if (m_should_seek && (m_seek_pos != pos)) {
473  if (m_seek_pos < first) m_seek_pos = first;
474  if (m_seek_pos > last) { pos = last; break; }
475  pos = m_seek_pos;
476  m_should_seek = false;
477  seek_again = true;
478  seek_done = true;
479  }
480  }
481 
482  if (seek_again) input.seek(pos);
483  if (seek_done) seekDone(pos);;
484 
485  // fill input buffer with samples
486  for (x = 0; x < audible_count; ++x) {
487  in_samples[x] = 0;
488  Kwave::SampleReader *stream = input[audible_tracks[x]];
489  Q_ASSERT(stream);
490  if (!stream) continue;
491 
492  if (!stream->eof()) (*stream) >> in_samples[x];
493  }
494 
495  // multiply matrix with input to get output
496  const Kwave::SampleArray &in = in_samples;
497  for (y = 0; y < out_channels; ++y) {
498  double sum = 0;
499  for (x = 0; x < audible_count; ++x) {
500  sum += static_cast<double>(in[x]) * (*mixer)[x][y];
501  }
502  out_samples[y] = static_cast<sample_t>(sum);
503  }
504 
505  // write samples to the playback device
506  int result = -1;
507  {
508  QMutexLocker lock(&m_lock_device);
509  if (m_device)
510  result = m_device->write(out_samples);
511  }
512  if (result) {
513  m_thread.cancel();
514  pos = last;
515  }
516 
517  // update the playback position if timer elapsed
518  if (!pos_countdown) {
519  pos_countdown = Kwave::toUint(ceil(
521  updatePlaybackPos(pos);
522  } else {
523  --pos_countdown;
524  }
525  }
526 
527  // maybe we loop. in this case the playback starts
528  // again from the left marker
529  if (m_loop_mode && !m_thread.shouldStop()) {
530  input.reset();
531  pos = startPos();
532  }
533 
534  } while (m_loop_mode && !m_thread.shouldStop());
535 
536  // playback is done
537  emit sigDevicePlaybackDone();
538 // qDebug("PlaybackController::run() done.");
539 }
Kwave::SignalManager & m_signal_manager
virtual int write(const Kwave::SampleArray &samples)=0
unsigned int channels
Definition: PlayBackParam.h:66
void updatePlaybackPos(sample_index_t pos)
#define SCREEN_REFRESHES_PER_SECOND
quint64 sample_index_t
Definition: Sample.h:28
sample_index_t startPos() const
bool eof() const
Definition: SampleReader.h:66
void seekDone(sample_index_t pos)
virtual void cancel()
const QList< unsigned int > allTracks()
Kwave::PlayBackDevice * m_device
const QList< unsigned int > selectedTracks()
unsigned int toUint(T x)
Definition: Utils.h:109
Kwave::PlayBackParam m_playback_params
Kwave::WorkerThread m_thread
qint32 sample_t
Definition: Sample.h:37
Here is the call graph for this function:

◆ running()

bool Kwave::PlaybackController::running ( ) const

returns true if the playback is running

Definition at line 267 of file PlaybackController.cpp.

References m_playing.

Referenced by Kwave::SignalView::mousePressEvent(), and Kwave::SignalView::mouseReleaseEvent().

268 {
269  return m_playing;
270 }
Here is the caller graph for this function:

◆ seekDone

void Kwave::PlaybackController::seekDone ( sample_index_t  pos)
slot

Called when the seek has finished

Definition at line 194 of file PlaybackController.cpp.

References sigSeekDone().

Referenced by run_wrapper(), and seekTo().

195 {
196  emit sigSeekDone(pos);
197 }
void sigSeekDone(sample_index_t pos)
Here is the caller graph for this function:

◆ seekTo

void Kwave::PlaybackController::seekTo ( sample_index_t  pos)
slot

Seeks to a new position

Definition at line 172 of file PlaybackController.cpp.

References m_lock_playback, m_paused, m_playback_end, m_playback_start, m_seek_pos, m_should_seek, seekDone(), and updatePlaybackPos().

173 {
174  if (pos < m_playback_start) pos = m_playback_start;
175  if (pos > m_playback_end) pos = m_playback_end;
176 
177  {
178  QMutexLocker lock(&m_lock_playback);
179  qDebug("seekTo(%llu)", pos);
180  m_seek_pos = pos;
181  m_should_seek = true;
182  }
183 
184  if (m_paused) {
185  // if playback is paused, we want an update of the playback
186  // position anyway. as this will not come from the device layer,
187  // fake an update right here
188  updatePlaybackPos(pos);
189  seekDone(pos);
190  }
191 }
void updatePlaybackPos(sample_index_t pos)
void seekDone(sample_index_t pos)
Here is the call graph for this function:

◆ setDefaultParams()

void Kwave::PlaybackController::setDefaultParams ( const Kwave::PlayBackParam params)

Sets default playback parameters, for use next time playback is started

Parameters
paramsnew playback parameters

Definition at line 665 of file PlaybackController.cpp.

References m_playback_params.

Referenced by Kwave::PlayBackPlugin::load(), and Kwave::PlayBackPlugin::setup().

667 {
668  m_playback_params = params;
669 }
Kwave::PlayBackParam m_playback_params
Here is the caller graph for this function:

◆ setEndPos()

void Kwave::PlaybackController::setEndPos ( sample_index_t  pos)

sets a new end position

Definition at line 285 of file PlaybackController.cpp.

References m_playback_end.

Referenced by startDevicePlayBack().

286 {
287  m_playback_end = pos;
288 }
Here is the caller graph for this function:

◆ setStartPos()

void Kwave::PlaybackController::setStartPos ( sample_index_t  pos)

sets a new start position

Definition at line 279 of file PlaybackController.cpp.

References m_playback_start.

Referenced by startDevicePlayBack().

280 {
281  m_playback_start = pos;
282 }
Here is the caller graph for this function:

◆ sigDevicePlaybackDone

void Kwave::PlaybackController::sigDevicePlaybackDone ( )
signal

Signals that playback has stopped (sent from worker thread).

Referenced by PlaybackController(), run_wrapper(), startDevicePlayBack(), and stopDevicePlayBack().

Here is the caller graph for this function:

◆ sigDevicePlaybackPos

void Kwave::PlaybackController::sigDevicePlaybackPos ( sample_index_t  pos)
signal

Emits the current playback position (from worker thread)

◆ sigDeviceSeekDone

void Kwave::PlaybackController::sigDeviceSeekDone ( sample_index_t  pos)
signal

Emitted after a successful seek operation (from worker thread)

◆ sigPlaybackPaused

void Kwave::PlaybackController::sigPlaybackPaused ( )
signal

Signals that playback has been paused.

Referenced by playbackDone().

Here is the caller graph for this function:

◆ sigPlaybackPos

void Kwave::PlaybackController::sigPlaybackPos ( sample_index_t  pos)
signal

Emits the current position of the playback pointer

Referenced by playbackDone(), playbackLoop(), playbackStart(), reset(), and updatePlaybackPos().

Here is the caller graph for this function:

◆ sigPlaybackStarted

void Kwave::PlaybackController::sigPlaybackStarted ( )
signal

Signals that playback has started.

Referenced by playbackContinue(), playbackLoop(), and playbackStart().

Here is the caller graph for this function:

◆ sigPlaybackStopped

void Kwave::PlaybackController::sigPlaybackStopped ( )
signal

Signals that playback has stopped.

Referenced by playbackDone(), playbackLoop(), playbackStart(), playbackStop(), and reset().

Here is the caller graph for this function:

◆ sigSeekDone

void Kwave::PlaybackController::sigSeekDone ( sample_index_t  pos)
signal

Emits the current position after a seek operation

Referenced by seekDone().

Here is the caller graph for this function:

◆ startDevicePlayBack()

void Kwave::PlaybackController::startDevicePlayBack ( )
private

Starts playback device (and worker thread)

Definition at line 309 of file PlaybackController.cpp.

References currentPos(), Kwave::Selection::first(), Kwave::Selection::last(), Kwave::SignalManager::length(), m_device, m_lock_device, m_old_first, m_old_last, m_paused, m_playback_params, m_signal_manager, m_thread, openDevice(), Kwave::PlayBackParam::rate, Kwave::SignalManager::rate(), Kwave::SignalManager::selection(), setEndPos(), setStartPos(), sigDevicePlaybackDone(), Kwave::WorkerThread::start(), and updatePlaybackPos().

Referenced by playbackContinue(), playbackDone(), playbackLoop(), and playbackStart().

310 {
311  // set the real sample rate for playback from the signal itself
313 
314  QMutexLocker lock_for_delete(&m_lock_device);
315 
316  // remove the old device if still one exists
317  if (m_device) {
318  qWarning("PlaybackController::startDevicePlayBack(): "
319  "removing stale instance");
320  delete m_device;
321  m_device = Q_NULLPTR;
322  }
323 
324  // open the device and abort if not possible
325 
326 // qDebug("PlaybackController::startDevicePlayBack(), device='%s'",
327 // DBG(m_playback_params.device));
329  if (!m_device) {
330  // simulate a "playback done" on errors
331  emit sigDevicePlaybackDone();
332  return;
333  }
334 
337 
338  if (m_paused) {
339  // continue after pause
340  if ((m_old_first != first) || (m_old_last != last)) {
341  // selection has changed
342  if (first != last) {
343  // something selected -> set new range
344  setStartPos(first);
345  setEndPos(last);
346 
347  sample_index_t pos = currentPos();
348  if ((pos < first) || (pos > last)) {
349  // completely new area selected, or the right margin
350  // has been moved before the current playback pointer
351  // -> play from start of new selection
352  updatePlaybackPos(first);
353  }
354  } else {
355  // nothing selected -> select all and move to position
356  setStartPos(first);
358  }
359  }
360  } else {
361  // determine first and last sample if not in paused mode"
362  if (first == last) {
363  // nothing selected -> play from cursor position
364  setStartPos(first);
366  } else {
367  // play only in selection
368  setStartPos(first);
369  setEndPos(last);
370  }
371  updatePlaybackPos(first);
372  }
373 
374  m_old_first = first;
375  m_old_last = last;
376 
377  m_thread.start();
378 }
Kwave::SignalManager & m_signal_manager
sample_index_t first() const
Definition: Selection.h:71
void setEndPos(sample_index_t pos)
sample_index_t last() const
Definition: Selection.h:76
void updatePlaybackPos(sample_index_t pos)
Kwave::Selection & selection()
quint64 sample_index_t
Definition: Sample.h:28
sample_index_t length()
double rate() const
Kwave::PlayBackDevice * m_device
virtual void start()
Kwave::PlayBackDevice * openDevice(int tracks, const Kwave::PlayBackParam *playback_params)
void setStartPos(sample_index_t pos)
Kwave::PlayBackParam m_playback_params
Kwave::WorkerThread m_thread
sample_index_t currentPos() const
Here is the call graph for this function:
Here is the caller graph for this function:

◆ startPos()

sample_index_t Kwave::PlaybackController::startPos ( ) const

returns the position where the playback starts

Definition at line 291 of file PlaybackController.cpp.

References m_playback_start.

Referenced by run_wrapper().

292 {
293  return m_playback_start;
294 }
Here is the caller graph for this function:

◆ stopDevicePlayBack()

void Kwave::PlaybackController::stopDevicePlayBack ( )
private

Stops the playback device (and worker thread)

Definition at line 381 of file PlaybackController.cpp.

References Kwave::WorkerThread::cancel(), closeDevice(), m_thread, and sigDevicePlaybackDone().

Referenced by playbackLoop(), playbackPause(), playbackStart(), playbackStop(), and reload().

382 {
383  m_thread.cancel();
384  if (!m_thread.isRunning()) {
385  qDebug("PlaybackController::stopDevicePlayBack() - not running");
386  emit sigDevicePlaybackDone();
387  }
388  closeDevice();
389 }
virtual void cancel()
Kwave::WorkerThread m_thread
Here is the call graph for this function:
Here is the caller graph for this function:

◆ trackSelectionChanged

void Kwave::PlaybackController::trackSelectionChanged ( )
privateslot

updates the mixer matrix if the track selection has changed

Definition at line 392 of file PlaybackController.cpp.

References m_lock_playback, and m_track_selection_changed.

Referenced by PlaybackController().

393 {
394  QMutexLocker lock(&m_lock_playback);
396 }
Here is the caller graph for this function:

◆ unregisterPlaybackDeviceFactory()

void Kwave::PlaybackController::unregisterPlaybackDeviceFactory ( Kwave::PlaybackDeviceFactory factory)

Unregisters a PlaybackDeviceFactory

Definition at line 679 of file PlaybackController.cpp.

References m_playback_factories.

Referenced by Kwave::PlayBackPlugin::unload().

681 {
682  m_playback_factories.removeAll(factory);
683 }
QList< Kwave::PlaybackDeviceFactory * > m_playback_factories
Here is the caller graph for this function:

◆ updatePlaybackPos

void Kwave::PlaybackController::updatePlaybackPos ( sample_index_t  pos)
slot

Updates the current playback position

Definition at line 200 of file PlaybackController.cpp.

References m_playback_position, and sigPlaybackPos().

Referenced by run_wrapper(), seekTo(), and startDevicePlayBack().

201 {
202  m_playback_position = pos;
203  emit sigPlaybackPos(m_playback_position); // TODO => per TIMER !!!
204 }
void sigPlaybackPos(sample_index_t pos)
Here is the caller graph for this function:

Member Data Documentation

◆ m_device

Kwave::PlayBackDevice* Kwave::PlaybackController::m_device
private

The playback device used for playback

Definition at line 274 of file PlaybackController.h.

Referenced by closeDevice(), run_wrapper(), and startDevicePlayBack().

◆ m_lock_device

QMutex Kwave::PlaybackController::m_lock_device
private

Mutex for locking access to the playback device

Definition at line 277 of file PlaybackController.h.

Referenced by closeDevice(), run_wrapper(), and startDevicePlayBack().

◆ m_lock_playback

QMutex Kwave::PlaybackController::m_lock_playback
private

Mutex for locking access to members that control the playback loop, like m_should_seek, m_seek_pos and m_mixer

Definition at line 286 of file PlaybackController.h.

Referenced by run_wrapper(), seekTo(), and trackSelectionChanged().

◆ m_loop_mode

bool Kwave::PlaybackController::m_loop_mode
private

if set to true, the playback will be done in loop mode

Definition at line 306 of file PlaybackController.h.

Referenced by loop(), playbackLoop(), playbackStart(), reset(), and run_wrapper().

◆ m_old_first

sample_index_t Kwave::PlaybackController::m_old_first
private

Start of the selection when playback started

Definition at line 324 of file PlaybackController.h.

Referenced by playbackDone(), and startDevicePlayBack().

◆ m_old_last

sample_index_t Kwave::PlaybackController::m_old_last
private

End of the selection when playback started

Definition at line 327 of file PlaybackController.h.

Referenced by playbackDone(), and startDevicePlayBack().

◆ m_paused

bool Kwave::PlaybackController::m_paused
private

if true, playback is only paused and can be continued

Definition at line 309 of file PlaybackController.h.

Referenced by paused(), playbackContinue(), playbackDone(), playbackLoop(), playbackPause(), playbackStart(), playbackStop(), reload(), reset(), seekTo(), and startDevicePlayBack().

◆ m_playback_end

sample_index_t Kwave::PlaybackController::m_playback_end
private

the end position for playback

Definition at line 321 of file PlaybackController.h.

Referenced by endPos(), run_wrapper(), seekTo(), and setEndPos().

◆ m_playback_factories

QList<Kwave::PlaybackDeviceFactory *> Kwave::PlaybackController::m_playback_factories
private

list of playback device factories

Definition at line 330 of file PlaybackController.h.

Referenced by checkMethod(), createDevice(), registerPlaybackDeviceFactory(), and unregisterPlaybackDeviceFactory().

◆ m_playback_params

Kwave::PlayBackParam Kwave::PlaybackController::m_playback_params
private

the parameters used for playback

Definition at line 280 of file PlaybackController.h.

Referenced by openDevice(), run_wrapper(), setDefaultParams(), and startDevicePlayBack().

◆ m_playback_position

sample_index_t Kwave::PlaybackController::m_playback_position
private

the current play position

Definition at line 315 of file PlaybackController.h.

Referenced by currentPos(), playbackDone(), playbackLoop(), playbackStart(), reset(), run_wrapper(), and updatePlaybackPos().

◆ m_playback_start

sample_index_t Kwave::PlaybackController::m_playback_start
private

the start position for playback

Definition at line 318 of file PlaybackController.h.

Referenced by playbackLoop(), playbackStart(), reset(), run_wrapper(), seekTo(), setStartPos(), and startPos().

◆ m_playing

bool Kwave::PlaybackController::m_playing
private

is set to true if the playback has been started

Definition at line 312 of file PlaybackController.h.

Referenced by playbackContinue(), playbackDone(), playbackLoop(), playbackPause(), playbackStart(), playbackStop(), reload(), reset(), and running().

◆ m_reload_mode

bool Kwave::PlaybackController::m_reload_mode
private

If true, we are in "reload" mode. In this mode the playback is paused and continued without emitting a sigPlaybackDone. This is useful if playback parameters or signal selection has changed during playback.

Definition at line 303 of file PlaybackController.h.

Referenced by playbackContinue(), playbackDone(), playbackLoop(), playbackPause(), playbackStart(), playbackStop(), reload(), and reset().

◆ m_seek_pos

sample_index_t Kwave::PlaybackController::m_seek_pos
private

position to seek to

Definition at line 292 of file PlaybackController.h.

Referenced by run_wrapper(), and seekTo().

◆ m_should_seek

bool Kwave::PlaybackController::m_should_seek
private

if true, m_seek_pos is valid and a seek has been requested

Definition at line 289 of file PlaybackController.h.

Referenced by run_wrapper(), and seekTo().

◆ m_signal_manager

Kwave::SignalManager& Kwave::PlaybackController::m_signal_manager
private

Reference to our signal manager

Definition at line 266 of file PlaybackController.h.

Referenced by openDevice(), PlaybackController(), run_wrapper(), and startDevicePlayBack().

◆ m_thread

Kwave::WorkerThread Kwave::PlaybackController::m_thread
private

Thread that executes the run() member function.

Definition at line 271 of file PlaybackController.h.

Referenced by run_wrapper(), startDevicePlayBack(), and stopDevicePlayBack().

◆ m_track_selection_changed

bool Kwave::PlaybackController::m_track_selection_changed
private

notification flag, true if the track selection has changed

Definition at line 295 of file PlaybackController.h.

Referenced by run_wrapper(), and trackSelectionChanged().


The documentation for this class was generated from the following files: