Buffer.h

Go to the documentation of this file.
00001 
00002 //
00003 //  $Id: Buffer.h 718 2012-04-15 23:59:35Z weegreenblobbie $
00004 //
00005 //  Nsound is a C++ library and Python module for audio synthesis featuring
00006 //  dynamic digital filters. Nsound lets you easily shape waveforms and write
00007 //  to disk or plot them. Nsound aims to be as powerful as Csound but easy to
00008 //  use.
00009 //
00010 //  Copyright (c) 2004-Present Nick Hilton
00011 //
00012 //  weegreenblobbie_yahoo_com (replace '_' with '@' and '.')
00013 //
00015 
00017 //
00018 //  This program is free software; you can redistribute it and/or modify
00019 //  it under the terms of the GNU General Public License as published by
00020 //  the Free Software Foundation; either version 2 of the License, or
00021 //  (at your option) any later version.
00022 //
00023 //  This program is distributed in the hope that it will be useful,
00024 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00025 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00026 //  GNU Library General Public License for more details.
00027 //
00028 //  You should have received a copy of the GNU General Public License
00029 //  along with this program; if not, write to the Free Software
00030 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00031 //
00033 #ifndef _NSOUND_BUFFER_H_
00034 #define _NSOUND_BUFFER_H_
00035 
00036 #include <Nsound/Nsound.h>
00037 #include <Nsound/BufferSelection.h>
00038 
00039 #include <cmath>
00040 #include <iostream>
00041 #include <string>
00042 #include <vector>
00043 
00044 namespace Nsound
00045 {
00046 
00047 typedef std::vector< uint32 > Uint32Vector;
00048 typedef std::vector< float64 > FloatVector;
00049 
00050 // Forward declaration
00051 class AudioStream;
00052 
00055 //
00061 class Buffer
00062 {
00063     public:
00064 
00065     // Forward declaration
00066     class circular_iterator;
00067 
00068     typedef FloatVector::iterator         iterator;
00069     typedef FloatVector::const_iterator   const_iterator;
00070 
00073     //
00085     Buffer();
00086     explicit Buffer(uint32 chunk_size);
00087 
00090     //
00108     explicit Buffer(const FloatVector & list);
00109 
00112     //
00124     Buffer(const std::string & filename, uint32 chunk_size = 4096);
00125 
00128     ~Buffer();
00129 
00132     //
00144     Buffer(const Buffer & rhs);
00145 
00148     //
00159     void
00160     abs();
00161 
00164     //
00175     Buffer
00176     getAbs() const
00177     { Buffer temp(*this); temp.abs(); return temp; };
00178 
00180     // add()
00181     //
00183     //
00237     //
00238     void
00239     add(const Buffer & buffer,
00240         uint32 offset = 0,
00241         uint32 n_samples = 0);
00242 
00245     //
00256     uint32
00257     argmax() const;
00258 
00261     //
00272     uint32
00273     argmin() const;
00274 
00277     //
00289     inline
00290     iterator
00291     begin()
00292     { return data_.begin(); };
00293 
00296     //
00308     inline
00309     const_iterator
00310     begin() const
00311     { return data_.begin(); };
00312 
00315     //
00324     inline
00325     circular_iterator
00326     cbegin()
00327     { return circular_iterator(data_.begin(), data_.end()); };
00328 
00331     //
00340     inline
00341     circular_iterator
00342     cbegin() const
00343     { return circular_iterator(data_.begin(), data_.end()); };
00344 
00347     //
00356     inline
00357     iterator
00358     end()
00359     { return data_.end(); };
00360 
00363     //
00372     inline
00373     const_iterator
00374     end() const
00375     { return data_.end(); };
00376 
00379     //
00390     inline
00391     uint32
00392     getNBytes() const
00393     { return bytes_per_sample_ * data_.size(); };
00394 
00397     //
00411     void
00412     exp();
00413 
00416     //
00430     Buffer
00431     getExp() const
00432     { Buffer temp(*this); temp.exp(); return temp; };
00433 
00436     //
00451     void
00452     convolve(const Buffer & H);
00453 
00456     //
00471     Buffer
00472     getConvolve(const Buffer & H) const;
00473 
00476     //
00488     void
00489     dB();
00490 
00493     //
00504     Buffer
00505     getdB() const
00506     { Buffer temp(*this); temp.dB(); return temp; };
00507 
00510     //
00521     void
00522     derivative(uint32 n);
00523 
00526     //
00537     Buffer
00538     getDerivative(uint32 n) const
00539     { Buffer temp(*this); temp.derivative(n); return temp; };
00540 
00543     //
00554     void
00555     downSample(uint32 n);
00556 
00559     //
00570     Buffer
00571     getDownSample(uint32 n) const;
00572 
00575     //
00586     Uint32Vector
00587     findPeaks(
00588         uint32 window_size = 0,
00589         const float64 & min_height = 0.0) const;
00590 
00591 //~    Experimental, doesn't work yet
00592 //~    ///////////////////////////////////////////////////////////////////////////
00593 //~    //! Returns the estimated fundamental frequency of the Buffer.
00594 //~    Buffer
00595 //~    findPitch(const float64 & sample_rate);
00596 
00599     //
00610     inline
00611     uint32
00612     getLength() const
00613     { return data_.size(); };
00614 
00617     //
00628     void
00629     limit(const float64 & min, const float64 & max);
00630 
00633     //
00649     void
00650     limit(const Buffer & min, const Buffer & max);
00651 
00654     //
00665     Buffer
00666     getLimit(const float64 & min, const float64 & max) const
00667     { Buffer temp(*this); temp.limit(min, max); return temp; };
00668 
00671     //
00687     Buffer
00688     getLimit(const Buffer & min, const Buffer & max) const
00689     { Buffer temp(*this); temp.limit(min, max); return temp; };
00690 
00693     //
00704     void
00705     log();
00706 
00709     //
00720     Buffer
00721     getLog() const
00722     { Buffer temp(*this); temp.log(); return temp; };
00723 
00726     //
00737     void
00738     log10();
00739 
00742     //
00753     Buffer
00754     getLog10() const
00755     { Buffer temp(*this); temp.log10(); return temp; };
00756 
00759     //
00770     float64
00771     getMax() const;
00772 
00775     //
00786     float64
00787     getMaxMagnitude() const;
00788 
00791     //
00802     float64
00803     getMean() const;
00804 
00807     //
00818     float64
00819     getMin() const;
00820 
00823     //
00834     void
00835     normalize();
00836 
00839     //
00850     Buffer
00851     getNormalize() const
00852     { Buffer temp(*this); temp.normalize(); return temp; };
00853 
00856     //
00867     Buffer
00868     getSignalEnergy(uint32 window_size) const;
00869 
00872     //
00883     float64
00884     getStd() const;
00885 
00888     //
00899     float64
00900     getSum() const;
00901 
00904     //
00917     void
00918     zNorm();
00919 
00922     //
00935     Buffer
00936     getZNorm() const
00937     { Buffer temp(*this); temp.zNorm(); return temp; };
00938 
00941     //
00952     BufferSelection
00953     operator()(const BooleanVector & bv);
00954 
00957     Buffer &
00958     operator=(const Buffer & rhs);
00959 
00962     boolean
00963     operator==(const Buffer & rhs) const;
00964 
00967     boolean
00968     operator!=(const Buffer & rhs) const;
00969 
00972     inline
00973     const float64
00974     operator[](uint32 index) const
00975     { return data_[index]; };
00976 
00979     inline
00980     float64 &
00981     operator[](uint32 index)
00982     { return data_[index]; };
00983 
00986     //
00999     Buffer &
01000     operator<<(const AudioStream & rhs);
01001 
01004     //
01017     Buffer &
01018     operator<<(const Buffer & rhs);
01019 
01020     Buffer &
01021     operator<<=(const Buffer & rhs);
01022 
01025     inline
01026     Buffer &
01027     operator<<(const float64 & d)
01028     { data_.push_back(d); return *this; };
01029 
01032     inline
01033     Buffer &
01034     operator<<=(const float64 & d)
01035     { data_.push_back(d); return *this; };
01036 
01039     //
01055     Buffer & operator+=(const Buffer & rhs);
01056 
01059     //
01075     Buffer & operator-=(const Buffer & rhs);
01076 
01079     //
01095     Buffer & operator*=(const Buffer & rhs);
01096 
01099     //
01115     Buffer & operator/=(const Buffer & rhs);
01116 
01119     //
01135     Buffer & operator^=(const Buffer & powers);
01136 
01139     //
01150     Buffer & operator+=(const float64 & d);
01151 
01154     //
01165     Buffer & operator-=(const float64 & d);
01166 
01169     //
01180     Buffer & operator*=(const float64 & d);
01181 
01184     //
01195     Buffer & operator/=(const float64 & d);
01196 
01199     //
01228     Buffer & operator^=(const float64 & power);
01229 
01230     #ifndef SWIG
01231 
01232 
01233         friend
01234         std::ostream &
01235         operator<<(std::ostream & out,const Buffer & rhs);
01236     #endif
01237 
01240     //
01251     BooleanVector operator>(const float64 & rhs);
01252 
01255     //
01266     BooleanVector operator>=(const float64 & rhs);
01267 
01270     //
01281     BooleanVector operator<(const float64 & rhs);
01282 
01285     //
01296     BooleanVector operator<=(const float64 & rhs);
01297 
01300     //
01311     BooleanVector operator==(const float64 & rhs);
01312 
01315     //
01326     BooleanVector operator!=(const float64 & rhs);
01327 
01328     //~    ///////////////////////////////////////////////////////////////////////////
01329     //~    //! EXPERIMENTAL!  Transforms the Buffer to the frequency domain and shifts it by n_bins_to_shift and then transforms it back to the time domain.
01330     //~    //
01331     //~    //! \par Example:
01332     //~    //! \code
01333     //~    //! // C++
01334     //~    //! Buffer b1("california.wav");
01335     //~    //! b1.pitchShift(2048, 2048, 2);
01336     //~    //!
01337     //~    //! // Python
01338     //~    //! b1 = Buffer("california.wav")
01339     //~    //! b1.pitchShift(2048, 2048, 2)
01340     //~    //! \endcode
01341     //~    void
01342     //~    pitchShift(uint32 window_size, uint32 fft_size, int32 n_bins_to_shift );
01343     //~
01344     //~    ///////////////////////////////////////////////////////////////////////////
01345     //~    //! EXPERIMENTAL!  Transforms a copy of the Buffer to the frequency domain and shifts it by n_bins_to_shift and then transforms it back to the time domain.
01346     //~    //
01347     //~    //! \par Example:
01348     //~    //! \code
01349     //~    //! // C++
01350     //~    //! Buffer b1("california.wav");
01351     //~    //! Buffer b2 = b1.getPitchShift(2048, 2048, 2);
01352     //~    //!
01353     //~    //! // Python
01354     //~    //! b1 = Buffer("california.wav")
01355     //~    //! b2 = b1.getPitchShift(2048, 2048, 2)
01356     //~    //! \endcode
01357     //~    Buffer
01358     //~    getPitchShift(uint32 window_size, uint32 fft_size, int32 n_bins_to_shift) const
01359     //~    { Buffer temp(*this);
01360     //~        temp.pitchShift(window_size, fft_size, n_bins_to_shift); return temp;};
01361 
01364     //
01377     void
01378     plot(const std::string & title = "Buffer") const;
01379 
01382     //
01391     const
01392     float64 *
01393     getPointer() const
01394     { return &(data_[0]); }
01395 
01398     //
01408     float64 *
01409     getPointer()
01410     { return &(data_[0]); }
01411 
01414     //
01427     void
01428     preallocate(uint32 n);
01429 
01432     //
01444     void
01445     readWavefile(const char * filename);
01446 
01449     //
01460     void
01461     resample(const float64 & factor)
01462     { *this = getResample(factor, 10, 5.0); };
01463 
01466     //
01482     void
01483     resample(const Buffer & factor)
01484     { *this = getResample(factor, 10, 5.0); };
01485 
01488     //
01499     Buffer
01500     getResample(
01501         const float64 & factor,
01502         const uint32 N = 10,
01503         const float64 & beta = 5.0) const;
01504 
01507     //
01523     Buffer
01524     getResample(
01525         const Buffer & factor,
01526         const uint32 N = 10,
01527         const float64 & beta = 5.0) const;
01528 
01531     //
01542     Buffer
01543     getResample(
01544         const uint32 L,
01545         const uint32 M,
01546         const uint32 N = 10,
01547         const float64 & beta = 5.0) const;
01548 
01551     //
01562     void
01563     reverse();
01564 
01567     //
01578     Buffer
01579     getReverse() const
01580     { Buffer temp(*this); temp.reverse(); return temp; };
01581 
01584     //
01597     void
01598     round();
01599 
01602     //
01615     Buffer
01616     getRound() const
01617     { Buffer temp(*this); temp.round(); return temp; };
01618 
01621     //
01635     BufferSelection
01636     select(const uint32 start_index, const uint32 stop_index);
01637 
01640     //
01654     void
01655     smooth(uint32 n_passes, uint32 n_samples_per_average);
01656 
01659     //
01673     Buffer
01674     getSmooth(uint32 n_passes, uint32 n_samples_per_average) const
01675     { Buffer temp(*this); temp.smooth(n_passes, n_samples_per_average); return temp; };
01676 
01679     //
01692     void
01693     speedUp(const float64 & step_size);
01694 
01697     //
01710     Buffer
01711     getSpeedUp(const float64 & step_size) const
01712     { Buffer temp(*this); temp.speedUp(step_size); return temp; };
01713 
01716     //
01732     void
01733     speedUp(const Buffer & step_size);
01734 
01737     //
01753     Buffer
01754     getSpeedUp(const Buffer & step_size) const
01755     { Buffer temp(*this); temp.speedUp(step_size); return temp; };
01756 
01759     //
01770     void
01771     sqrt();
01772 
01775     //
01786     Buffer
01787     getSqrt() const
01788     { Buffer temp(*this); temp.sqrt(); return temp; };
01789 
01792     //
01805     Buffer
01806     subbuffer(uint32 start_index, uint32 n_samples = 0) const;
01807 
01810     //
01821     void
01822     upSample(uint32 n);
01823 
01826     //
01837     Buffer
01838     getUpSample(uint32 n) const;
01839 
01842     //
01853     void
01854     writeWavefile(const char * filename) const;
01855 
01856     #ifndef SWIG
01857 
01858 
01859     //
01874     class circular_iterator
01875     {
01877         public:
01878 
01880         circular_iterator()
01881             : begin_(), end_(), iter_(){};
01882 
01884         circular_iterator(const circular_iterator & copy);
01885 
01887         circular_iterator(const FloatVector & v);
01888 
01890         circular_iterator(
01891             const FloatVector::const_iterator & begin,
01892             const FloatVector::const_iterator & end);
01893 
01895         circular_iterator &
01896         operator++();
01897 
01899         circular_iterator &
01900         operator+=(const int32 i);
01901 
01903         circular_iterator
01904         operator+(const int32 i);
01905 
01907         circular_iterator &
01908         operator--();
01909 
01911         circular_iterator &
01912         operator-=(const int32 i);
01913 
01915         circular_iterator
01916         operator-(const int32 i);
01917 
01919         circular_iterator &
01920         operator=(const circular_iterator & rhs);
01921 
01923         boolean
01924         operator==(const circular_iterator & rhs)
01925         { return iter_ == rhs.iter_; };
01926 
01928         boolean
01929         operator!=(const circular_iterator & rhs)
01930         { return iter_ != rhs.iter_; };
01931 
01933         boolean
01934         operator==(const FloatVector::const_iterator & rhs)
01935         { return iter_ == rhs; };
01936 
01938         boolean
01939         operator!=(const FloatVector::const_iterator & rhs)
01940         { return iter_ != rhs; };
01941 
01943         inline
01944         const FloatVector::value_type
01945         operator*() const
01946         { return *iter_; };
01947 
01950         void
01951         reset()
01952         { iter_ = begin_; };
01953 
01955         protected:
01956 
01957         FloatVector::const_iterator begin_;
01958         FloatVector::const_iterator end_;
01959         FloatVector::const_iterator iter_;
01960 
01961     }; // const_circular_iterator
01962     #endif
01963 
01965     float64
01966     get_at_index(int32 index) const;
01967 
01969     void
01970     set_at_index(int32 index, const float64 & d);
01971 
01973     void swig_hook(){};
01974 
01976     static
01977     Buffer
01978     ones(const uint32 n_samples);
01979 
01981     static
01982     Buffer
01983     rand(const uint32 n_samples);
01984 
01986     static
01987     Buffer
01988     zeros(const uint32 n_samples);
01989 
01991     protected:
01992 
01993     Buffer
01994     getResample_(
01995         const uint32 L,
01996         const uint32 M,
01997         const uint32 N,
01998         const float64 & beta) const;
01999 
02000     // DOXME
02001     enum MathOperator
02002     {
02003             ADD,
02004             SUBTRACT,
02005             MULTIPLY,
02006             DIVIDE,
02007             POW
02008     };
02009 
02010     Buffer &
02011     vectorOperator(const Buffer & rhs, MathOperator op);
02012 
02013     Buffer &
02014     scalarOperator(const float64 & d, MathOperator op);
02015 
02016     FloatVector data_;
02017 
02018     static const uint32 bytes_per_sample_ = sizeof(float64);
02019 
02020 }; // class Buffer
02021 
02022 
02023 
02025 // Non class methods
02027 
02029 inline Buffer operator+(const Buffer & lhs, const Buffer & rhs)
02030 {
02031     Buffer temp(lhs);
02032     return temp += rhs;
02033 }
02034 
02036 inline Buffer operator-(const Buffer & lhs, const Buffer & rhs)
02037 {
02038     Buffer temp(lhs);
02039     return temp -= rhs;
02040 }
02041 
02043 inline Buffer operator*(const Buffer & lhs, const Buffer & rhs)
02044 {
02045     Buffer temp(lhs);
02046     return temp *= rhs;
02047 }
02048 
02050 inline Buffer operator/(const Buffer & lhs, const Buffer & rhs)
02051 {
02052     Buffer temp(lhs);
02053     return temp /= rhs;
02054 }
02055 
02057 inline Buffer operator^(const Buffer & lhs, const Buffer & rhs)
02058 {
02059     Buffer temp(lhs);
02060     return temp ^= rhs;
02061 }
02062 
02063 // Scalar operators
02064 
02066 inline Buffer operator+(const Buffer & lhs, const float64 & d)
02067 {
02068     Buffer temp(lhs);
02069     return temp += d;
02070 }
02071 
02073 inline Buffer operator-(const Buffer & lhs, const float64 & d)
02074 {
02075     Buffer temp(lhs);
02076     return temp -= d;
02077 }
02078 
02080 inline Buffer operator*(const Buffer & lhs, const float64 & d)
02081 {
02082     Buffer temp(lhs);
02083     return temp *= d;
02084 }
02085 
02087 inline Buffer operator/(const Buffer & lhs, const float64 & d)
02088 {
02089     Buffer temp(lhs);
02090     return temp /= d;
02091 }
02092 
02095 //
02124 inline Buffer operator^(const Buffer & lhs, const float64 & d)
02125 {
02126     Buffer temp(lhs);
02127     return temp ^= d;
02128 }
02129 
02130 // Reverse scalar operators
02131 
02133 inline Buffer operator+(const float64 & d, const Buffer & rhs)
02134 {
02135     return rhs + d;
02136 }
02137 
02139 inline Buffer operator-(const float64 & d, const Buffer & rhs)
02140 {
02141     return (rhs * -1.0) + d;
02142 }
02143 
02145 inline Buffer operator*(const float64 & d, const Buffer & rhs)
02146 {
02147     return rhs * d;
02148 }
02149 
02151 inline Buffer operator/(const float64 & d, const Buffer & rhs)
02152 {
02153     Buffer temp(rhs);
02154 
02155     uint32 size = rhs.getLength();
02156 
02157     for(uint32 i = 0; i < size; ++i)
02158     {
02159         temp[i] = d / rhs[i];
02160     }
02161 
02162     return temp;
02163 }
02164 
02166 inline Buffer operator^(const float64 & d, const Buffer & rhs)
02167 {
02168     Buffer temp(rhs);
02169 
02170     uint32 size = rhs.getLength();
02171 
02172     for(uint32 i = 0; i < size; ++i)
02173     {
02174         temp[i] = ::pow(d ,rhs[i]);
02175     }
02176 
02177     return temp;
02178 }
02179 
02180 // DOXME
02181 typedef std::vector<Buffer>   BufferVector;
02182 typedef std::vector<Buffer *> BufferPointerVector;
02183 
02184 // Friends
02185 std::ostream &
02186 operator<<(std::ostream & out, const Buffer & rhs);
02187 
02188 }; // Namespace Nsound
02189 
02190 
02191 // :mode=c++: jEdit modeline
02192 #endif
Generated on Sun Apr 15 20:10:05 2012 for nsound by  doxygen 1.6.3