diff options
Diffstat (limited to 'extern/audaspace/plugins/libsndfile/SndFileReader.cpp')
-rw-r--r-- | extern/audaspace/plugins/libsndfile/SndFileReader.cpp | 161 |
1 files changed, 161 insertions, 0 deletions
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 |