kwave  18.07.70
Kwave::RateConverter Class Reference

#include <RateConverter.h>

Inheritance diagram for Kwave::RateConverter:
Inheritance graph
Collaboration diagram for Kwave::RateConverter:
Collaboration graph

Public Slots

void input (Kwave::SampleArray data)
 
void setRatio (const QVariant r)
 

Signals

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

Public Member Functions

 RateConverter ()
 
virtual ~RateConverter () 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 tracksOfPort (const char *port) const
 
virtual Kwave::StreamObjectport (const char *port, unsigned int track)
 
virtual unsigned int blockSize () const
 
void setAttribute (const char *attribute, const QVariant &value)
 

Private Attributes

double m_ratio
 
SRC_STATE * m_converter
 
QVarLengthArray< float, 65536 > m_converter_in
 
QVarLengthArray< float, 65536 > m_converter_out
 

Additional Inherited Members

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

Detailed Description

Definition at line 36 of file RateConverter.h.

Constructor & Destructor Documentation

◆ RateConverter()

Kwave::RateConverter::RateConverter ( )

Constructor

Definition at line 26 of file RateConverter.cpp.

References m_converter.

27  :Kwave::SampleSource(), m_ratio(1.0), m_converter(Q_NULLPTR),
29 {
30  int error = 0;
31  m_converter = src_new(SRC_SINC_MEDIUM_QUALITY, 1, &error);
32  Q_ASSERT(m_converter);
33  if (!m_converter) qWarning("creating converter failed: '%s",
34  src_strerror(error));
35 }
SRC_STATE * m_converter
Definition: RateConverter.h:71
QVarLengthArray< float, 65536 > m_converter_out
Definition: RateConverter.h:77
QVarLengthArray< float, 65536 > m_converter_in
Definition: RateConverter.h:74

◆ ~RateConverter()

Kwave::RateConverter::~RateConverter ( )
virtual

Destructor

Definition at line 38 of file RateConverter.cpp.

References m_converter.

39 {
40  if (m_converter) src_delete(m_converter);
41 }
SRC_STATE * m_converter
Definition: RateConverter.h:71

Member Function Documentation

◆ goOn()

void Kwave::RateConverter::goOn ( )
virtual

does nothing, processing is done in input()

Implements Kwave::SampleSource.

Definition at line 44 of file RateConverter.cpp.

45 {
46 }

◆ input

void Kwave::RateConverter::input ( Kwave::SampleArray  data)
slot

receives input data and also directly does the calculation

Definition at line 49 of file RateConverter.cpp.

References Kwave::SampleArray::constData(), Kwave::SampleArray::data(), float2sample(), Kwave::SampleArray::isEmpty(), m_converter, m_converter_in, m_converter_out, m_ratio, output(), sample2float(), Kwave::SampleArray::size(), and Kwave::toUint().

50 {
51  // shortcut for ratio == 1:1
52  if ((m_ratio == 1.0) || data.isEmpty()) {
53  emit output(data);
54  return;
55  }
56 
57  // normal processing
58  Kwave::SampleArray samples_out;
59  const unsigned int in_len = data.size();
60 
61  // convert the input buffer into an array of floats
62  m_converter_in.resize(in_len);
63  float *f_in = m_converter_in.data();
64  const sample_t *s_in = data.constData();
65  Q_ASSERT(f_in);
66  Q_ASSERT(s_in);
67 
68  // work blockwise to allow loop unrolling
69  unsigned int remaining = in_len;
70  const unsigned int block_size = 16;
71  while (remaining >= block_size) {
72  for (unsigned int i = 0; i < block_size; i++)
73  f_in[i] = sample2float(s_in[i]);
74  f_in += block_size;
75  s_in += block_size;
76  remaining -= block_size;
77  }
78  for (; remaining; remaining--)
79  (*f_in++) = sample2float(*(s_in++));
80 
81  // prepare the output buffer (estimated size, rounded up)
82  // worst case would be factor 2, which means that there was a 100%
83  // leftover remaining from the previous pass
84  // just for safety we limit the extra output space to some
85  // (hopefully) reasonable range between 4096 and 16384
86  const unsigned int out_len = Kwave::toUint(
87  ceil(static_cast<double>(in_len) * m_ratio)
88  );
89  const unsigned int extra = qBound<unsigned int>(4096, out_len, 16384);
90  m_converter_out.resize(out_len + extra);
91 
92  // set up the sample rate converter input
93  SRC_DATA src;
94  src.data_in = m_converter_in.data();
95  src.data_out = m_converter_out.data();
96  src.input_frames = in_len;
97  src.output_frames = out_len + extra;
98  src.input_frames_used = 0;
99  src.output_frames_gen = 0;
100  src.end_of_input = (in_len == 0) ? 1 : 0;
101  src.src_ratio = m_ratio;
102 
103  // let the converter run...
104  int error = src_process(m_converter, &src);
105  if (error) qWarning("SRC error: '%s'", src_strerror(error));
106  Q_ASSERT(!error);
107 
108  // convert the result back from floats to sample_t
109  unsigned int gen = Kwave::toUint(src.output_frames_gen);
110  Kwave::SampleArray out(gen);
111  const float *f_out = src.data_out;
112  sample_t *s_out = out.data();
113 
114  // work blockwise to allow loop unrolling
115  remaining = gen;
116  while (remaining >= block_size) {
117  for (unsigned int i = 0; i < block_size; ++i)
118  s_out[i] = float2sample(f_out[i]);
119  s_out += block_size;
120  f_out += block_size;
121  remaining -= block_size;
122  }
123  for (; remaining; remaining--, ++s_out, ++f_out)
124  *s_out = float2sample(*f_out);
125 
126  emit output(out);
127 }
SRC_STATE * m_converter
Definition: RateConverter.h:71
QVarLengthArray< float, 65536 > m_converter_out
Definition: RateConverter.h:77
QVarLengthArray< float, 65536 > m_converter_in
Definition: RateConverter.h:74
void output(Kwave::SampleArray data)
bool isEmpty() const
Definition: SampleArray.h:118
static float sample2float(const sample_t s)
Definition: Sample.h:65
const sample_t * constData() const
Definition: SampleArray.h:54
unsigned int size() const
unsigned int toUint(T x)
Definition: Utils.h:109
static sample_t float2sample(const float f)
Definition: Sample.h:57
qint32 sample_t
Definition: Sample.h:37
Here is the call graph for this function:

◆ output

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

emits a block with the filtered data

Referenced by input().

Here is the caller graph for this function:

◆ setRatio

void Kwave::RateConverter::setRatio ( const QVariant  r)
slot

Sets the conversion ratio, ((new rate) / (old rate))

Definition at line 130 of file RateConverter.cpp.

References m_ratio.

131 {
132  m_ratio = QVariant(ratio).toDouble();
133 }

Member Data Documentation

◆ m_converter

SRC_STATE* Kwave::RateConverter::m_converter
private

sample rate converter context for libsamplerate

Definition at line 71 of file RateConverter.h.

Referenced by input(), RateConverter(), and ~RateConverter().

◆ m_converter_in

QVarLengthArray<float, 65536> Kwave::RateConverter::m_converter_in
private

input values for the sample rate converter

Definition at line 74 of file RateConverter.h.

Referenced by input().

◆ m_converter_out

QVarLengthArray<float, 65536> Kwave::RateConverter::m_converter_out
private

output values for the sample rate converter

Definition at line 77 of file RateConverter.h.

Referenced by input().

◆ m_ratio

double Kwave::RateConverter::m_ratio
private

conversion ratio, ((new rate) / (old rate))

Definition at line 68 of file RateConverter.h.

Referenced by input(), and setRatio().


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