diff options
author | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-01-05 00:01:18 +0000 |
---|---|---|
committer | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-01-05 00:01:18 +0000 |
commit | 42995d7bf396933ee60c5f89c354ea89cf13df0d (patch) | |
tree | cfdcea0ac57420e7baf570bfe435e107bb842541 /flow/gslpp | |
download | arts-42995d7bf396933ee60c5f89c354ea89cf13df0d.tar.gz arts-42995d7bf396933ee60c5f89c354ea89cf13df0d.zip |
Copy of aRts for Trinity modifications
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/dependencies/arts@1070145 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'flow/gslpp')
-rw-r--r-- | flow/gslpp/Makefile.am | 7 | ||||
-rw-r--r-- | flow/gslpp/datahandle.cpp | 412 | ||||
-rw-r--r-- | flow/gslpp/datahandle.h | 220 |
3 files changed, 639 insertions, 0 deletions
diff --git a/flow/gslpp/Makefile.am b/flow/gslpp/Makefile.am new file mode 100644 index 0000000..11f7407 --- /dev/null +++ b/flow/gslpp/Makefile.am @@ -0,0 +1,7 @@ +INCLUDES = -I$(top_srcdir)/flow -I$(top_srcdir)/flow/gsl -I$(top_builddir)/flow -I$(top_srcdir)/mcop -I$(top_builddir)/mcop -I$(top_builddir) $(all_includes) + +noinst_LTLIBRARIES = libgslpp.la + +libgslpp_la_SOURCES = datahandle.cpp +#libgslpp_la_LIBADD = $(top_builddir)/mcop/libmcop.la $(top_builddir)/flow/gsl/libgsl.la -lm $(LIBPOSIX4) +#libgslpp_la_LDFLAGS = -no-undefined diff --git a/flow/gslpp/datahandle.cpp b/flow/gslpp/datahandle.cpp new file mode 100644 index 0000000..963e57e --- /dev/null +++ b/flow/gslpp/datahandle.cpp @@ -0,0 +1,412 @@ + /* + + Copyright (C) 2002 Hans Meine + hans_meine@gmx.net + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + */ + +#include "datahandle.h" +#include "../../mcop/debug.h" + +namespace GSL { + +void DataHandle::copyFrom(const DataHandle &other) +{ + handle_ = other.handle_; + if(handle_) + gsl_data_handle_ref(handle_); +} + +DataHandle::DataHandle(GslDataHandle *handle) + : handle_(handle) +{ +} + +DataHandle::DataHandle(const DataHandle &other) { copyFrom(other); } + +DataHandle &DataHandle::operator =(const DataHandle &other) +{ + if(!( other == *this )) { + if(handle_) + gsl_data_handle_unref(handle_); + copyFrom(other); + } + return *this; +} + +bool DataHandle::operator ==(const DataHandle &other) const +{ + return handle_ == other.handle_; +} + +bool DataHandle::isNull() const +{ + return handle_ == 0; +} + +DataHandle::~DataHandle() +{ + if(handle_) + gsl_data_handle_unref(handle_); +} + +gint DataHandle::open() +{ + arts_return_val_if_fail(handle_ != 0, -1); + + arts_debug("open()ing datahandle (open_count before: %d)..", + handle_->open_count); + + return gsl_data_handle_open(handle_); +} + +void DataHandle::close() +{ + arts_return_if_fail(handle_ != 0); + + arts_debug("close()ing datahandle (open_count before: %d)..", + handle_->open_count); + + gsl_data_handle_close(handle_); +} + +bool DataHandle::isOpen() const +{ + if(!handle_) + return false; + + return handle_->open_count != 0; +} + +GslLong DataHandle::read(GslLong valueOffset, GslLong valueCount, gfloat *values) +{ + arts_return_val_if_fail(handle_ != 0, 0); + + return gsl_data_handle_read(handle_, valueOffset, valueCount, values); +} + +DataHandle DataHandle::createCropped(GslLong headCutValueCount, + GslLong tailCutValueCount) +{ + arts_return_val_if_fail(handle_ != 0, null()); + + return DataHandle(gsl_data_handle_new_crop(handle_, + headCutValueCount, tailCutValueCount)); +} + +DataHandle DataHandle::createCut(GslLong cutOffset, + GslLong cutValueCount) +{ + arts_return_val_if_fail(handle_ != 0, null()); + + return DataHandle(gsl_data_handle_new_cut(handle_, cutOffset, + cutValueCount)); +} + +DataHandle DataHandle::createReversed() +{ + arts_return_val_if_fail(handle_ != 0, null()); + + return DataHandle(gsl_data_handle_new_reverse(handle_)); +} + +GslDataCache *DataHandle::createGslDataCache() +{ + arts_debug("wanna have cache with padding %d for each of %d channels..", + gsl_get_config()->wave_chunk_padding, + channelCount()); + return gsl_data_cache_from_dhandle(handle_, + gsl_get_config()->wave_chunk_padding * + channelCount()); +} + +GslLong DataHandle::valueCount() const +{ + arts_return_val_if_fail(handle_ != 0, 0); + arts_return_val_if_fail(isOpen(), 0); + + return handle_->setup.n_values; +} + +guint DataHandle::channelCount() const +{ + arts_return_val_if_fail(handle_ != 0, 0); + arts_return_val_if_fail(isOpen(), 0); + + return handle_->setup.n_channels; +} + +guint DataHandle::bitDepth() const +{ + arts_return_val_if_fail(handle_ != 0, 0); + arts_return_val_if_fail(isOpen(), 0); + + return handle_->setup.bit_depth; +} + +// ---------------------------------------------------------------------------- + +WaveChunkDescription::WaveChunkDescription(const GslWaveDsc *parent, guint index) + : parent_(parent), parentIndex_(index) +{ + if(index>parent->n_chunks) + { + arts_debug("wrong index given to WaveChunkDescription constructor, " + "using 0 instead.."); + parentIndex_ = 0; + } +} + +float WaveChunkDescription::oscillatorFrequency() +{ + return parent_->chunks[parentIndex_].osc_freq; +} + +float WaveChunkDescription::mixerFrequency() +{ + return parent_->chunks[parentIndex_].mix_freq; +} + +GslWaveLoopType WaveChunkDescription::loopType() +{ + return parent_->chunks[parentIndex_].loop_type; +} + +GslLong WaveChunkDescription::loopStart() +{ + return parent_->chunks[parentIndex_].loop_start; +} + +GslLong WaveChunkDescription::loopEnd() +{ + return parent_->chunks[parentIndex_].loop_end; +} + +guint WaveChunkDescription::loopCount() +{ + return parent_->chunks[parentIndex_].loop_count; +} + +WaveDataHandle WaveChunkDescription::createDataHandle() +{ + return WaveDataHandle(parent_, parentIndex_); +} + +// ---------------------------------------------------------------------------- + +/** + * We use GslWaveFileInfos' refcounting - probably this lazy + * construction happens only once, where the object is used. After + * copying it would have to be constructed again, but that's not + * likely to happen. (?) + */ +void WaveDescription::ensurePointer() const +{ + if(!desc_) + desc_ = gsl_wave_dsc_load(parentInfo_, parentIndex_, &error_); +} + +void WaveDescription::copyFrom(const WaveDescription &other) +{ + parentInfo_ = other.parentInfo_; + parentIndex_ = other.parentIndex_; + gsl_wave_file_info_ref(other.parentInfo_); +} + +// internal, private +WaveDescription::WaveDescription(GslWaveFileInfo *parent, guint index, + const std::string &name) + : parentInfo_(parent), name_(name), parentIndex_(index), + desc_(0), error_(GSL_ERROR_NONE) +{ + gsl_wave_file_info_ref(parentInfo_); +} + +WaveDescription::~WaveDescription() +{ + if(desc_) + gsl_wave_dsc_free(desc_); + gsl_wave_file_info_unref(parentInfo_); +} + +WaveDescription::WaveDescription(const WaveDescription &other) + : desc_(0), error_(GSL_ERROR_NONE) +{ + copyFrom(other); +} + +WaveDescription &WaveDescription::operator =(const WaveDescription &other) +{ + if(desc_) + gsl_wave_dsc_free(desc_); + gsl_wave_file_info_unref(parentInfo_); + copyFrom(other); + return *this; +} + +const std::string &WaveDescription::name() const +{ + return name_; +} + +GslErrorType WaveDescription::error() const +{ + ensurePointer(); + return error_; +} + +guint WaveDescription::chunkCount() const +{ + ensurePointer(); + return desc_ ? desc_->n_chunks : 0; +} + +WaveChunkDescription WaveDescription::chunkDescription(guint index) const +{ + ensurePointer(); + return WaveChunkDescription(desc_, index); +} + +guint WaveDescription::channelCount() const +{ + ensurePointer(); + return desc_ ? desc_->n_channels : 0; +} + +// ---------------------------------------------------------------------------- + +void WaveFileInfo::copyFrom(const WaveFileInfo &other) +{ + info_ = other.info_; + filename_ = other.filename_; + if(info_) + gsl_wave_file_info_ref(info_); + + error_ = other.error_; +} + +WaveFileInfo::WaveFileInfo(const std::string &filename) + : info_(0), error_(GSL_ERROR_NONE), filename_(filename) +{ + info_ = gsl_wave_file_info_load(filename.c_str(), &error_); +} + +WaveFileInfo::~WaveFileInfo() +{ + if(info_) + gsl_wave_file_info_unref(info_); +} + +WaveFileInfo::WaveFileInfo(const WaveFileInfo &other) +{ + copyFrom(other); +} + +WaveFileInfo &WaveFileInfo::operator =(const WaveFileInfo &other) +{ + if(info_) + gsl_wave_file_info_unref(info_); + copyFrom(other); + return *this; +} + +guint WaveFileInfo::waveCount() const +{ + return info_ ? info_->n_waves : 0; +} + +std::string WaveFileInfo::waveName(guint index) const +{ + if(index >= waveCount()) + return ""; + return info_->waves[index].name; +} + +WaveDescription WaveFileInfo::waveDescription(guint index) +{ + return WaveDescription(info_, index, waveName(index)); +} + +GslErrorType WaveFileInfo::error() const +{ + return error_; +} + +// ---------------------------------------------------------------------------- + +WaveDataHandle::WaveDataHandle() + : DataHandle(NULL), + oscillatorFrequency_(0), + mixerFrequency_(0) +{ +} + +WaveDataHandle::WaveDataHandle(const GslWaveDsc *waveDesc, guint chunkIndex) + : DataHandle(NULL), + oscillatorFrequency_(0), + mixerFrequency_(0) +{ + handle_ = gsl_wave_handle_create(const_cast<GslWaveDsc *>(waveDesc), + chunkIndex, &error_); + if(error() == GSL_ERROR_NONE) + { + oscillatorFrequency_ = waveDesc->chunks[chunkIndex].osc_freq; + mixerFrequency_ = waveDesc->chunks[chunkIndex].mix_freq; + } +} + +WaveDataHandle::WaveDataHandle(const std::string& filename, + guint waveIndex, + guint chunkIndex) + : DataHandle(NULL), + oscillatorFrequency_(0), + mixerFrequency_(0) +{ + GSL::WaveFileInfo info(filename); + error_ = info.error(); + + if(!info.error()) + { + GSL::WaveDescription desc= info.waveDescription(waveIndex); + error_ = desc.error(); + + if(!desc.error() && (desc.chunkCount() > chunkIndex)) + { + GSL::WaveChunkDescription chunkDesc= desc.chunkDescription(chunkIndex); + + (*this) = chunkDesc.createDataHandle(); + } + } +} + +GslErrorType WaveDataHandle::error() const +{ + return error_; +} + +float WaveDataHandle::oscillatorFrequency() const +{ + return oscillatorFrequency_; +} + +float WaveDataHandle::mixerFrequency() const +{ + return mixerFrequency_; +} + +} diff --git a/flow/gslpp/datahandle.h b/flow/gslpp/datahandle.h new file mode 100644 index 0000000..7cab930 --- /dev/null +++ b/flow/gslpp/datahandle.h @@ -0,0 +1,220 @@ + /* + + Copyright (C) 2002 Hans Meine + hans_meine@gmx.net + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + */ + +#ifndef GSLPP_DATAHANDLE_H +#define GSLPP_DATAHANDLE_H + +#include <gsl/gsldatahandle.h> +#include <gsl/gslloader.h> +#include <string> + +namespace GSL +{ + class WaveFileInfo; + class WaveDataHandle; + class WaveDescription; + + class DataHandle + { + protected: + GslDataHandle *handle_; + + void clearHandle(); + void copyFrom(const DataHandle &other); + + DataHandle(GslDataHandle *handle); + + public: + static DataHandle null() { return DataHandle(); } + + DataHandle(): handle_(0) {} + + DataHandle(const DataHandle &other); + + DataHandle &operator =(const DataHandle &other); + + bool operator ==(const DataHandle &other) const; + + bool isNull() const; + + virtual ~DataHandle(); + + /** + * returns error code with errno meaning + */ + virtual gint open(); + + virtual void close(); + + bool isOpen() const; + + /** + * read from this datahandle and fill buffer pointed to by + * values with sample data from the range + * [valueOffset..valueOffset+valueCount-1] + * + * returns number of sample values actually read, -1 on error + * (errno _may_ be useful then) + */ + virtual GslLong read(GslLong valueOffset, GslLong valueCount, gfloat *values); + + /** + * Create a new data handle by chopping off headCutValueCount + * values at the start, and tailCutValueCount values at the + * end of this data handle. + */ + DataHandle createCropped(GslLong headCutValueCount, + GslLong tailCutValueCount); + + /** + * Create a new data handle by removing the values + * [cutOffset..cutOffset+cutValueCount-1]. + */ + DataHandle createCut(GslLong cutOffset, + GslLong cutValueCount); + + /** + * Create a new data handle which contains the same values as + * this one but in reversed order. + */ + DataHandle createReversed(); + + // this will maybe be made private in the future, having a + // better interface instead + GslDataCache *createGslDataCache(); + + GslLong valueCount() const; + + guint bitDepth() const; + + guint channelCount() const; + }; + + class WaveChunkDescription + { + friend class WaveDescription; + + const GslWaveDsc *parent_; + guint parentIndex_; + + WaveChunkDescription(const GslWaveDsc *parent, guint index); + + public: + float oscillatorFrequency(); + float mixerFrequency(); + + GslWaveLoopType loopType(); + GslLong loopStart(); /* sample offset */ + GslLong loopEnd(); /* sample offset */ + guint loopCount(); + + WaveDataHandle createDataHandle(); + }; + + class WaveDescription + { + friend class WaveFileInfo; // for construction of WaveDescriptions + + mutable GslWaveFileInfo *parentInfo_; // mutable for ensurePointer() + std::string name_; + guint parentIndex_; + mutable GslWaveDsc *desc_; + mutable GslErrorType error_; + + void ensurePointer() const; // lazy construction + + void copyFrom(const WaveDescription &other); + + WaveDescription(GslWaveFileInfo *parent, guint index, const std::string &name); + + public: + ~WaveDescription(); + + WaveDescription(const WaveDescription &other); + + WaveDescription &operator =(const WaveDescription &other); + + const std::string &name() const; + + GslErrorType error() const; + + guint chunkCount() const; + + WaveChunkDescription chunkDescription(guint index) const; + + guint channelCount() const; + }; + + class WaveFileInfo + { + GslWaveFileInfo *info_; + GslErrorType error_; + std::string filename_; + + void copyFrom(const WaveFileInfo &other); + + public: + WaveFileInfo(const std::string &filename); + + ~WaveFileInfo(); + + WaveFileInfo(const WaveFileInfo &other); + + WaveFileInfo &operator =(const WaveFileInfo &other); + + guint waveCount() const; + + std::string waveName(guint index) const; + + WaveDescription waveDescription(guint index); + + GslErrorType error() const; + }; + + class WaveDataHandle: public DataHandle + { + friend class WaveChunkDescription; + + GslErrorType error_; + + float oscillatorFrequency_; + float mixerFrequency_; + + WaveDataHandle(); + WaveDataHandle(const GslWaveDsc *waveDesc, guint chunkIndex = 0); + + public: + WaveDataHandle(const std::string& filename, + guint waveIndex = 0, + guint chunkIndex = 0); + + static WaveDataHandle null() { return WaveDataHandle(); } + + GslErrorType error() const; + + float oscillatorFrequency() const; + + float mixerFrequency() const; + }; +} + +#endif // GSLPP_DATAHANDLE_H |