kwave  18.07.70
Filter.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  Filter.cpp - parameters of a digital IIR or FIR filter
3  -------------------
4  begin : Jan 20 2001
5  copyright : (C) 2001 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 #include "config.h"
19 
20 #include <QFile>
21 #include <QLatin1Char>
22 #include <QString>
23 #include <QTextStream>
24 
25 #include "libkwave/Filter.h"
26 #include "libkwave/Parser.h"
27 #include "libkwave/String.h"
28 #include "libkwave/Utils.h"
29 
30 //***************************************************************************
31 Kwave::Filter::Filter(const QString &command)
32  :m_fir(true), m_rate(0), m_coeff(), m_delay()
33 {
34  Kwave::Parser parse(command);
35 
36  m_rate = parse.toInt();
37  m_fir = (parse.nextParam().toLower() == _("fir"));
38  resize(parse.toInt());
39 
40  for (unsigned int i = 0; i < count(); i++) {
41  m_delay[i] = parse.toInt();
42  m_coeff[i] = parse.toDouble();
43  }
44 }
45 
46 //***************************************************************************
48  :m_fir(true), m_rate(rate), m_coeff(), m_delay()
49 {
50 }
51 
52 //***************************************************************************
54 {
55  resize(0);
56 }
57 
58 //***************************************************************************
60 {
61  QString s;
62 
63  s = _("filter (");
64  s += QString::number(m_rate);
65  s += QLatin1Char(',');
66  s += _((m_fir) ? "fir" : "iir");
67  s += QLatin1Char(',') + QString::number(count());
68 
69  for (unsigned int i = 0; i < count(); i++) {
70  s += QLatin1Char(',');
71  s += QString::number(m_delay[i]);
72  s += QLatin1Char(',');
73  s += QString::number(m_coeff[i]);
74  }
75  return s;
76 }
77 
78 //***************************************************************************
79 unsigned int Kwave::Filter::resize(unsigned int newnum)
80 {
81  unsigned int oldnum = count();
82  if (newnum == oldnum) return oldnum; // nothing to do
83 
84  // resize both arrays
85  m_delay.resize(newnum);
86  m_coeff.resize(newnum);
87  Q_ASSERT(m_delay.size() >= Kwave::toInt(newnum));
88  Q_ASSERT(m_coeff.size() >= Kwave::toInt(newnum));
89  Q_ASSERT(m_delay.size() == m_coeff.size());
90 
91  // initialize the new entries
92  while (oldnum < newnum) {
93  m_delay[oldnum] = oldnum;
94  m_coeff[oldnum] = 0.0;
95  oldnum++;
96  }
97 
98  return newnum;
99 }
100 
101 //***************************************************************************
102 unsigned int Kwave::Filter::count()
103 {
104  Q_ASSERT(m_coeff.count() == m_delay.count());
105  return m_coeff.count();
106 }
107 
108 //***************************************************************************
109 double Kwave::Filter::coeff(unsigned int index)
110 {
111  Q_ASSERT(Kwave::toInt(index) < m_coeff.count());
112  return m_coeff[index];
113 }
114 
115 //***************************************************************************
116 void Kwave::Filter::setCoeff(unsigned int index, double newval)
117 {
118  Q_ASSERT(Kwave::toInt(index) < m_coeff.count());
119  m_coeff[index] = newval;
120 }
121 
122 //***************************************************************************
123 unsigned int Kwave::Filter::delay(unsigned int index)
124 {
125  Q_ASSERT(Kwave::toInt(index) < m_delay.count());
126  return m_delay[index];
127 }
128 
129 //***************************************************************************
130 void Kwave::Filter::setDelay(unsigned int index, unsigned int newval)
131 {
132  Q_ASSERT(Kwave::toInt(index) < m_delay.count());
133  m_delay[index] = newval;
134 }
135 
136 //***************************************************************************
137 void Kwave::Filter::save(const QString &filename)
138 {
139  QString name(filename);
140  Q_ASSERT(name.length());
141  if (!name.length()) return;
142 
143  if (name.lastIndexOf(_(".filter")) != Kwave::toInt(name.length() - 7))
144  name.append(_(".filter"));
145 
146  QFile file(name);
147  file.open(QIODevice::WriteOnly);
148  QTextStream out(&file);
149 
150  out << ((m_fir) ? "FIR " : "IIR ") << count() << endl;
151  for (unsigned int i = 0; i < count(); i++) {
152  out << m_delay[i] << ' ' << m_coeff[i] << endl;
153  }
154 
155  file.close();
156 }
157 
158 //***************************************************************************
159 void Kwave::Filter::load(const QString &filename)
160 {
161  unsigned int i;
162  bool ok;
163  QString line;
164  unsigned int linenr = 0;
165 
166  QFile file(filename);
167  file.open(QIODevice::ReadOnly);
168  QTextStream in(&file);
169 
170  // type of the filter (FIR/IIR)
171  while (!in.atEnd()) {
172  line = in.readLine().simplified();
173  linenr++;
174 
175  if (line.isEmpty() || line.isNull()) continue;
176  if ((line[0] == QLatin1Char('#')) || (line[0] == QLatin1Char('/')))
177  continue;
178  break;
179  }
180  m_fir = line.startsWith(_("FIR "));
181  qDebug("Filter::load(): fir = %d", m_fir);
182 
183  // order
184  unsigned int order = line.remove(0,4).toUInt(&ok);
185  resize(0);
186  resize(order);
187  qDebug("Filter::load(): order = %d", order);
188 
189  // read delays and coefficients
190  i = 0;
191  while (!in.atEnd()) {
192  line = in.readLine().simplified();
193  linenr++;
194 
195  if (line.isEmpty() || line.isNull()) continue;
196  if ((line[0] == QLatin1Char('#')) || (line[0] == QLatin1Char('/')))
197  continue;
198 
199  int spacepos = line.indexOf(QLatin1Char(' '));
200  ok = true;
201  if (ok) m_delay[i] = line.left(spacepos).toUInt(&ok);
202  line.remove(0, spacepos);
203  if (ok) m_coeff[i] = line.toDouble(&ok);
204 
205  if (ok) {
206  i++;
207  } else {
208  qDebug("Filter::load(%s): syntax error in line %d",
209  DBG(filename), linenr);
210  }
211  }
212 }
213 
214 //***************************************************************************
215 //***************************************************************************
QVector< double > m_coeff
Definition: Filter.h:120
double coeff(unsigned int index)
Definition: Filter.cpp:109
bool m_fir
Definition: Filter.h:114
int toInt()
Definition: Parser.cpp:216
int rate() const
Definition: Filter.h:71
const char name[16]
Definition: memcpy.c:510
unsigned int count()
Definition: Filter.cpp:102
unsigned int delay(unsigned int index)
Definition: Filter.cpp:123
int toInt(T x)
Definition: Utils.h:127
Filter(int rate)
Definition: Filter.cpp:47
void save(const QString &filename)
Definition: Filter.cpp:137
double toDouble()
Definition: Parser.cpp:262
void setDelay(unsigned int index, unsigned int newval)
Definition: Filter.cpp:130
unsigned int m_rate
Definition: Filter.h:117
#define _(m)
Definition: memcpy.c:66
#define DBG(qs)
Definition: String.h:55
QVector< int > m_delay
Definition: Filter.h:123
void load(const QString &filename)
Definition: Filter.cpp:159
unsigned int resize(unsigned int newnum)
Definition: Filter.cpp:79
virtual ~Filter()
Definition: Filter.cpp:53
void setCoeff(unsigned int index, double newval)
Definition: Filter.cpp:116
QString command()
Definition: Filter.cpp:59
const QString & nextParam()
Definition: Parser.cpp:175