summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaszlo Papp <lpapp@kde.org>2011-12-06 18:38:39 +0200
committerLaszlo Papp <ext-laszlo.papp@nokia.com>2011-12-06 18:38:39 +0200
commit9f44baaeec4d422db83f34561ddff68dcc08b107 (patch)
tree186d5e4b4fada330accf6d80a9a654cbccd8a4f7
parent2bd5bfaaaeaf95af4e611a8f7184b54ea2b1c393 (diff)
Add an initial implementation of the QALMpg123AudioDecoder class to the project
-rw-r--r--src/decoders/qalmpg123audiodecoder.cpp230
-rw-r--r--src/decoders/qalmpg123audiodecoder.h55
2 files changed, 285 insertions, 0 deletions
diff --git a/src/decoders/qalmpg123audiodecoder.cpp b/src/decoders/qalmpg123audiodecoder.cpp
new file mode 100644
index 0000000..96db818
--- /dev/null
+++ b/src/decoders/qalmpg123audiodecoder.cpp
@@ -0,0 +1,230 @@
+/******************************************************************************
+ * This file is part of the QtOpenAL project
+ * Copyright (c) 2011 Laszlo Papp <lpapp@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "qalmpg123audiodecoder.h"
+
+#include <QtCore/QFile>
+#include <QtCore/QString>
+#include <QtCore/QUrl>
+#include <QtCore/QDebug>
+
+class QALMpg123AudioDecoder::Private
+{
+ public:
+ Private()
+ : mpg123Handle(0)
+ {
+ int error;
+ if ((error = mpg123_init()) == MPG123_OK) {
+ qWarning() << Q_FUNC_INFO << "Failed to initialize the mpg123 library:" << error;
+ }
+ }
+
+ ~Private()
+ {
+ mpg123_exit();
+ }
+
+ static sf_count_t fileLengthCallback(void *user_data);
+ static sf_count_t seekCallback(sf_count_t offset, int whence, void *user_data);
+ static sf_count_t readCallback(void *ptr, sf_count_t count, void *user_data);
+ static sf_count_t tellCallback(void *user_data);
+
+ QFile file;
+
+ QByteArray encodedData;
+ mpg123_handle *mpg123Handle;
+ SNDFILE *sndFile;
+ SF_INFO sfInfo;
+};
+
+sf_count_t
+QALMpg123AudioDecoder::Private::fileLengthCallback(void *user_data)
+{
+ return reinterpret_cast<QALMpg123AudioDecoder::Private*>(user_data)->file.size();
+}
+
+sf_count_t
+QALMpg123AudioDecoder::Private::seekCallback(sf_count_t offset, int whence, void *user_data)
+{
+ QFile &tmpFile = reinterpret_cast<QALMpg123AudioDecoder::Private*>(user_data)->file;
+ switch (whence) {
+ case SEEK_SET:
+ if (tmpFile.seek(offset) == true)
+ return offset;
+
+ break;
+
+ case SEEK_CUR:
+ offset += tmpFile.pos();
+ if (tmpFile.seek(offset) == true)
+ return offset;
+
+ break;
+
+ case SEEK_END:
+ offset += tmpFile.size();
+ if (tmpFile.seek(offset) == true)
+ return offset;
+
+ break;
+
+ default:
+ qWarning() << Q_FUNC_INFO << "Failed to seek the file:" << tmpFile.fileName() << "Invalid whence value:" << whence;
+ break;
+ }
+
+ qWarning() << Q_FUNC_INFO << "Failed to seek the file:" << tmpFile.fileName();
+ return -1;
+}
+
+sf_count_t
+QALMpg123AudioDecoder::Private::readCallback(void *ptr, sf_count_t count, void *user_data)
+{
+ return reinterpret_cast<QALMpg123AudioDecoder::Private*>(user_data)->file.read(reinterpret_cast<char*>(ptr), count);
+}
+
+sf_count_t
+QALMpg123AudioDecoder::Private::tellCallback(void *user_data)
+{
+ return reinterpret_cast<QALMpg123AudioDecoder::Private*>(user_data)->file.pos();
+}
+
+QALMpg123AudioDecoder::QALMpg123AudioDecoder()
+ : d(new Private)
+{
+}
+
+QALMpg123AudioDecoder::~QALMpg123AudioDecoder()
+{
+}
+
+bool
+QALMpg123AudioDecoder::open(const QFile &file)
+{
+ return open(file.fileName());
+}
+
+bool
+QALMpg123AudioDecoder::open(const QUrl &fileUrl)
+{
+ return open(fileUrl.toLocalFile());
+}
+
+bool
+QALMpg123AudioDecoder::open(const QString &fileName)
+{
+ d->file.setFileName(fileName);
+
+ mpg123Handle = mpg123_new(NULL, NULL);
+
+ SF_INFO sfInfo;
+ sfInfo.format = 0;
+
+ SF_VIRTUAL_IO sfVirtualIO;
+ sfVirtualIO.get_filelen = &d->fileLengthCallback;
+ sfVirtualIO.seek = &d->seekCallback;
+ sfVirtualIO.read = &d->readCallback;
+ sfVirtualIO.write = 0;
+ sfVirtualIO.tell = &d->tellCallback;
+
+ if ((d->sndFile = sf_open_virtual(&sfVirtualIO, SFM_READ, &sfInfo, d)) == 0) {
+ qWarning() << Q_FUNC_INFO << "Failed to open the file" << fileName.toUtf8().constData() << "for decoding:" << sf_strerror(d->sndFile);
+ return false;
+ }
+
+ d->sfInfo = sfInfo;
+
+ return true;
+}
+
+qint64
+QALMpg123AudioDecoder::pos()
+{
+ int position;
+ if ((position = sf_seek(d->sndFile, 0, SEEK_CUR)) == -1) {
+ qWarning() << Q_FUNC_INFO << "Failed to tell the current position:" << sf_strerror(d->sndFile);
+ }
+
+ return position;
+}
+
+bool
+QALMpg123AudioDecoder::seek(qint64 pos)
+{
+ if (sf_seek(d->sndFile, pos, SEEK_SET) == -1) {
+ qWarning() << Q_FUNC_INFO << "Failed to seek in the file:" << sf_strerror(d->sndFile);
+ return false;
+ }
+
+ return true;
+}
+
+bool
+QALMpg123AudioDecoder::close()
+{
+ mpg123_delete_close(d->mp3Handle);
+ d->mp3Handle = 0;
+
+ return true;
+}
+
+void
+QALMpg123AudioDecoder::setEncodedData(const QByteArray &encodedData)
+{
+ d->encodedData = encodedData;
+}
+
+int
+QALMpg123AudioDecoder::channels() const
+{
+ return d->sfInfo.channels;
+}
+
+int
+QALMpg123AudioDecoder::sampleRate() const
+{
+ return d->sfInfo.samplerate;
+}
+
+int
+QALMpg123AudioDecoder::sampleSize() const
+{
+ return 16;
+}
+
+QByteArray
+QALMpg123AudioDecoder::decode(qint64 maxlen)
+{
+ QByteArray result;
+ result.reserve(maxlen);
+
+ char *decodedData = result.data();
+
+ if (maxlen != decode(decodedData, maxlen))
+ qWarning() << Q_FUNC_INFO << "Could not to decode all the data:" << maxlen;
+
+ return result;
+}
+
+qint64
+QALMpg123AudioDecoder::decode(char *decodedData, qint64 maxlen)
+{
+ return sf_readf_short(d->sndFile, reinterpret_cast<short*>(decodedData), maxlen);
+}
diff --git a/src/decoders/qalmpg123audiodecoder.h b/src/decoders/qalmpg123audiodecoder.h
new file mode 100644
index 0000000..ecfd53b
--- /dev/null
+++ b/src/decoders/qalmpg123audiodecoder.h
@@ -0,0 +1,55 @@
+/******************************************************************************
+ * This file is part of the QtOpenAL project
+ * Copyright (c) 2011 Laszlo Papp <lpapp@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef QALMPG123AUDIODECODER_H
+#define QALMPG123AUDIODECODER_H
+
+#include "q_openal_export.h"
+
+#include "qalabstractaudiodecoder.h"
+
+class Q_OPENAL_EXPORT QALMpg123FileAudioDecoder : QALAbstractAudioDecoder
+{
+ //Q_DECLARE_PRIVATE(QALMpg123AudioDecoder)
+public:
+ QALMpg123AudioDecoder();
+ virtual ~QALMpg123AudioDecoder();
+
+ bool open(const QFile &file);
+ bool open(const QUrl &fileUrl);
+ bool open(const QString &fileName);
+ qint64 pos();
+ bool seek(qint64 pos);
+ bool close();
+
+ void setEncodedData(const QByteArray &encodedData);
+
+ int channels() const;
+ int sampleRate() const;
+ int sampleSize() const;
+
+ QByteArray decode(qint64 maxlen);
+ qint64 decode(char *decodedData, qint64 maxlen);
+
+ private:
+ class Private;
+ Private *const d;
+};
+
+#endif // QALMPG123AUDIODECODER_H