kwave  18.07.70
Kwave::ChannelMixer Class Reference

#include <ChannelMixer.h>

Inheritance diagram for Kwave::ChannelMixer:
Inheritance graph
Collaboration diagram for Kwave::ChannelMixer:
Collaboration graph

Public Slots

void input (Kwave::SampleArray data)
 

Signals

void output (Kwave::SampleArray data)
 
- Signals inherited from Kwave::StreamObject
void attributeChanged (const QVariant value)
 

Public Member Functions

 ChannelMixer (unsigned int inputs, unsigned int outputs)
 
virtual ~ChannelMixer () Q_DECL_OVERRIDE
 
virtual bool init ()
 
virtual unsigned int tracksOfPort (const char *port) const Q_DECL_OVERRIDE
 
virtual Kwave::StreamObjectport (const char *port, unsigned int track) Q_DECL_OVERRIDE
 
virtual void goOn () Q_DECL_OVERRIDE
 
- Public Member Functions inherited from Kwave::SampleSource
 SampleSource (QObject *parent=Q_NULLPTR)
 
virtual ~SampleSource ()
 
virtual bool done () const
 
- Public Member Functions inherited from Kwave::StreamObject
 StreamObject (QObject *parent=Q_NULLPTR)
 
virtual ~StreamObject ()
 
virtual unsigned int tracks () const
 
virtual Kwave::StreamObjectoperator[] (unsigned int track)
 
virtual unsigned int blockSize () const
 
void setAttribute (const char *attribute, const QVariant &value)
 

Private Slots

void idxInput (unsigned int index, Kwave::SampleArray data)
 

Private Member Functions

virtual void mix ()
 

Private Attributes

Kwave::MixerMatrixm_matrix
 
unsigned int m_inputs
 
unsigned int m_outputs
 
QVector< QPointer< Kwave::StreamObject > > m_indexer
 
QVector< QQueue< Kwave::SampleArray > > m_input_queue
 
QVector< QPointer< Kwave::SampleBuffer > > m_output_buffer
 
QMutex m_lock
 

Additional Inherited Members

- Static Public Member Functions inherited from Kwave::StreamObject
static void setInteractive (bool interactive)
 

Detailed Description

Definition at line 41 of file ChannelMixer.h.

Constructor & Destructor Documentation

◆ ChannelMixer()

Kwave::ChannelMixer::ChannelMixer ( unsigned int  inputs,
unsigned int  outputs 
)

Constructor

Parameters
inputsnumber of input channels
outputsnumber of output channels

Definition at line 35 of file ChannelMixer.cpp.

37  m_matrix(Q_NULLPTR),
38  m_inputs(inputs),
39  m_outputs(outputs),
40  m_indexer(),
41  m_input_queue(),
43  m_lock()
44 {
45 }
Kwave::MixerMatrix * m_matrix
Definition: ChannelMixer.h:113
unsigned int m_inputs
Definition: ChannelMixer.h:116
QVector< QPointer< Kwave::StreamObject > > m_indexer
Definition: ChannelMixer.h:121
unsigned int m_outputs
Definition: ChannelMixer.h:119
QVector< QPointer< Kwave::SampleBuffer > > m_output_buffer
Definition: ChannelMixer.h:127
QVector< QQueue< Kwave::SampleArray > > m_input_queue
Definition: ChannelMixer.h:124

◆ ~ChannelMixer()

Kwave::ChannelMixer::~ChannelMixer ( )
virtual

Destructor

Definition at line 92 of file ChannelMixer.cpp.

References m_indexer, m_input_queue, m_lock, and m_output_buffer.

93 {
94  QMutexLocker _lock(&m_lock);
95 
96  while (!m_indexer.isEmpty()) {
97  Kwave::StreamObject *indexer = m_indexer[0];
98  if (indexer) delete indexer;
99  m_indexer.remove(0);
100  }
101 
102  m_input_queue.clear();
103 
104  while (!m_output_buffer.isEmpty()) {
106  if (buffer) delete buffer;
107  m_output_buffer.remove(0);
108  }
109 }
QVector< QPointer< Kwave::StreamObject > > m_indexer
Definition: ChannelMixer.h:121
QVector< QPointer< Kwave::SampleBuffer > > m_output_buffer
Definition: ChannelMixer.h:127
QVector< QQueue< Kwave::SampleArray > > m_input_queue
Definition: ChannelMixer.h:124

Member Function Documentation

◆ goOn()

virtual void Kwave::ChannelMixer::goOn ( )
inlinevirtual

does nothing, work is done automatically in mix()

Implements Kwave::SampleSource.

Definition at line 83 of file ChannelMixer.h.

84  {
85  }

◆ idxInput

void Kwave::ChannelMixer::idxInput ( unsigned int  index,
Kwave::SampleArray  data 
)
privateslot

receives a block with index + input data

Definition at line 167 of file ChannelMixer.cpp.

References m_input_queue, m_inputs, m_lock, m_matrix, mix(), and Kwave::toInt().

Referenced by init(), port(), and tracksOfPort().

168 {
169  QMutexLocker _lock(&m_lock);
170 
171  // put the data into the corresponding input queue
172  Q_ASSERT(index < m_inputs);
173  Q_ASSERT(Kwave::toInt(index) < m_input_queue.count());
174  if (Kwave::toInt(index) < m_input_queue.count())
175  m_input_queue[index].enqueue(data);
176 
177  // check: if there is one empty queue we are not yet ready for mixing
178  bool ready = true;
179  foreach (const QQueue<Kwave::SampleArray> &queue, m_input_queue) {
180  if (queue.isEmpty()) {
181  ready = false;
182  break;
183  }
184  }
185 
186  // mix if we are ready
187  if (ready && m_matrix) mix();
188 }
Kwave::MixerMatrix * m_matrix
Definition: ChannelMixer.h:113
unsigned int m_inputs
Definition: ChannelMixer.h:116
int toInt(T x)
Definition: Utils.h:127
virtual void mix()
QVector< QQueue< Kwave::SampleArray > > m_input_queue
Definition: ChannelMixer.h:124
Here is the call graph for this function:
Here is the caller graph for this function:

◆ init()

bool Kwave::ChannelMixer::init ( )
virtual

Init function, you must call it once after creating and before using this object. If the return value is false, you should delete this object.

Returns
true if succeeded, false if failed

Definition at line 48 of file ChannelMixer.cpp.

References Kwave::connect(), idxInput(), m_indexer, m_input_queue, m_inputs, m_matrix, m_output_buffer, m_outputs, output(), and Kwave::toInt().

Referenced by Kwave::MimeData::decode(), and Kwave::OpusEncoder::setupDownMix().

49 {
50  if (!m_inputs || !m_outputs) return false;
51 
52  // create queues for the input data
53  m_input_queue.resize(m_inputs);
54  Q_ASSERT(m_input_queue.count() == Kwave::toInt(m_inputs));
55  if (m_input_queue.count() != Kwave::toInt(m_inputs)) return false;
56 
57  // create the buffers for the output data
58  for (unsigned int index = 0; index < m_outputs; ++index) {
59  // create a buffer for the input
60  Kwave::SampleBuffer *out_buffer = new Kwave::SampleBuffer();
61  Q_ASSERT(out_buffer);
62  if (!out_buffer) return false;
63  m_output_buffer.append(out_buffer);
64  }
65 
66  // create indexing proxies and connect their output to this mixer
67  for (unsigned int index = 0; index < m_inputs; ++index) {
68  Kwave::StreamObject *indexer = new Kwave::Indexer(index);
69  Q_ASSERT(indexer);
70  if (!indexer) return false;
71 
72  m_indexer.append(indexer);
73  bool ok = Kwave::connect(
74  *indexer, SIGNAL(output(uint,Kwave::SampleArray)),
75  *this, SLOT(idxInput(uint,Kwave::SampleArray)));
76  Q_ASSERT(ok);
77  if (!ok) return false;
78  }
79 
80  // create the mixer matrix
81  // create a translation matrix for mixing up/down to the desired
82  // number of output channels
83  m_matrix = new Kwave::MixerMatrix(m_inputs, m_outputs);
84  Q_ASSERT(m_matrix);
85  if (!m_matrix) return false;
86 
87  // everything succeeded
88  return true;
89 }
Kwave::MixerMatrix * m_matrix
Definition: ChannelMixer.h:113
unsigned int m_inputs
Definition: ChannelMixer.h:116
bool connect(Kwave::StreamObject &source, const char *output, Kwave::StreamObject &sink, const char *input)
Definition: Connect.cpp:48
void output(Kwave::SampleArray data)
QVector< QPointer< Kwave::StreamObject > > m_indexer
Definition: ChannelMixer.h:121
int toInt(T x)
Definition: Utils.h:127
unsigned int m_outputs
Definition: ChannelMixer.h:119
void idxInput(unsigned int index, Kwave::SampleArray data)
QVector< QPointer< Kwave::SampleBuffer > > m_output_buffer
Definition: ChannelMixer.h:127
QVector< QQueue< Kwave::SampleArray > > m_input_queue
Definition: ChannelMixer.h:124
Here is the call graph for this function:
Here is the caller graph for this function:

◆ input

void Kwave::ChannelMixer::input ( Kwave::SampleArray  data)
inlineslot

dummy implementation, the real "input" is a multi-track slot and available through the port(...) interface only

Definition at line 98 of file ChannelMixer.h.

Referenced by mix(), port(), and tracksOfPort().

98 { Q_UNUSED(data); }
Here is the caller graph for this function:

◆ mix()

void Kwave::ChannelMixer::mix ( )
privatevirtual

does the calculation

Definition at line 191 of file ChannelMixer.cpp.

References Kwave::SampleArray::constData(), Kwave::SampleBuffer::constData(), Kwave::SampleBuffer::data(), Kwave::SampleArray::data(), Kwave::SampleBuffer::finished(), input(), m_input_queue, m_inputs, m_matrix, m_output_buffer, m_outputs, output(), Kwave::SampleArray::resize(), and Kwave::SampleArray::size().

Referenced by idxInput().

192 {
193  Q_ASSERT(m_matrix);
194 
195  // all inputs should contain a buffer, dequeue them into a vector
196  // and form an array of pointers to the raw data, for speeding up
197  QVector<Kwave::SampleArray> v_input(m_inputs);
198  QVarLengthArray<const sample_t *> input(m_inputs);
199  unsigned int min_len = UINT_MAX;
200  for (unsigned int track = 0; track < m_inputs; track++) {
201  // dequeue the buffer with input data
202  QQueue<Kwave::SampleArray> &queue = m_input_queue[track];
203  Q_ASSERT(!queue.isEmpty());
204  Kwave::SampleArray buffer = queue.dequeue();
205  v_input[track] = buffer;
206 
207  // get a pointer for quick access
208  const sample_t *raw_data = v_input[track].constData();
209  input[track] = raw_data;
210 
211  // detect minimum input length
212  min_len = qMin(min_len, buffer.size());
213  }
214  Q_ASSERT(min_len);
215  if (!min_len) return; // zero length buffer in the queue, data underrun?
216 
217  // make sure all output buffers are large enough
218  // and build an array of pointers to the raw data, for speeding up
219  QVarLengthArray<sample_t *> output(m_outputs);
220  for (unsigned int track = 0; track < m_outputs; track++) {
221  Kwave::SampleBuffer *buffer = m_output_buffer[track];
222  Q_ASSERT(buffer);
223  if (!buffer) return;
224  bool ok = true;
225  if (buffer->constData().size() < min_len)
226  ok &= buffer->data().resize(min_len);
227  if (!ok) {
228  qWarning("ChannelMixer: failed to increase buffer size to %u",
229  min_len);
230  return; // OOM ?
231  }
232  output[track] = buffer->data().data();
233  }
234 
235  // mix all channels together, using the mixer matrix
236  for (unsigned int y = 0; y < m_outputs; y++) {
237  sample_t *out = output[y];
238  for (unsigned int pos = 0; pos < min_len; pos++) {
239  double sum = 0.0;
240  for (unsigned int x = 0; x < m_inputs; x++) {
241  const double f = (*m_matrix)[x][y];
242  const double i = static_cast<double>(input[x][pos]);
243  sum += (f * i);
244  }
245  out[pos] = static_cast<sample_t>(sum);
246  }
247 
248  // emit the output
249  Kwave::SampleBuffer *out_buf = m_output_buffer[y];
250  if (Q_UNLIKELY(out_buf->constData().size() > min_len)) {
251  bool ok = out_buf->data().resize(min_len);
252  Q_ASSERT(ok);
253  Q_UNUSED(ok);
254  }
255  out_buf->finished();
256  }
257 
258 }
virtual Kwave::SampleArray & data()
Kwave::MixerMatrix * m_matrix
Definition: ChannelMixer.h:113
virtual const Kwave::SampleArray & constData() const
unsigned int m_inputs
Definition: ChannelMixer.h:116
void output(Kwave::SampleArray data)
unsigned int m_outputs
Definition: ChannelMixer.h:119
virtual void finished()
const sample_t * constData() const
Definition: SampleArray.h:54
unsigned int size() const
void input(Kwave::SampleArray data)
Definition: ChannelMixer.h:98
sample_t * data()
Definition: SampleArray.h:62
QVector< QPointer< Kwave::SampleBuffer > > m_output_buffer
Definition: ChannelMixer.h:127
bool resize(unsigned int size) Q_REQUIRED_RESULT
QVector< QQueue< Kwave::SampleArray > > m_input_queue
Definition: ChannelMixer.h:124
qint32 sample_t
Definition: Sample.h:37
Here is the call graph for this function:
Here is the caller graph for this function:

◆ output

void Kwave::ChannelMixer::output ( Kwave::SampleArray  data)
signal

emits a block with output data

Referenced by init(), mix(), port(), and tracksOfPort().

Here is the caller graph for this function:

◆ port()

Kwave::StreamObject * Kwave::ChannelMixer::port ( const char *  port,
unsigned int  track 
)
virtual

Returns an indexed port, identified by name

Parameters
portname of the port (name of signal or slot)
trackindex of the track

Reimplemented from Kwave::StreamObject.

Definition at line 140 of file ChannelMixer.cpp.

References _sig(), idxInput(), input(), m_indexer, m_lock, m_output_buffer, output(), and Kwave::toInt().

142 {
143  Kwave::StreamObject *retval = Q_NULLPTR;
144  QMutexLocker _lock(&m_lock);
145 
146  if (_sig(port) == _sig(SLOT(input(Kwave::SampleArray)))) {
147  // input proxy
148  Q_ASSERT(Kwave::toInt(track) < m_indexer.count());
149  if (Kwave::toInt(track) >= m_indexer.count()) return Q_NULLPTR;
150  retval = m_indexer.at(track);
151  } else if (_sig(port) == _sig(SIGNAL(output(Kwave::SampleArray)))) {
152  // output proxy
153  Q_ASSERT(Kwave::toInt(track) < m_output_buffer.count());
154  if (Kwave::toInt(track) >= m_output_buffer.count()) return Q_NULLPTR;
155  retval = m_output_buffer[track];
156  } else if (_sig(port) ==
157  _sig(SLOT(idxInput(uint,Kwave::SampleArray)))) {
158  retval = this;
159  } else {
160  qFatal("unknown port");
161  }
162 
163  return retval;
164 }
virtual Kwave::StreamObject * port(const char *port, unsigned int track) Q_DECL_OVERRIDE
void output(Kwave::SampleArray data)
QVector< QPointer< Kwave::StreamObject > > m_indexer
Definition: ChannelMixer.h:121
int toInt(T x)
Definition: Utils.h:127
void idxInput(unsigned int index, Kwave::SampleArray data)
static QByteArray _sig(const char *sig)
void input(Kwave::SampleArray data)
Definition: ChannelMixer.h:98
QVector< QPointer< Kwave::SampleBuffer > > m_output_buffer
Definition: ChannelMixer.h:127
Here is the call graph for this function:

◆ tracksOfPort()

unsigned int Kwave::ChannelMixer::tracksOfPort ( const char *  port) const
virtual

Returns the number of tracks of a input or output port. Can be overwritten for objects that have a different count of inputs and outputs.

Parameters
portname of the port (name of signal or slot)
Returns
number of tracks of a input or output, default is the same as tracks()

Reimplemented from Kwave::StreamObject.

Definition at line 118 of file ChannelMixer.cpp.

References _sig(), idxInput(), input(), m_inputs, m_lock, m_outputs, and output().

119 {
120  unsigned int retval = 0;
121  QMutexLocker _lock(const_cast<QMutex *>(&m_lock));
122 
123  if (_sig(port) == _sig(SLOT(input(Kwave::SampleArray)))) {
124  // input ports
125  retval = m_inputs; // init is done
126  } else if (_sig(port) == _sig(SIGNAL(output(Kwave::SampleArray)))) {
127  // output ports
128  retval = m_outputs;
129  } else if (_sig(port) ==
130  _sig(SLOT(idxInput(uint,Kwave::SampleArray)))) {
131  retval = 1;
132  } else {
133  qFatal("unknown port");
134  }
135 
136  return retval;
137 }
virtual Kwave::StreamObject * port(const char *port, unsigned int track) Q_DECL_OVERRIDE
unsigned int m_inputs
Definition: ChannelMixer.h:116
void output(Kwave::SampleArray data)
unsigned int m_outputs
Definition: ChannelMixer.h:119
void idxInput(unsigned int index, Kwave::SampleArray data)
static QByteArray _sig(const char *sig)
void input(Kwave::SampleArray data)
Definition: ChannelMixer.h:98
Here is the call graph for this function:

Member Data Documentation

◆ m_indexer

QVector< QPointer<Kwave::StreamObject> > Kwave::ChannelMixer::m_indexer
private

Definition at line 121 of file ChannelMixer.h.

Referenced by init(), port(), and ~ChannelMixer().

◆ m_input_queue

QVector< QQueue<Kwave::SampleArray> > Kwave::ChannelMixer::m_input_queue
private

queues for input data

Definition at line 124 of file ChannelMixer.h.

Referenced by idxInput(), init(), mix(), and ~ChannelMixer().

◆ m_inputs

unsigned int Kwave::ChannelMixer::m_inputs
private

number of inputs

Definition at line 116 of file ChannelMixer.h.

Referenced by idxInput(), init(), mix(), and tracksOfPort().

◆ m_lock

QMutex Kwave::ChannelMixer::m_lock
private

mutex for locking access to the queues

Definition at line 130 of file ChannelMixer.h.

Referenced by idxInput(), port(), tracksOfPort(), and ~ChannelMixer().

◆ m_matrix

Kwave::MixerMatrix* Kwave::ChannelMixer::m_matrix
private

mixer matrix

Definition at line 113 of file ChannelMixer.h.

Referenced by idxInput(), init(), and mix().

◆ m_output_buffer

QVector< QPointer<Kwave::SampleBuffer> > Kwave::ChannelMixer::m_output_buffer
private

buffers with output data

Definition at line 127 of file ChannelMixer.h.

Referenced by init(), mix(), port(), and ~ChannelMixer().

◆ m_outputs

unsigned int Kwave::ChannelMixer::m_outputs
private

number of outputs

Definition at line 119 of file ChannelMixer.h.

Referenced by init(), mix(), and tracksOfPort().


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