From d6073e01c933c77f1e2bc3c3fe1126d617003549 Mon Sep 17 00:00:00 2001 From: John Glover Date: Fri, 8 Jul 2011 18:06:21 +0100 Subject: Start adding Loris files --- src/loris/AiffFile.h | 388 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 388 insertions(+) create mode 100644 src/loris/AiffFile.h (limited to 'src/loris/AiffFile.h') diff --git a/src/loris/AiffFile.h b/src/loris/AiffFile.h new file mode 100644 index 0000000..55c2bc7 --- /dev/null +++ b/src/loris/AiffFile.h @@ -0,0 +1,388 @@ +/* + * This is the Loris C++ Class Library, implementing analysis, + * manipulation, and synthesis of digitized sounds using the Reassigned + * Bandwidth-Enhanced Additive Sound Model. + * + * Loris is Copyright (c) 1999-2010 by Kelly Fitz and Lippold Haken + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * + * AiffFile.h + * + * Definition of AiffFile class for sample import and export in Loris. + * + * Kelly Fitz, 8 Jan 2003 + * loris@cerlsoundgroup.org + * + * http://www.cerlsoundgroup.org/Loris/ + * + */ +#include "Marker.h" +#include "Synthesizer.h" + +#if defined(NO_TEMPLATE_MEMBERS) +#include "PartialList.h" +#endif + +#include +#include +#include + +// begin namespace +namespace Loris { + +class Partial; + +// --------------------------------------------------------------------------- +// class AiffFile +// +//! Class AiffFile represents sample data in a AIFF-format samples +//! file, and manages file I/O and sample conversion. Since the sound +//! analysis and synthesis algorithms in Loris and the reassigned +//! bandwidth-enhanced representation are monaural, AiffFile imports +//! only monaural (single channel) AIFF-format samples files, though +//! it can create and export a new two-channel file from a pair of +//! sample vectors. +// +class AiffFile +{ +// -- public interface -- +public: + +// -- types -- + + //! The type of the sample storage in an AiffFile. + typedef std::vector< double > samples_type; + + //! The type of all size parameters for AiffFile. + typedef samples_type::size_type size_type; + + //! The type of AIFF marker storage in an AiffFile. + typedef std::vector< Marker > markers_type; + +// -- construction -- + + //! Initialize an instance of AiffFile by importing sample data from + //! the file having the specified filename or path. + //! + //! \param filename is the name or path of an AIFF samples file + explicit AiffFile( const std::string & filename ); + + //! Initialize an instance of AiffFile with samples rendered + //! from a sequnence of Partials. The Partials in the + //! specified half-open (STL-style) range are rendered at + //! the specified sample rate, using the (optionally) + //! specified Partial fade time (see Synthesizer.h + //! for an examplanation of fade time). Other synthesis + //! parameters are taken from the Synthesizer DefaultParameters. + //! + //! \sa Synthesizer::DefaultParameters + //! + //! \param begin_partials is the beginning of a sequence of Partials + //! \param end_partials is (one-past) the end of a sequence of + //! Partials + //! \param samplerate is the rate (Hz) at which Partials are rendered + //! \param fadeTime is the Partial fade time (seconds) for rendering + //! the Partials on the specified range. If unspecified, the + //! fade time is taken from the Synthesizer DefaultParameters. + //! + //! If compiled with NO_TEMPLATE_MEMBERS defined, this member accepts + //! only PartialList::const_iterator arguments. +#if !defined(NO_TEMPLATE_MEMBERS) + template + AiffFile( Iter begin_partials, Iter end_partials, + double samplerate, double fadeTime = FadeTimeUnspecified ); +#else + AiffFile( PartialList::const_iterator begin_partials, + PartialList::const_iterator end_partials, + double samplerate, double fadeTime = FadeTimeUnspecified ); +#endif + + //! Initialize an instance of AiffFile having the specified sample + //! rate, preallocating numFrames samples, initialized to zero. + //! + //! \param samplerate is the rate at which Partials are rendered + //! \param numFrames is the initial number of (zero) samples. If + //! unspecified, no samples are preallocated. + //! \param numChannels is the number of channels of audio data + //! to preallocate (default 1 channel) + AiffFile( double samplerate, size_type numFrames = 0, + unsigned int numChannels = 1 ); + + //! Initialize an instance of AiffFile from a buffer of sample + //! data, with the specified sample rate. + //! + //! \param buffer is a pointer to a buffer of floating point samples. + //! \param bufferlength is the number of samples in the buffer. + //! \param samplerate is the sample rate of the samples in the buffer. + AiffFile( const double * buffer, size_type bufferlength, double samplerate ); + + //! Initialize an instance of AiffFile from two buffers of sample + //! data, with the specified sample rate. Both buffers must store + //! the same number (bufferLength) of samples. + //! + //! \param buffer_left is a pointer to a buffer of floating point samples + //! representing the left channel samples. + //! \param buffer_right is a pointer to a buffer of floating point samples + //! representing the right channel samples. + //! \param bufferlength is the number of samples in the buffer. + //! \param samplerate is the sample rate of the samples in the buffer. + // + AiffFile( const double * buffer_left, const double * buffer_right, + size_type bufferlength, double samplerate ); + + //! Initialize an instance of AiffFile from a vector of sample + //! data, with the specified sample rate. + //! + //! \param vec is a vector of floating point samples. + //! \param samplerate is the sample rate of the samples in the vector. + AiffFile( const std::vector< double > & vec, double samplerate ); + + //! Initialize an instance of AiffFile from two vectors of sample + //! data, with the specified sample rate. If the two vectors have different + //! lengths, the shorter one is padded with zeros. + //! + //! \param vec_left is a vector of floating point samples representing the + //! left channel samples. + //! \param vec_right is a vector of floating point samples representing the + //! right channel samples. + //! \param samplerate is the sample rate of the samples in the vectors. + // + AiffFile( const std::vector< double > & vec_left, + const std::vector< double > & vec_right, + double samplerate ); + + //! Initialize this and AiffFile that is an exact copy, having + //! all the same sample data, as another AiffFile. + //! + //! \param other is the AiffFile to copy + AiffFile( const AiffFile & other ); + + //! Assignment operator: change this AiffFile to be an exact copy + //! of the specified AiffFile, rhs, that is, having the same sample + //! data. + //! + //! \param rhs is the AiffFile to replicate + AiffFile & operator= ( const AiffFile & rhs ); + +// -- access -- + + //! Return a reference to the Marker (see Marker.h) container + //! for this AiffFile. + markers_type & markers( void ); + + //! Return a const reference to the Marker (see Marker.h) container + //! for this AiffFile. + const markers_type & markers( void ) const; + + //! Return the fractional MIDI note number assigned to this AiffFile. + //! If the sound has no definable pitch, note number 60.0 is used. + double midiNoteNumber( void ) const; + + //! Return the number of channels of audio samples represented by + //! this AiffFile, 1 for mono, 2 for stereo. + unsigned int numChannels( void ) const; + + //! Return the number of sample frames represented in this AiffFile. + //! A sample frame contains one sample per channel for a single sample + //! interval (e.g. mono and stereo samples files having a sample rate of + //! 44100 Hz both have 44100 sample frames per second of audio samples). + size_type numFrames( void ) const; + + //! Bad old legacy name for numFrames. + //! \deprecated Use numFrames instead. + size_type sampleFrames( void ) const { return numFrames(); } + + //! Return the sampling freqency in Hz for the sample data in this + //! AiffFile. + double sampleRate( void ) const; + + //! Return a reference (or const reference) to the vector containing + //! the floating-point sample data for this AiffFile. + samples_type & samples( void ); + + //! Return a const reference (or const reference) to the vector containing + //! the floating-point sample data for this AiffFile. + const samples_type & samples( void ) const; + +// -- mutation -- + + //! Render the specified Partial using the (optionally) specified + //! Partial fade time (see Synthesizer.h for an examplanation + //! of fade time), and accumulate the resulting samples into + //! the sample vector for this AiffFile. Other synthesis parameters + //! are taken from the Synthesizer DefaultParameters. + //! + //! \sa Synthesizer::DefaultParameters + //! + //! \param p is the partial to render into this AiffFile + //! \param fadeTime is the Partial fade time for rendering + //! the Partials on the specified range. If unspecified, the + //! fade time is taken from the Synthesizer DefaultParameters. + void addPartial( const Loris::Partial & p, double fadeTime = FadeTimeUnspecified ); + + //! Accumulate samples rendered from a sequence of Partials. + //! The Partials in the specified half-open (STL-style) range are + //! rendered at this AiffFile's sample rate, using the (optionally) + //! specified Partial fade time (see Synthesizer.h for an examplanation + //! of fade time). Other synthesis parameters are taken from the + //! Synthesizer DefaultParameters. + //! + //! \sa Synthesizer::DefaultParameters + //! + //! \param begin_partials is the beginning of a sequence of Partials + //! \param end_partials is (one-past) the end of a sequence of + //! Partials + //! \param fadeTime is the Partial fade time for rendering + //! the Partials on the specified range. If unspecified, the + //! fade time is taken from the Synthesizer DefaultParameters. + //! + //! If compiled with NO_TEMPLATE_MEMBERS defined, this member accepts + //! only PartialList::const_iterator arguments. +#if !defined(NO_TEMPLATE_MEMBERS) + template + void addPartials( Iter begin_partials, Iter end_partials, + double fadeTime = FadeTimeUnspecified ); +#else + void addPartials( PartialList::const_iterator begin_partials, + PartialList::const_iterator end_partials, + double fadeTime = FadeTimeUnspecified ); +#endif + + //! Set the fractional MIDI note number assigned to this AiffFile. + //! If the sound has no definable pitch, use note number 60.0 (the default). + //! + //! \param nn is a fractional MIDI note number, 60 is middle C. + void setMidiNoteNumber( double nn ); + +// -- export -- + + //! Export the sample data represented by this AiffFile to + //! the file having the specified filename or path. Export + //! signed integer samples of the specified size, in bits + //! (8, 16, 24, or 32). + //! + //! \param filename is the name or path of the AIFF samples file + //! to be created or overwritten. + //! \param bps is the number of bits per sample to store in the + //! samples file (8, 16, 24, or 32).If unspeicified, 16 bits + void write( const std::string & filename, unsigned int bps = 16 ); + +private: +// -- implementation -- + double notenum_, rate_; // MIDI note number and sample rate + unsigned int numchans_; + markers_type markers_; // AIFF Markers + samples_type samples_; // floating point samples [-1.0, 1.0] + + +// -- helpers -- + + // Construct a Synthesizer for rendering Partials and set its fadeTime. + // Modify the default synthesizer parameters with this file's sample rate + // and, if specified (not equal to FadeTimeUnspecified), the fade time. + Synthesizer configureSynthesizer( double fadeTime ); + + // Import data from an AIFF file on disk. + void readAiffData( const std::string & filename ); + + enum { FadeTimeUnspecified = -9999999 }; + // This is not pretty, but it is better (perhaps) than defining two + // of every member having an optional fade time parameter. + +}; // end of class AiffFile + +// -- template members -- + +// --------------------------------------------------------------------------- +// constructor from Partial range +// --------------------------------------------------------------------------- +//! Initialize an instance of AiffFile with samples rendered +//! from a sequnence of Partials. The Partials in the +//! specified half-open (STL-style) range are rendered at +//! the specified sample rate, using the (optionally) +//! specified Partial fade time (see Synthesizer.h +//! for an examplanation of fade time). Other synthesis +//! parameters are taken from the Synthesizer DefaultParameters. +//! +//! \sa Synthesizer::DefaultParameters +//! +//! \param begin_partials is the beginning of a sequence of Partials +//! \param end_partials is (one-past) the end of a sequence of +//! Partials +//! \param samplerate is the rate (Hz) at which Partials are rendered +//! \param fadeTime is the Partial fade time (seconds) for rendering +//! the Partials on the specified range. If unspecified, the +//! fade time is taken from the Synthesizer DefaultParameters. +//! +//! If compiled with NO_TEMPLATE_MEMBERS defined, this member accepts +//! only PartialList::const_iterator arguments. +// +#if !defined(NO_TEMPLATE_MEMBERS) +template< typename Iter > + AiffFile::AiffFile( Iter begin_partials, Iter end_partials, + double samplerate, double fadeTime ) : +#else + AiffFile::AiffFile( PartialList::const_iterator begin_partials, + PartialList::const_iterator end_partials, + double samplerate, double fadeTime ) : +#endif +// initializers: + notenum_( 60 ), + rate_( samplerate ), + numchans_( 1 ) +{ + addPartials( begin_partials, end_partials, fadeTime ); +} + +// --------------------------------------------------------------------------- +// addPartials +// --------------------------------------------------------------------------- +//! Accumulate samples rendered from a sequence of Partials. +//! The Partials in the specified half-open (STL-style) range are +//! rendered at this AiffFile's sample rate, using the (optionally) +//! specified Partial fade time (see Synthesizer.h for an examplanation +//! of fade time). Other synthesis parameters are taken from the +//! Synthesizer DefaultParameters. +//! +//! \sa Synthesizer::DefaultParameters +//! +//! \param begin_partials is the beginning of a sequence of Partials +//! \param end_partials is (one-past) the end of a sequence of +//! Partials +//! \param fadeTime is the Partial fade time for rendering +//! the Partials on the specified range. If unspecified, the +//! fade time is taken from the Synthesizer DefaultParameters. +//! +//! If compiled with NO_TEMPLATE_MEMBERS defined, this member accepts +//! only PartialList::const_iterator arguments. +// +#if !defined(NO_TEMPLATE_MEMBERS) +template< typename Iter > +void + AiffFile::addPartials( Iter begin_partials, Iter end_partials, double fadeTime ) +#else +void + AiffFile::addPartials( PartialList::const_iterator begin_partials, + PartialList::const_iterator end_partials, + double fadeTime ) +#endif +{ + Synthesizer synth = configureSynthesizer( fadeTime ); + synth.synthesize( begin_partials, end_partials ); +} + +} // end of namespace Loris -- cgit v1.2.3