kwave  18.07.70
Kwave::AsciiDecoder Class Reference

#include <AsciiDecoder.h>

Inheritance diagram for Kwave::AsciiDecoder:
Inheritance graph
Collaboration diagram for Kwave::AsciiDecoder:
Collaboration graph

Public Member Functions

 AsciiDecoder ()
 
virtual ~AsciiDecoder () Q_DECL_OVERRIDE
 
virtual Kwave::Decoderinstance () Q_DECL_OVERRIDE
 
virtual bool open (QWidget *widget, QIODevice &source) Q_DECL_OVERRIDE
 
virtual bool decode (QWidget *widget, Kwave::MultiWriter &dst) Q_DECL_OVERRIDE
 
virtual void close () Q_DECL_OVERRIDE
 
- Public Member Functions inherited from Kwave::Decoder
 Decoder ()
 
virtual ~Decoder ()
 
virtual Kwave::MetaDataListmetaData ()
 
- Public Member Functions inherited from Kwave::CodecBase
 CodecBase ()
 
virtual ~CodecBase ()
 
virtual bool supports (const QMimeType &mimetype)
 
virtual bool supports (const QString &mimetype_name)
 
virtual QStringList extensions (const QString &mimetype_name) const
 
virtual const QList< CodecBase::MimeTypemimeTypes ()
 
virtual const QList< Kwave::Compression::TypecompressionTypes ()
 
virtual void addMimeType (const char *name, const QString &description, const char *patterns)
 
virtual void addCompression (Kwave::Compression::Type compression)
 
virtual QString mimeTypeOf (const QUrl &url)
 

Private Member Functions

bool readNextLine ()
 

Private Attributes

QTextStream m_source
 
Kwave::MultiWriterm_dest
 
QQueue< QString > m_queue_input
 
quint64 m_line_nr
 

Additional Inherited Members

- Signals inherited from Kwave::Decoder
void sourceProcessed (quint64 pos)
 
- Protected Attributes inherited from Kwave::Decoder
Kwave::MetaDataList m_meta_data
 

Detailed Description

Definition at line 35 of file AsciiDecoder.h.

Constructor & Destructor Documentation

◆ AsciiDecoder()

Kwave::AsciiDecoder::AsciiDecoder ( )

Constructor

Definition at line 44 of file AsciiDecoder.cpp.

References LOAD_MIME_TYPES, m_source, and REGISTER_COMPRESSION_TYPES.

45  :Kwave::Decoder(),
46  m_source(),
47  m_dest(Q_NULLPTR),
48  m_queue_input(),
49  m_line_nr(0)
50 {
53  m_source.setCodec("UTF-8");
54 }
#define LOAD_MIME_TYPES
QQueue< QString > m_queue_input
Definition: AsciiDecoder.h:90
QTextStream m_source
Definition: AsciiDecoder.h:84
Kwave::MultiWriter * m_dest
Definition: AsciiDecoder.h:87
#define REGISTER_COMPRESSION_TYPES

◆ ~AsciiDecoder()

Kwave::AsciiDecoder::~AsciiDecoder ( )
virtual

Destructor

Definition at line 57 of file AsciiDecoder.cpp.

References close(), and m_source.

58 {
59  if (m_source.device()) close();
60 }
virtual void close() Q_DECL_OVERRIDE
QTextStream m_source
Definition: AsciiDecoder.h:84
Here is the call graph for this function:

Member Function Documentation

◆ close()

void Kwave::AsciiDecoder::close ( )
virtual

Closes the source.

Implements Kwave::Decoder.

Definition at line 289 of file AsciiDecoder.cpp.

References m_source.

Referenced by ~AsciiDecoder().

290 {
291  m_source.reset();
292  m_source.setDevice(Q_NULLPTR);
293 }
QTextStream m_source
Definition: AsciiDecoder.h:84
Here is the caller graph for this function:

◆ decode()

bool Kwave::AsciiDecoder::decode ( QWidget *  widget,
Kwave::MultiWriter dst 
)
virtual

Decodes a stream of bytes into a MultiWriter

Parameters
widgeta widget that can be used for displaying message boxes or dialogs
dstMultiWriter that receives the audio data
Returns
true if succeeded, false on errors

Implements Kwave::Decoder.

Definition at line 235 of file AsciiDecoder.cpp.

References Kwave::MultiWriter::isCanceled(), Kwave::MultiWriter::last(), m_dest, m_queue_input, m_source, Kwave::Decoder::metaData(), readNextLine(), Kwave::MetaDataList::replace(), Kwave::FileInfo::setLength(), and Kwave::FileInfo::tracks().

237 {
238  Q_UNUSED(widget);
239 
240  Q_ASSERT(m_source.device());
241  if (!m_source.device()) return false;
242 
243  m_dest = &dst;
244 
245  // for the moment: use a comma as separator <= TODO
246  const char separators[] = {',', '\0' };
247 
248  Kwave::FileInfo info(metaData());
249  unsigned int channels = info.tracks();
250  QVector<sample_t> frame(channels);
251 
252  // read in all remaining data until EOF or user cancel
253  qDebug("AsciiDecoder::decode(...)");
254  while (readNextLine() && !dst.isCanceled()) {
255  QByteArray d = m_queue_input.dequeue().toLatin1();
256  char *line = d.data();
257  char *saveptr = Q_NULLPTR;
258 
259  frame.fill(0);
260  for (unsigned int channel = 0; channel < channels; channel++) {
261  sample_t s = 0;
262 
263  char *token = strtok_r(line, separators, &saveptr);
264  line = Q_NULLPTR;
265  if (token) {
266  // skip whitespace at the start
267  while (*token && isspace(*token)) ++token;
268  if (*token) {
269  char *p = token + 1;
270  while (isdigit(*p) || (*p == '+') || (*p == '-')) ++p;
271  *p = 0;
272  if (*token) s = atoi(token);
273  Kwave::Writer *w = dst[channel];
274  if (w) (*w) << s;
275  }
276  }
277  }
278  }
279 
280  m_dest = Q_NULLPTR;
281  info.setLength(dst.last() ? (dst.last() + 1) : 0);
283 
284  // return with a valid Signal, even if the user pressed cancel !
285  return true;
286 }
virtual sample_index_t last() const
Definition: MultiWriter.cpp:85
QQueue< QString > m_queue_input
Definition: AsciiDecoder.h:90
virtual void replace(const MetaDataList &list)
virtual Kwave::MetaDataList & metaData()
Definition: Decoder.h:78
bool isCanceled() const
Definition: MultiWriter.h:64
QTextStream m_source
Definition: AsciiDecoder.h:84
Kwave::MultiWriter * m_dest
Definition: AsciiDecoder.h:87
qint32 sample_t
Definition: Sample.h:37
Here is the call graph for this function:

◆ instance()

Kwave::Decoder * Kwave::AsciiDecoder::instance ( )
virtual

Returns a new instance of the decoder

Implements Kwave::Decoder.

Definition at line 63 of file AsciiDecoder.cpp.

64 {
65  return new Kwave::AsciiDecoder();
66 }

◆ open()

bool Kwave::AsciiDecoder::open ( QWidget *  widget,
QIODevice &  source 
)
virtual

Opens the source and decodes the header information.

Parameters
widgeta widget that can be used for displaying message boxes or dialogs
sourcefile or other source with a stream of bytes
Returns
true if succeeded, false on errors

Implements Kwave::Decoder.

Definition at line 69 of file AsciiDecoder.cpp.

References _, Kwave::MetaDataList::add(), Kwave::FileInfo::allKnownProperties(), Kwave::FileInfo::contains(), DBG, Kwave::FileInfo::get(), Kwave::INF_BITS_PER_SAMPLE, Kwave::INF_CHANNELS, Kwave::INF_SAMPLE_RATE, Kwave::INF_TRACK, Kwave::INF_TRACKS, m_line_nr, m_queue_input, m_source, MAX_LINE_LEN, Kwave::Decoder::metaData(), Kwave::FileInfo::name(), name, Kwave::MetaDataList::replace(), Kwave::FileInfo::set(), Kwave::LabelList::toMetaDataList(), Kwave::FileInfo::tracks(), and Kwave::Parser::unescape().

70 {
71  Q_UNUSED(widget);
72 
73  metaData().clear();
74  Q_ASSERT(!m_source.device());
75  if (m_source.device()) qWarning("AsciiDecoder::open(), already open !");
76 
77  // try to open the source
78  if (!src.open(QIODevice::ReadOnly)) {
79  qWarning("failed to open source !");
80  return false;
81  }
82 
83  // take over the source
84  m_source.setDevice(&src);
85 
86  Kwave::FileInfo info(metaData());
87  Kwave::LabelList labels;
88 
89  /********** Decoder setup ************/
90  qDebug("--- AsciiDecoder::open() ---");
91 
92  // read in all metadata until start of samples, EOF or user cancel
93  qDebug("AsciiDecoder::open(...)");
94 
95  m_line_nr = 0;
96  while (!m_source.atEnd()) {
97  QString line = m_source.readLine(MAX_LINE_LEN).simplified();
98  m_line_nr++;
99  if (!line.length())
100  continue; // skip empty line
101 
102  QRegExp regex(_(
103  "(^##\\s*)" // 1 start of meta data line
104  "([\\'\\\"])?" // 2 property, quote start (' or ")
105  "\\s*(\\w+[\\s\\w]*\\w)\\s*" // 3 property
106  "(\\[\\d*\\])?" // 4 index (optional)
107  "(\\2)" // 5 property, quote end
108  "(\\s*=\\s*)" // 6 assignment '='
109  "(.*)" // 7 rest, up to end of line
110  ));
111  if (regex.exactMatch(line)) {
112  // meta data entry: "## 'Name' = value"
113  QString name = Kwave::Parser::unescape(regex.cap(3) + regex.cap(4));
114  QString v = regex.cap(7);
115 
116  QString value;
117  if (v.length()) {
118  // remove quotes from the value
119  bool is_escaped = false;
120  char quote = v[0].toLatin1();
121  if ((quote != '\'') && (quote != '"'))
122  quote = -1;
123 
124  for (QString::ConstIterator it = v.begin(); it != v.end(); ++it)
125  {
126  const char c = QChar(*it).toLatin1();
127 
128  if ((c == '\\') && !is_escaped) {
129  is_escaped = true; // next char is escaped
130  continue;
131  }
132  if (is_escaped) {
133  value += *it; // escaped char
134  is_escaped = false;
135  continue;
136  }
137 
138  if (c == quote) {
139  if (!value.length())
140  continue; // starting quote
141  else
142  break; // ending quote
143  }
144 
145  if ((quote == -1) && (c == '#'))
146  break; // comment in unquoted text
147 
148  // otherwise: normal character, part of text
149  value += *it;
150  }
151 
152  // if the text was unquoted, remove leading/trailing spaces
153  if (quote == -1)
154  value = value.trimmed();
155  }
156 
157  // handle some well known aliases
158  if (name == _("rate")) name = info.name(INF_SAMPLE_RATE);
159  if (name == _("bits")) name = info.name(INF_BITS_PER_SAMPLE);
160 
161  // handle labels
162  QRegExp regex_label(_("label\\[(\\d*)\\]"));
163  if (regex_label.exactMatch(name)) {
164  bool ok = false;
165  sample_index_t pos = regex_label.cap(1).toULongLong(&ok);
166  if (!ok) {
167  qWarning("line %llu: malformed label position: '%s'",
168  m_line_nr, DBG(name));
169  continue; // skip it
170  }
171  Kwave::Label label(pos, value);
172  labels.append(label);
173  continue;
174  }
175 
176  bool found = false;
177  foreach (const Kwave::FileProperty &p, info.allKnownProperties()) {
178  if (info.name(p).toLower() == name.toLower()) {
179  found = true;
180  info.set(p, QVariant(value));
181  }
182  }
183  if (!found) {
184  qWarning("line %llu: unknown meta data entry: '%s' = '%s'",
185  m_line_nr, DBG(name), DBG(value));
186  }
187  } else if (line.startsWith(QLatin1Char('#'))) {
188  continue; // skip comment lines
189  } else {
190  // reached end of metadata:
191  // -> push back the line into the queue
192  m_queue_input.enqueue(line);
193  break;
194  }
195  }
196 
197  // if the number of channels is not known, but "tracks" is given and
198  // "track" is not present: old syntax has been used
199  if ((info.tracks() < 1) && info.contains(INF_TRACKS) &&
200  !info.contains(INF_TRACK))
201  {
202  info.set(INF_CHANNELS, info.get(INF_TRACKS));
203  info.set(INF_TRACKS, QVariant());
204  }
205 
207  metaData().add(labels.toMetaDataList());
208 
209  return (info.tracks() >= 1);
210 }
quint64 sample_index_t
Definition: Sample.h:28
virtual void add(const MetaData &metadata)
const char name[16]
Definition: memcpy.c:510
static QString unescape(const QString &text)
Definition: Parser.cpp:314
QQueue< QString > m_queue_input
Definition: AsciiDecoder.h:90
virtual void replace(const MetaDataList &list)
virtual Kwave::MetaDataList & metaData()
Definition: Decoder.h:78
Kwave::MetaDataList toMetaDataList() const
Definition: LabelList.cpp:71
QTextStream m_source
Definition: AsciiDecoder.h:84
#define _(m)
Definition: memcpy.c:66
#define DBG(qs)
Definition: String.h:55
#define MAX_LINE_LEN
FileProperty
Definition: FileInfo.h:45
Here is the call graph for this function:

◆ readNextLine()

bool Kwave::AsciiDecoder::readNextLine ( )
private

try to read a complete line from the source, skip empty lines and comments

Returns
true if one line was read, false if EOF was reached before one line was complete

Definition at line 213 of file AsciiDecoder.cpp.

References m_line_nr, m_queue_input, m_source, and MAX_LINE_LEN.

Referenced by decode().

214 {
215  if (!m_queue_input.isEmpty())
216  return true; // there is still something in the queue
217 
218  while (!m_source.atEnd()) {
219  QString line = m_source.readLine(MAX_LINE_LEN).simplified();
220  m_line_nr++;
221  if (!line.length()) {
222  continue; // skip empty line
223  } else if (line.startsWith(QLatin1Char('#'))) {
224  continue; // skip comment lines
225  } else {
226  // -> push back the line into the queue
227  m_queue_input.enqueue(line);
228  return true;
229  }
230  }
231  return false;
232 }
QQueue< QString > m_queue_input
Definition: AsciiDecoder.h:90
QTextStream m_source
Definition: AsciiDecoder.h:84
#define MAX_LINE_LEN
Here is the caller graph for this function:

Member Data Documentation

◆ m_dest

Kwave::MultiWriter* Kwave::AsciiDecoder::m_dest
private

destination of the audio data

Definition at line 87 of file AsciiDecoder.h.

Referenced by decode().

◆ m_line_nr

quint64 Kwave::AsciiDecoder::m_line_nr
private

last read line number, starting with 1

Definition at line 93 of file AsciiDecoder.h.

Referenced by open(), and readNextLine().

◆ m_queue_input

QQueue<QString> Kwave::AsciiDecoder::m_queue_input
private

queue for buffering strings read from the file

Definition at line 90 of file AsciiDecoder.h.

Referenced by decode(), open(), and readNextLine().

◆ m_source

QTextStream Kwave::AsciiDecoder::m_source
private

source of the audio data

Definition at line 84 of file AsciiDecoder.h.

Referenced by AsciiDecoder(), close(), decode(), open(), readNextLine(), and ~AsciiDecoder().


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