kwave  18.07.70
Kwave::FlacDecoder Class Reference

#include <FlacDecoder.h>

Inheritance diagram for Kwave::FlacDecoder:
Inheritance graph
Collaboration diagram for Kwave::FlacDecoder:
Collaboration graph

Public Member Functions

 FlacDecoder ()
 
virtual ~FlacDecoder () 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)
 

Protected Member Functions

void parseStreamInfo (const FLAC::Metadata::StreamInfo &stream_info)
 
void parseVorbisComments (const FLAC::Metadata::VorbisComment &vorbis_comments)
 
virtual ::FLAC__StreamDecoderReadStatus read_callback (FLAC__byte buffer[], size_t *bytes) Q_DECL_OVERRIDE
 
virtual ::FLAC__StreamDecoderWriteStatus write_callback (const ::FLAC__Frame *frame, const FLAC__int32 *const buffer[]) Q_DECL_OVERRIDE
 
virtual void metadata_callback (const ::FLAC__StreamMetadata *metadata) Q_DECL_OVERRIDE
 
virtual void error_callback (::FLAC__StreamDecoderErrorStatus status) Q_DECL_OVERRIDE
 

Private Attributes

QIODevice * m_source
 
Kwave::MultiWriterm_dest
 
Kwave::VorbisCommentMap m_vorbis_comment_map
 

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 42 of file FlacDecoder.h.

Constructor & Destructor Documentation

◆ FlacDecoder()

Kwave::FlacDecoder::FlacDecoder ( )

Constructor

Definition at line 35 of file FlacDecoder.cpp.

References REGISTER_COMPRESSION_TYPES, and REGISTER_MIME_TYPES.

36  :Kwave::Decoder(),
37  FLAC::Decoder::Stream(),
38  m_source(Q_NULLPTR),
39  m_dest(Q_NULLPTR),
41 {
44 }
QIODevice * m_source
Definition: FlacDecoder.h:138
Kwave::MultiWriter * m_dest
Definition: FlacDecoder.h:141
Kwave::VorbisCommentMap m_vorbis_comment_map
Definition: FlacDecoder.h:144
#define REGISTER_MIME_TYPES
#define REGISTER_COMPRESSION_TYPES

◆ ~FlacDecoder()

Kwave::FlacDecoder::~FlacDecoder ( )
virtual

Destructor

Definition at line 47 of file FlacDecoder.cpp.

References close(), and m_source.

48 {
49  if (m_source) close();
50 }
QIODevice * m_source
Definition: FlacDecoder.h:138
virtual void close() Q_DECL_OVERRIDE
Here is the call graph for this function:

Member Function Documentation

◆ close()

void Kwave::FlacDecoder::close ( )
virtual

Closes the source.

Implements Kwave::Decoder.

Definition at line 326 of file FlacDecoder.cpp.

References m_source.

Referenced by ~FlacDecoder().

327 {
328  finish();
329  m_source = Q_NULLPTR;
330 }
QIODevice * m_source
Definition: FlacDecoder.h:138
Here is the caller graph for this function:

◆ decode()

bool Kwave::FlacDecoder::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 304 of file FlacDecoder.cpp.

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

306 {
307  Q_ASSERT(m_source);
308  if (!m_source) return false;
309 
310  m_dest = &dst;
311 
312  // read in all remaining data
313  qDebug("FlacDecoder::decode(...)");
314  process_until_end_of_stream();
315 
316  m_dest = Q_NULLPTR;
317  Kwave::FileInfo info(metaData());
318  info.setLength(dst.last() ? (dst.last() + 1) : 0);
320 
321  // return with a valid Signal, even if the user pressed cancel !
322  return true;
323 }
QIODevice * m_source
Definition: FlacDecoder.h:138
Kwave::MultiWriter * m_dest
Definition: FlacDecoder.h:141
virtual sample_index_t last() const
Definition: MultiWriter.cpp:85
virtual void replace(const MetaDataList &list)
virtual Kwave::MetaDataList & metaData()
Definition: Decoder.h:78
Here is the call graph for this function:

◆ error_callback()

void Kwave::FlacDecoder::error_callback ( ::FLAC__StreamDecoderErrorStatus  status)
protectedvirtual

FLAC decoder interface: error callback.

Parameters
statusthe FLAC status

Definition at line 250 of file FlacDecoder.cpp.

251 {
252  qDebug("FlacDecoder::error_callback: status=%d", status);
253 }

◆ instance()

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

Returns a new instance of the decoder

Implements Kwave::Decoder.

Definition at line 53 of file FlacDecoder.cpp.

54 {
55  return new Kwave::FlacDecoder();
56 }

◆ metadata_callback()

void Kwave::FlacDecoder::metadata_callback ( const ::FLAC__StreamMetadata *  metadata)
protectedvirtual

FLAC decoder interface: callback for processing meta data.

Parameters
metadatathe FLAC meta data to be parsed

Definition at line 212 of file FlacDecoder.cpp.

References parseStreamInfo(), and parseVorbisComments().

214 {
215  Q_ASSERT(metadata);
216  if (!metadata) return;
217 
218  switch (metadata->type) {
219  case FLAC__METADATA_TYPE_STREAMINFO: {
220  FLAC::Metadata::StreamInfo stream_info(
221  const_cast< ::FLAC__StreamMetadata * >(metadata), true);
222  parseStreamInfo(stream_info);
223  break;
224  }
225  case FLAC__METADATA_TYPE_PADDING:
226  // -> ignored
227  break;
228  case FLAC__METADATA_TYPE_APPLICATION:
229  qDebug("FLAC metadata: application data");
230  break;
231  case FLAC__METADATA_TYPE_SEEKTABLE:
232  qDebug("FLAC metadata: seektable - not supported yet");
233  break;
234  case FLAC__METADATA_TYPE_VORBIS_COMMENT: {
235  FLAC::Metadata::VorbisComment vorbis_comments(
236  const_cast< ::FLAC__StreamMetadata * >(metadata), true);
237  parseVorbisComments(vorbis_comments);
238  break;
239  }
240  case FLAC__METADATA_TYPE_CUESHEET:
241  qDebug("FLAC metadata: cuesheet - not supported yet");
242  break;
243  case FLAC__METADATA_TYPE_UNDEFINED:
244  default:
245  qDebug("FLAC metadata: unknown/undefined type");
246  }
247 }
void parseStreamInfo(const FLAC::Metadata::StreamInfo &stream_info)
void parseVorbisComments(const FLAC::Metadata::VorbisComment &vorbis_comments)
Here is the call graph for this function:

◆ open()

bool Kwave::FlacDecoder::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 256 of file FlacDecoder.cpp.

References _, DEFAULT_MIME_TYPE, Kwave::MessageBox::error(), Kwave::Compression::FLAC, Kwave::INF_COMPRESSION, Kwave::INF_MIMETYPE, m_source, Kwave::Decoder::metaData(), Kwave::MetaDataList::replace(), and Kwave::FileInfo::set().

257 {
258  metaData().clear();
259  Q_ASSERT(!m_source);
260  if (m_source) qWarning("FlacDecoder::open(), already open !");
261 
262  // try to open the source
263  if (!src.open(QIODevice::ReadOnly)) {
264  qWarning("failed to open source !");
265  return false;
266  }
267 
268  // take over the source
269  m_source = &src;
270 
271  /********** Decoder setup ************/
272  qDebug("--- FlacDecoder::open() ---");
273  set_metadata_respond_all();
274 
275  // initialize the stream
276  FLAC__StreamDecoderInitStatus init_state = init();
277  if (init_state > FLAC__STREAM_DECODER_INIT_STATUS_OK) {
278  Kwave::MessageBox::error(widget, i18n(
279  "Opening the FLAC bitstream failed."));
280  return false;
281  }
282 
283  // read in all metadata
284  process_until_end_of_metadata();
285 
286  FLAC::Decoder::Stream::State state = get_state();
287  if (state >= FLAC__STREAM_DECODER_END_OF_STREAM) {
288  Kwave::MessageBox::error(widget, i18n(
289  "Error while parsing the FLAC metadata. (%s)"),
290  _(state.as_cstring()));
291  return false;
292  }
293 
294  // set some more standard properties
295  Kwave::FileInfo info(metaData());
299 
300  return true;
301 }
QIODevice * m_source
Definition: FlacDecoder.h:138
static int error(QWidget *widget, QString message, QString caption=QString())
Definition: MessageBox.cpp:126
#define DEFAULT_MIME_TYPE
virtual void replace(const MetaDataList &list)
virtual Kwave::MetaDataList & metaData()
Definition: Decoder.h:78
#define _(m)
Definition: memcpy.c:66
Here is the call graph for this function:

◆ parseStreamInfo()

void Kwave::FlacDecoder::parseStreamInfo ( const FLAC::Metadata::StreamInfo &  stream_info)
protected

Parse information about the stream, like sample rate, resolution, channels etc...

Parameters
stream_infoFLAC metadata with stream information

Definition at line 141 of file FlacDecoder.cpp.

References Kwave::Decoder::metaData(), and Kwave::MetaDataList::replace().

Referenced by metadata_callback().

143 {
144  qDebug("FLAC stream info");
145  qDebug("\tmin_blocksize = %d", stream_info.get_min_blocksize());
146  qDebug("\tmax_blocksize = %d", stream_info.get_max_blocksize());
147  qDebug("\tmin_framesize = %d", stream_info.get_min_framesize());
148  qDebug("\tmax_framesize = %d", stream_info.get_max_framesize());
149 
150  Kwave::FileInfo info(metaData());
151  info.setRate(stream_info.get_sample_rate());
152  info.setTracks(stream_info.get_channels());
153  info.setBits(stream_info.get_bits_per_sample());
154  info.setLength(stream_info.get_total_samples());
156 
157  qDebug("Bitstream is %u channel, %uHz",
158  stream_info.get_channels(),
159  stream_info.get_sample_rate());
160 }
virtual void replace(const MetaDataList &list)
virtual Kwave::MetaDataList & metaData()
Definition: Decoder.h:78
Here is the call graph for this function:
Here is the caller graph for this function:

◆ parseVorbisComments()

void Kwave::FlacDecoder::parseVorbisComments ( const FLAC::Metadata::VorbisComment &  vorbis_comments)
protected

Parse vorbis comments

Parameters
vorbis_commentslist of vorbis comments, can be empty

Definition at line 163 of file FlacDecoder.cpp.

References Kwave::FileInfo::contains(), DBG, Kwave::FileInfo::get(), Kwave::INF_CREATION_DATE, Kwave::INF_SOFTWARE, m_vorbis_comment_map, Kwave::Decoder::metaData(), name, Kwave::MetaDataList::replace(), and Kwave::FileInfo::set().

Referenced by metadata_callback().

165 {
166  Kwave::FileInfo info(metaData());
167 
168  // first of all: the vendor string, specifying the software
169  QString vendor = QString::fromUtf8(reinterpret_cast<const char *>(
170  vorbis_comments.get_vendor_string()));
171  if (vendor.length()) {
172  info.set(Kwave::INF_SOFTWARE, vendor);
173  qDebug("Encoded by: '%s'\n\n", DBG(vendor));
174  }
175 
176  // parse all vorbis comments into Kwave file properties
177  for (unsigned int i = 0; i < vorbis_comments.get_num_comments(); i++) {
178  FLAC::Metadata::VorbisComment::Entry comment =
179  vorbis_comments.get_comment(i);
180  Q_ASSERT(comment.is_valid());
181  if (!comment.is_valid()) continue;
182 
183  QString name = QString::fromUtf8(
184  comment.get_field_name(), comment.get_field_name_length());
185  QString value = QString::fromUtf8(
186  comment.get_field_value(), comment.get_field_value_length());
187 
188  if (!m_vorbis_comment_map.contains(name)) continue;
189 
190  // we have a known vorbis tag
192  info.set(prop, value);
193  }
194 
195  // convert the date property to a QDate
196  if (info.contains(Kwave::INF_CREATION_DATE)) {
197  QString str_date =
198  QVariant(info.get(Kwave::INF_CREATION_DATE)).toString();
199  QDate date;
200  date = QDate::fromString(str_date, Qt::ISODate);
201  if (!date.isValid()) {
202  int year = str_date.toInt();
203  date.setDate(year, 1, 1);
204  }
205  if (date.isValid()) info.set(Kwave::INF_CREATION_DATE, date);
206  }
207 
209 }
Kwave::VorbisCommentMap m_vorbis_comment_map
Definition: FlacDecoder.h:144
const char name[16]
Definition: memcpy.c:510
virtual void replace(const MetaDataList &list)
virtual Kwave::MetaDataList & metaData()
Definition: Decoder.h:78
#define DBG(qs)
Definition: String.h:55
FileProperty
Definition: FileInfo.h:45
Here is the call graph for this function:
Here is the caller graph for this function:

◆ read_callback()

FLAC__StreamDecoderReadStatus Kwave::FlacDecoder::read_callback ( FLAC__byte  buffer[],
size_t *  bytes 
)
protected

FLAC decoder interface: read callback.

Parameters
bufferthe byte buffer to be filled
bytespointer with the number of bytes to be read, can be modified
Returns
read state

Definition at line 59 of file FlacDecoder.cpp.

References m_source.

61 {
62  Q_ASSERT(bytes);
63  Q_ASSERT(m_source);
64  if (!bytes || !m_source) return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
65 
66  // check for EOF
67  if (m_source->atEnd()) {
68  *bytes = 0;
69  return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
70  }
71 
72  // read into application buffer
73  *bytes = static_cast<unsigned>(m_source->read(
74  reinterpret_cast<char *>(&(buffer[0])),
75  static_cast<qint64>(*bytes)
76  ));
77 
78  if (!*bytes) return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
79 
80  return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
81 }
QIODevice * m_source
Definition: FlacDecoder.h:138

◆ write_callback()

FLAC__StreamDecoderWriteStatus Kwave::FlacDecoder::write_callback ( const ::FLAC__Frame *  frame,
const FLAC__int32 *const  buffer[] 
)
protected

FLAC decoder interface: write callback.

Parameters
framea FLAC frame structure
buffera buffer that contains the decoded samples
Returns
FLAC stream decoder write state

Definition at line 84 of file FlacDecoder.cpp.

References Kwave::FileInfo::bits(), Kwave::SampleArray::data(), Kwave::MultiWriter::isCanceled(), m_dest, Kwave::Decoder::metaData(), SAMPLE_BITS, and Kwave::FileInfo::tracks().

87 {
88  Q_ASSERT(buffer);
89  Q_ASSERT(frame);
90  Q_ASSERT(m_dest);
91  if (!buffer || !frame || !m_dest)
92  return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
93 
94  const unsigned int samples = frame->header.blocksize;
95 
96  const unsigned int tracks = Kwave::FileInfo(metaData()).tracks();
97  Q_ASSERT(samples);
98  Q_ASSERT(tracks);
99  if (!samples || !tracks)
100  return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
101 
102  Kwave::SampleArray dst(samples);
103 
104  // expand the samples up to the correct number of bits
105  int shift = SAMPLE_BITS - Kwave::FileInfo(metaData()).bits();
106  if (shift < 0) shift = 0;
107  unsigned int mul = (1 << shift);
108 
109  // decode the samples into a temporary buffer and
110  // flush it to the Writer(s), track by track
111  for (unsigned int track=0; track < tracks; track++) {
112  Kwave::Writer *writer = (*m_dest)[track];
113  Q_ASSERT(writer);
114  if (!writer) continue;
115  const FLAC__int32 *src = buffer[track];
116  sample_t *d = dst.data();
117 
118  for (unsigned int sample = 0; sample < samples; sample++) {
119  // the following cast is only necessary if
120  // sample_t is not equal to a quint32
121  sample_t s = static_cast<sample_t>(*src++);
122 
123  // correct precision
124  if (shift) s *= mul;
125 
126  // write to destination buffer
127  *d++ = s;
128  }
129 
130  // flush the temporary buffer
131  (*writer) << dst;
132  }
133 
134  // at this point we check for a user-cancel
135  return (m_dest->isCanceled()) ?
136  FLAC__STREAM_DECODER_WRITE_STATUS_ABORT :
137  FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
138 }
Kwave::MultiWriter * m_dest
Definition: FlacDecoder.h:141
virtual Kwave::MetaDataList & metaData()
Definition: Decoder.h:78
bool isCanceled() const
Definition: MultiWriter.h:64
unsigned int tracks() const
Definition: FileInfo.cpp:445
unsigned int bits() const
Definition: FileInfo.cpp:430
#define SAMPLE_BITS
Definition: Sample.h:43
qint32 sample_t
Definition: Sample.h:37
Here is the call graph for this function:

Member Data Documentation

◆ m_dest

Kwave::MultiWriter* Kwave::FlacDecoder::m_dest
private

destination of the audio data

Definition at line 141 of file FlacDecoder.h.

Referenced by decode(), and write_callback().

◆ m_source

QIODevice* Kwave::FlacDecoder::m_source
private

source of the audio data

Definition at line 138 of file FlacDecoder.h.

Referenced by close(), decode(), open(), read_callback(), and ~FlacDecoder().

◆ m_vorbis_comment_map

Kwave::VorbisCommentMap Kwave::FlacDecoder::m_vorbis_comment_map
private

map for translating vorbis comments to FileInfo properties

Definition at line 144 of file FlacDecoder.h.

Referenced by parseVorbisComments().


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