diff options
Diffstat (limited to 'extern/audaspace/plugins/libsndfile')
-rw-r--r-- | extern/audaspace/plugins/libsndfile/SndFile.cpp | 62 | ||||
-rw-r--r-- | extern/audaspace/plugins/libsndfile/SndFile.h | 60 | ||||
-rw-r--r-- | extern/audaspace/plugins/libsndfile/SndFileReader.cpp | 161 | ||||
-rw-r--r-- | extern/audaspace/plugins/libsndfile/SndFileReader.h | 125 | ||||
-rw-r--r-- | extern/audaspace/plugins/libsndfile/SndFileWriter.cpp | 128 | ||||
-rw-r--r-- | extern/audaspace/plugins/libsndfile/SndFileWriter.h | 84 |
6 files changed, 620 insertions, 0 deletions
diff --git a/extern/audaspace/plugins/libsndfile/SndFile.cpp b/extern/audaspace/plugins/libsndfile/SndFile.cpp new file mode 100644 index 00000000000..ba4ff24ad68 --- /dev/null +++ b/extern/audaspace/plugins/libsndfile/SndFile.cpp @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright 2009-2016 Jörg Müller + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ******************************************************************************/ + +#include "SndFile.h" +#include "SndFileReader.h" +#include "SndFileWriter.h" +#include "file/FileManager.h" + +AUD_NAMESPACE_BEGIN + +SndFile::SndFile() +{ +} + +void SndFile::registerPlugin() +{ + std::shared_ptr<SndFile> plugin = std::shared_ptr<SndFile>(new SndFile); + FileManager::registerInput(plugin); + FileManager::registerOutput(plugin); +} + +std::shared_ptr<IReader> SndFile::createReader(std::string filename) +{ + return std::shared_ptr<IReader>(new SndFileReader(filename)); +} + +std::shared_ptr<IReader> SndFile::createReader(std::shared_ptr<Buffer> buffer) +{ + return std::shared_ptr<IReader>(new SndFileReader(buffer)); +} + +std::shared_ptr<IWriter> SndFile::createWriter(std::string filename, DeviceSpecs specs, Container format, Codec codec, unsigned int bitrate) +{ + return std::shared_ptr<IWriter>(new SndFileWriter(filename, specs, format, codec, bitrate)); +} + +#ifdef LIBSNDFILE_PLUGIN +extern "C" AUD_PLUGIN_API void registerPlugin() +{ + SndFile::registerPlugin(); +} + +extern "C" AUD_PLUGIN_API const char* getName() +{ + return "LibSndFile"; +} +#endif + +AUD_NAMESPACE_END diff --git a/extern/audaspace/plugins/libsndfile/SndFile.h b/extern/audaspace/plugins/libsndfile/SndFile.h new file mode 100644 index 00000000000..61afed1d564 --- /dev/null +++ b/extern/audaspace/plugins/libsndfile/SndFile.h @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright 2009-2016 Jörg Müller + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ******************************************************************************/ + +#pragma once + +#ifdef LIBSNDFILE_PLUGIN +#define AUD_BUILD_PLUGIN +#endif + +/** + * @file SndFile.h + * @ingroup plugin + * The SndFile class. + */ + +#include "file/IFileInput.h" +#include "file/IFileOutput.h" + +AUD_NAMESPACE_BEGIN + +/** + * This plugin class reads and writes sounds via libsndfile. + */ +class AUD_PLUGIN_API SndFile : public IFileInput, public IFileOutput +{ +private: + // delete copy constructor and operator= + SndFile(const SndFile&) = delete; + SndFile& operator=(const SndFile&) = delete; + +public: + /** + * Creates a new libsndfile plugin. + */ + SndFile(); + + /** + * Registers this plugin. + */ + static void registerPlugin(); + + virtual std::shared_ptr<IReader> createReader(std::string filename); + virtual std::shared_ptr<IReader> createReader(std::shared_ptr<Buffer> buffer); + virtual std::shared_ptr<IWriter> createWriter(std::string filename, DeviceSpecs specs, Container format, Codec codec, unsigned int bitrate); +}; + +AUD_NAMESPACE_END diff --git a/extern/audaspace/plugins/libsndfile/SndFileReader.cpp b/extern/audaspace/plugins/libsndfile/SndFileReader.cpp new file mode 100644 index 00000000000..d2d89814c07 --- /dev/null +++ b/extern/audaspace/plugins/libsndfile/SndFileReader.cpp @@ -0,0 +1,161 @@ +/******************************************************************************* + * Copyright 2009-2016 Jörg Müller + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ******************************************************************************/ + +#include "SndFileReader.h" +#include "util/Buffer.h" +#include "Exception.h" + +#include <cstring> + +AUD_NAMESPACE_BEGIN + +sf_count_t SndFileReader::vio_get_filelen(void* user_data) +{ + SndFileReader* reader = (SndFileReader*)user_data; + return reader->m_membuffer->getSize(); +} + +sf_count_t SndFileReader::vio_seek(sf_count_t offset, int whence, + void* user_data) +{ + SndFileReader* reader = (SndFileReader*)user_data; + + switch(whence) + { + case SEEK_SET: + reader->m_memoffset = offset; + break; + case SEEK_CUR: + reader->m_memoffset = reader->m_memoffset + offset; + break; + case SEEK_END: + reader->m_memoffset = reader->m_membuffer->getSize() + offset; + break; + } + + return reader->m_memoffset; +} + +sf_count_t SndFileReader::vio_read(void* ptr, sf_count_t count, + void* user_data) +{ + SndFileReader* reader = (SndFileReader*)user_data; + + if(reader->m_memoffset + count > reader->m_membuffer->getSize()) + count = reader->m_membuffer->getSize() - reader->m_memoffset; + + std::memcpy(ptr, ((data_t*)reader->m_membuffer->getBuffer()) + + reader->m_memoffset, count); + reader->m_memoffset += count; + + return count; +} + +sf_count_t SndFileReader::vio_tell(void* user_data) +{ + SndFileReader* reader = (SndFileReader*)user_data; + + return reader->m_memoffset; +} + +SndFileReader::SndFileReader(std::string filename) : + m_position(0) +{ + SF_INFO sfinfo; + + sfinfo.format = 0; + m_sndfile = sf_open(filename.c_str(), SFM_READ, &sfinfo); + + if(!m_sndfile) + AUD_THROW(FileException, "The file couldn't be opened with libsndfile."); + + m_specs.channels = (Channels) sfinfo.channels; + m_specs.rate = (SampleRate) sfinfo.samplerate; + m_length = sfinfo.frames; + m_seekable = sfinfo.seekable; +} + +SndFileReader::SndFileReader(std::shared_ptr<Buffer> buffer) : + m_position(0), + m_membuffer(buffer), + m_memoffset(0) +{ + m_vio.get_filelen = vio_get_filelen; + m_vio.read = vio_read; + m_vio.seek = vio_seek; + m_vio.tell = vio_tell; + m_vio.write = nullptr; + + SF_INFO sfinfo; + + sfinfo.format = 0; + m_sndfile = sf_open_virtual(&m_vio, SFM_READ, &sfinfo, this); + + if(!m_sndfile) + AUD_THROW(FileException, "The buffer couldn't be read with libsndfile."); + + m_specs.channels = (Channels) sfinfo.channels; + m_specs.rate = (SampleRate) sfinfo.samplerate; + m_length = sfinfo.frames; + m_seekable = sfinfo.seekable; +} + +SndFileReader::~SndFileReader() +{ + sf_close(m_sndfile); +} + +bool SndFileReader::isSeekable() const +{ + return m_seekable; +} + +void SndFileReader::seek(int position) +{ + if(m_seekable) + { + position = sf_seek(m_sndfile, position, SEEK_SET); + m_position = position; + } +} + +int SndFileReader::getLength() const +{ + return m_length; +} + +int SndFileReader::getPosition() const +{ + return m_position; +} + +Specs SndFileReader::getSpecs() const +{ + return m_specs; +} + +void SndFileReader::read(int& length, bool& eos, sample_t* buffer) +{ + int olen = length; + + length = sf_readf_float(m_sndfile, buffer, length); + + m_position += length; + + eos = length < olen; +} + +AUD_NAMESPACE_END diff --git a/extern/audaspace/plugins/libsndfile/SndFileReader.h b/extern/audaspace/plugins/libsndfile/SndFileReader.h new file mode 100644 index 00000000000..081c29c686c --- /dev/null +++ b/extern/audaspace/plugins/libsndfile/SndFileReader.h @@ -0,0 +1,125 @@ +/******************************************************************************* + * Copyright 2009-2016 Jörg Müller + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ******************************************************************************/ + +#pragma once + +#include "IReader.h" + +#ifdef LIBSNDFILE_PLUGIN +#define AUD_BUILD_PLUGIN +#endif + +/** + * @file SndFileReader.h + * @ingroup plugin + * The SndFileReader class. + */ + +#include <string> +#include <sndfile.h> +#include <memory> + +AUD_NAMESPACE_BEGIN + +class Buffer; + +/** + * This class reads a sound file via libsndfile. + */ +class AUD_PLUGIN_API SndFileReader : public IReader +{ +private: + /** + * The current position in samples. + */ + int m_position; + + /** + * The sample count in the file. + */ + int m_length; + + /** + * Whether the file is seekable. + */ + bool m_seekable; + + /** + * The specification of the audio data. + */ + Specs m_specs; + + /** + * The sndfile. + */ + SNDFILE* m_sndfile; + + /** + * The virtual IO structure for memory file reading. + */ + SF_VIRTUAL_IO m_vio; + + /** + * The pointer to the memory file. + */ + std::shared_ptr<Buffer> m_membuffer; + + /** + * The current reading pointer of the memory file. + */ + int m_memoffset; + + // Functions for libsndfile virtual IO functionality + AUD_LOCAL static sf_count_t vio_get_filelen(void* user_data); + AUD_LOCAL static sf_count_t vio_seek(sf_count_t offset, int whence, void* user_data); + AUD_LOCAL static sf_count_t vio_read(void* ptr, sf_count_t count, void* user_data); + AUD_LOCAL static sf_count_t vio_tell(void* user_data); + + // delete copy constructor and operator= + SndFileReader(const SndFileReader&) = delete; + SndFileReader& operator=(const SndFileReader&) = delete; + +public: + /** + * Creates a new reader. + * \param filename The path to the file to be read. + * \exception Exception Thrown if the file specified does not exist or + * cannot be read with libsndfile. + */ + SndFileReader(std::string filename); + + /** + * Creates a new reader. + * \param buffer The buffer to read from. + * \exception Exception Thrown if the buffer specified cannot be read + * with libsndfile. + */ + SndFileReader(std::shared_ptr<Buffer> buffer); + + /** + * Destroys the reader and closes the file. + */ + virtual ~SndFileReader(); + + virtual bool isSeekable() const; + virtual void seek(int position); + virtual int getLength() const; + virtual int getPosition() const; + virtual Specs getSpecs() const; + virtual void read(int& length, bool& eos, sample_t* buffer); +}; + +AUD_NAMESPACE_END diff --git a/extern/audaspace/plugins/libsndfile/SndFileWriter.cpp b/extern/audaspace/plugins/libsndfile/SndFileWriter.cpp new file mode 100644 index 00000000000..d2ab117132d --- /dev/null +++ b/extern/audaspace/plugins/libsndfile/SndFileWriter.cpp @@ -0,0 +1,128 @@ +/******************************************************************************* + * Copyright 2009-2016 Jörg Müller + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ******************************************************************************/ + +#include "SndFileWriter.h" +#include "Exception.h" + +#include <cstring> + +AUD_NAMESPACE_BEGIN + +SndFileWriter::SndFileWriter(std::string filename, DeviceSpecs specs, + Container format, Codec codec, unsigned int bitrate) : + m_position(0), m_specs(specs) +{ + SF_INFO sfinfo; + + sfinfo.channels = specs.channels; + sfinfo.samplerate = int(specs.rate); + + switch(format) + { + case CONTAINER_FLAC: + sfinfo.format = SF_FORMAT_FLAC; + switch(specs.format) + { + case FORMAT_S16: + sfinfo.format |= SF_FORMAT_PCM_16; + break; + case FORMAT_S24: + sfinfo.format |= SF_FORMAT_PCM_24; + break; + case FORMAT_S32: + sfinfo.format |= SF_FORMAT_PCM_32; + break; + case FORMAT_FLOAT32: + sfinfo.format |= SF_FORMAT_FLOAT; + break; + case FORMAT_FLOAT64: + sfinfo.format |= SF_FORMAT_DOUBLE; + break; + default: + sfinfo.format = 0; + break; + } + break; + case CONTAINER_OGG: + if(codec == CODEC_VORBIS) + sfinfo.format = SF_FORMAT_OGG | SF_FORMAT_VORBIS; + else + sfinfo.format = 0; + break; + case CONTAINER_WAV: + sfinfo.format = SF_FORMAT_WAV; + switch(specs.format) + { + case FORMAT_U8: + sfinfo.format |= SF_FORMAT_PCM_U8; + break; + case FORMAT_S16: + sfinfo.format |= SF_FORMAT_PCM_16; + break; + case FORMAT_S24: + sfinfo.format |= SF_FORMAT_PCM_24; + break; + case FORMAT_S32: + sfinfo.format |= SF_FORMAT_PCM_32; + break; + case FORMAT_FLOAT32: + sfinfo.format |= SF_FORMAT_FLOAT; + break; + case FORMAT_FLOAT64: + sfinfo.format |= SF_FORMAT_DOUBLE; + break; + default: + sfinfo.format = 0; + break; + } + break; + default: + sfinfo.format = 0; + break; + } + + if(sfinfo.format == 0) + AUD_THROW(FileException, "This format couldn't be written with libsndfile."); + + m_sndfile = sf_open(filename.c_str(), SFM_WRITE, &sfinfo); + + if(!m_sndfile) + AUD_THROW(FileException, "The file couldn't be written with libsndfile."); +} + +SndFileWriter::~SndFileWriter() +{ + sf_close(m_sndfile); +} + +int SndFileWriter::getPosition() const +{ + return m_position; +} + +DeviceSpecs SndFileWriter::getSpecs() const +{ + return m_specs; +} + +void SndFileWriter::write(unsigned int length, sample_t* buffer) +{ + length = sf_writef_float(m_sndfile, buffer, length); + + m_position += length; +} + +AUD_NAMESPACE_END diff --git a/extern/audaspace/plugins/libsndfile/SndFileWriter.h b/extern/audaspace/plugins/libsndfile/SndFileWriter.h new file mode 100644 index 00000000000..75d761f5163 --- /dev/null +++ b/extern/audaspace/plugins/libsndfile/SndFileWriter.h @@ -0,0 +1,84 @@ +/******************************************************************************* + * Copyright 2009-2016 Jörg Müller + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ******************************************************************************/ + +#pragma once + +#ifdef LIBSNDFILE_PLUGIN +#define AUD_BUILD_PLUGIN +#endif + +/** + * @file SndFileWriter.h + * @ingroup plugin + * The SndFileWriter class. + */ + +#include "file/IWriter.h" + +#include <string> +#include <sndfile.h> + +AUD_NAMESPACE_BEGIN + +/** + * This class writes a sound file via libsndfile. + */ +class AUD_PLUGIN_API SndFileWriter : public IWriter +{ +private: + /** + * The current position in samples. + */ + int m_position; + + /** + * The specification of the audio data. + */ + DeviceSpecs m_specs; + + /** + * The sndfile. + */ + SNDFILE* m_sndfile; + + // delete copy constructor and operator= + SndFileWriter(const SndFileWriter&) = delete; + SndFileWriter& operator=(const SndFileWriter&) = delete; + +public: + /** + * Creates a new writer. + * \param filename The path to the file to be read. + * \param specs The file's audio specification. + * \param format The file's container format. + * \param codec The codec used for encoding the audio data. + * \param bitrate The bitrate for encoding. + * \exception Exception Thrown if the file specified cannot be written + * with libsndfile. + */ + SndFileWriter(std::string filename, DeviceSpecs specs, Container format, Codec codec, unsigned int bitrate); + + /** + * Destroys the writer and closes the file. + */ + virtual ~SndFileWriter(); + + virtual int getPosition() const; + virtual DeviceSpecs getSpecs() const; + virtual void write(unsigned int length, sample_t* buffer); +}; + +AUD_NAMESPACE_END |