M Makefile +3 -2
@@ 9,6 9,7 @@
# -DHAVE_OGGZ -DHAVE_FISHSOUND
# * Read Ogg/Vorbis files using oggz
# -DHAVE_OPUS * Read Opus files using libopus
+# -DHAVE_MINIMP3 * Read mp3 files using minimp3
# -DHAVE_MEDIAFOUNDATION
# * Read various formats using MediaFoundation on Windows
# -DHAVE_COREAUDIO * Read various formats using CoreAudio on macOS/iOS
@@ 17,12 18,12 @@
# will also be provided, as none of the other libraries have write
# support included here.
-AUDIOSTREAM_DEFINES := -DHAVE_LIBSNDFILE -DHAVE_OGGZ -DHAVE_FISHSOUND -DHAVE_OPUS
+AUDIOSTREAM_DEFINES := -DHAVE_LIBSNDFILE -DHAVE_OGGZ -DHAVE_FISHSOUND -DHAVE_OPUS -DHAVE_MINIMP3
# Add any related includes and libraries here
#
-THIRD_PARTY_INCLUDES := -I/usr/include/opus
+THIRD_PARTY_INCLUDES := -I/usr/include/opus -I../thirdparty/minimp3
THIRD_PARTY_LIBS :=
M build/Makefile.inc +4 -0
@@ 31,6 31,8 @@ src/AudioReadStreamFactory.o: src/WavFil
src/AudioReadStreamFactory.o: src/OggVorbisReadStream.cpp
src/AudioReadStreamFactory.o: src/MediaFoundationReadStream.cpp
src/AudioReadStreamFactory.o: src/CoreAudioReadStream.cpp
+src/AudioReadStreamFactory.o: src/OpusReadStream.cpp
+src/AudioReadStreamFactory.o: src/MiniMP3ReadStream.cpp
src/AudioWriteStreamFactory.o: ./bqaudiostream/AudioWriteStreamFactory.h
src/AudioWriteStreamFactory.o: ./bqaudiostream/AudioWriteStream.h
src/AudioWriteStreamFactory.o: ./bqaudiostream/Exceptions.h
@@ 48,3 50,5 @@ src/WavFileReadStream.o: ./bqaudiostream
src/CoreAudioWriteStream.o: ./bqaudiostream/AudioWriteStream.h
src/CoreAudioReadStream.o: ./bqaudiostream/AudioReadStream.h
src/OggVorbisReadStream.o: ./bqaudiostream/AudioReadStream.h
+src/OpusReadStream.o: ./bqaudiostream/AudioReadStream.h
+src/MiniMP3ReadStream.o: ./bqaudiostream/AudioReadStream.h
M src/AudioReadStreamFactory.cpp +1 -0
@@ 125,6 125,7 @@ AudioReadStreamFactory::getFileFilter()
#include "WavFileReadStream.cpp"
#include "OggVorbisReadStream.cpp"
+#include "MiniMP3ReadStream.cpp"
#include "MediaFoundationReadStream.cpp"
#include "CoreAudioReadStream.cpp"
#include "OpusReadStream.cpp"
A => src/MiniMP3ReadStream.cpp +133 -0
@@ 0,0 1,133 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
+/*
+ bqaudiostream
+
+ A small library wrapping various audio file read/write
+ implementations in C++.
+
+ Copyright 2007-2020 Particular Programs Ltd.
+
+ Permission is hereby granted, free of charge, to any person
+ obtaining a copy of this software and associated documentation
+ files (the "Software"), to deal in the Software without
+ restriction, including without limitation the rights to use, copy,
+ modify, merge, publish, distribute, sublicense, and/or sell copies
+ of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
+ ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ Except as contained in this notice, the names of Chris Cannam and
+ Particular Programs Ltd shall not be used in advertising or
+ otherwise to promote the sale, use or other dealings in this
+ Software without prior written authorization.
+*/
+
+#ifdef HAVE_MINIMP3
+
+#define MINIMP3_IMPLEMENTATION
+#define MINIMP3_FLOAT_OUTPUT
+#include <minimp3_ex.h>
+
+#include "MiniMP3ReadStream.h"
+
+#include <sstream>
+
+namespace breakfastquay
+{
+
+static vector<string>
+getMiniMP3Extensions()
+{
+ vector<string> extensions;
+ extensions.push_back("mp3");
+ return extensions;
+}
+
+static
+AudioReadStreamBuilder<MiniMP3ReadStream>
+minimp3builder(
+ string("http://breakfastquay.com/rdf/turbot/audiostream/MiniMP3ReadStream"),
+ getMiniMP3Extensions()
+ );
+
+class MiniMP3ReadStream::D
+{
+public:
+ D() { }
+ mp3dec_ex_t dec;
+};
+
+MiniMP3ReadStream::MiniMP3ReadStream(string path) :
+ m_path(path),
+ m_d(new D)
+{
+ //!!! Windows: use wchar versions
+
+ m_channelCount = 0;
+ m_sampleRate = 0;
+
+ int err = mp3dec_ex_open(&m_d->dec, path.c_str(), MP3D_DO_NOT_SCAN);
+ if (err) {
+ ostringstream os;
+ os << "MiniMP3ReadStream: Unable to open file (error code " << err << ")";
+ m_error = os.str();
+ if (err == MP3D_E_IOERROR) {
+ throw FileNotFound(m_path);
+ } else {
+ throw InvalidFileFormat(m_path, "failed to open audio file");
+ }
+ }
+
+ m_channelCount = m_d->dec.info.channels;
+ m_sampleRate = m_d->dec.info.hz;
+}
+
+size_t
+MiniMP3ReadStream::getFrames(size_t count, float *frames)
+{
+ if (m_error != "") return 0;
+ if (count == 0) return 0;
+
+// cerr << "getFrames: working" << endl;
+
+ size_t desired = count * m_channelCount;
+ size_t obtained = mp3dec_ex_read(&m_d->dec, frames, desired);
+
+ //!!! have to provide our own tags support?
+
+ if (obtained < desired) {
+ if (m_d->dec.last_error) {
+ ostringstream os;
+ os << "MiniMP3ReadStream: Failed to read from file (error code "
+ << m_d->dec.last_error << ")";
+ m_error = os.str();
+ mp3dec_ex_close(&m_d->dec);
+ throw InvalidFileFormat(m_path, "error in decoder");
+ }
+ }
+
+ return obtained / m_channelCount;
+}
+
+MiniMP3ReadStream::~MiniMP3ReadStream()
+{
+ if (m_error != "") {
+ mp3dec_ex_close(&m_d->dec);
+ }
+ delete m_d;
+}
+
+}
+
+#endif
+
A => src/MiniMP3ReadStream.h +72 -0
@@ 0,0 1,72 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
+/*
+ bqaudiostream
+
+ A small library wrapping various audio file read/write
+ implementations in C++.
+
+ Copyright 2007-2020 Particular Programs Ltd.
+
+ Permission is hereby granted, free of charge, to any person
+ obtaining a copy of this software and associated documentation
+ files (the "Software"), to deal in the Software without
+ restriction, including without limitation the rights to use, copy,
+ modify, merge, publish, distribute, sublicense, and/or sell copies
+ of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
+ ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ Except as contained in this notice, the names of Chris Cannam and
+ Particular Programs Ltd shall not be used in advertising or
+ otherwise to promote the sale, use or other dealings in this
+ Software without prior written authorization.
+*/
+
+#ifndef BQ_MINIMP3_READ_STREAM_H
+#define BQ_MINIMP3_READ_STREAM_H
+
+#include "AudioReadStream.h"
+
+#ifdef HAVE_MINIMP3
+
+namespace breakfastquay
+{
+
+class MiniMP3ReadStream : public AudioReadStream
+{
+public:
+ MiniMP3ReadStream(std::string path);
+ virtual ~MiniMP3ReadStream();
+
+ virtual std::string getTrackName() const { return m_track; }
+ virtual std::string getArtistName() const { return m_artist; }
+
+ virtual std::string getError() const { return m_error; }
+
+protected:
+ virtual size_t getFrames(size_t count, float *frames);
+
+ std::string m_path;
+ std::string m_error;
+ std::string m_track;
+ std::string m_artist;
+
+ class D;
+ D *m_d;
+};
+
+}
+
+#endif
+
+#endif
M test/test.pro +1 -1
@@ 10,7 10,7 @@ QT -= gui
DESTDIR = .
QMAKE_LIBDIR += . ..
-LIBS += -L.. -lbqaudiostream -L../../bqresample -lbqresample -L../../bqvec -lbqvec -lsndfile -loggz -lfishsound -lopusfile -lopus -logg
+LIBS += -L.. -lbqaudiostream -L../../bqresample -lbqresample -L../../bqvec -lbqvec -lsndfile -loggz -lfishsound -lopusfile -lopus -logg -lsamplerate
INCLUDEPATH += . .. ../../bqvec ../../bqresample ../../bqthingfactory
DEPENDPATH += . .. ../../bqvec ../../bqresample ../../bqthingfactory