kwave  18.07.70
MultiPlaybackSink.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  MultiPlaybackSink.cpp - multi-track Kwave playback sink
3  -------------------
4  begin : Sun Nov 04 2007
5  copyright : (C) 2007 by Thomas Eschenbacher
6  email : 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 #include "config.h"
19 
20 #include <new>
21 
22 #include <QMutexLocker>
23 #include <QtGlobal>
24 
27 #include "libkwave/PlaybackSink.h"
28 #include "libkwave/memcpy.h"
29 
30 //***************************************************************************
32  Kwave::PlayBackDevice *device)
33  :Kwave::MultiTrackSink<Kwave::PlaybackSink, false>(0),
34  m_tracks(tracks), m_device(device), m_in_buffer(tracks),
35  m_in_buffer_filled(tracks),
36  m_out_buffer(tracks), m_lock()
37 {
39  m_in_buffer_filled.fill(false);
40 
41  for (unsigned int track = 0; track < m_tracks; track++) {
42  // allocate a sink
43  Kwave::PlaybackSink *sink =
44  new(std::nothrow) Kwave::PlaybackSink(track);
45  insert(track, sink);
46  connect(sink, SIGNAL(output(uint,Kwave::SampleArray)),
47  this, SLOT(input(uint,Kwave::SampleArray)),
48  Qt::DirectConnection);
49  }
50 }
51 
52 //***************************************************************************
54 {
55  // close all stream objects
56  clear();
57 
58  // close the device
59  if (m_device) {
60  m_device->close();
61  delete m_device;
62  }
63  m_device = Q_NULLPTR;
64 
65  // discard the buffers
66  while (!m_in_buffer.isEmpty())
67  m_in_buffer.erase(m_in_buffer.end() - 1);
68  m_in_buffer.clear();
69 }
70 
71 //***************************************************************************
72 void Kwave::MultiPlaybackSink::input(unsigned int track,
73  Kwave::SampleArray data)
74 {
75  QMutexLocker lock(&m_lock);
76 
77  Q_ASSERT(m_device);
78  Q_ASSERT(m_tracks);
79  if (!m_device || !m_tracks) return;
80 
81  Q_ASSERT(!m_in_buffer_filled[track]);
82  m_in_buffer_filled[track] = true;
83 
84  // copy the input data to the buffer
85  unsigned int samples = data.size();
86  m_in_buffer[track] = data;
87 
88  // check if all buffers are filled
89  for (unsigned int t = 0; t < m_tracks; t++)
90  if (!m_in_buffer_filled[t]) return;
91 
92  // all tracks have left their data, now we are ready
93  // to convert the buffers into a big combined one
94  Q_ASSERT(m_out_buffer.size() >= m_tracks);
95  for (unsigned int sample = 0; sample < samples; sample++) {
96  for (unsigned int t = 0; t < m_tracks; t++) {
97  const Kwave::SampleArray &in = m_in_buffer[t];
98  m_out_buffer[t] = in[sample];
99  }
100 
101  // play the output buffer
103  }
104 
105  m_in_buffer_filled.fill(false);
106 }
107 
108 //***************************************************************************
109 //***************************************************************************
virtual int write(const Kwave::SampleArray &samples)=0
Definition: App.h:33
Kwave::SampleArray m_out_buffer
QVector< Kwave::SampleArray > m_in_buffer
void input(unsigned int track, Kwave::SampleArray data)
bool connect(Kwave::StreamObject &source, const char *output, Kwave::StreamObject &sink, const char *input)
Definition: Connect.cpp:48
MultiPlaybackSink(unsigned int tracks, Kwave::PlayBackDevice *device)
virtual bool insert(unsigned int track, Kwave::PlaybackSink *sink)
Kwave::PlayBackDevice * m_device
unsigned int size() const
virtual int close()=0