Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members

SpcFile.h

00001 /*
00002  * This is the Loris C++ Class Library, implementing analysis, 
00003  * manipulation, and synthesis of digitized sounds using the Reassigned 
00004  * Bandwidth-Enhanced Additive Sound Model.
00005  *
00006  * Loris is Copyright (c) 1999-2004 by Kelly Fitz and Lippold Haken
00007  *
00008  * This program is free software; you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation; either version 2 of the License, or
00011  * (at your option) any later version.
00012  *
00013  * This program is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY, without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00016  * GNU General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU General Public License
00019  * along with this program; if not, write to the Free Software
00020  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00021  *
00022  *
00023  * SpcFile.h
00024  *
00025  * Definition of SpcFile class for Partial import and export for
00026  * real-time synthesis in Kyma.
00027  *
00028  * Spc files always represent a number of Partials that is a power of
00029  * two. This is not necessary for purely-sinusoidal files, but might be
00030  * (not clear) for enhanced data to be properly processed in Kyma. 
00031  *
00032  * All of this is kind of disgusting right now. This code has evolved 
00033  * somewhat randomly, and we are awaiting full support for bandwidth-
00034  * enhanced data in Kyma..
00035  *
00036  * Kelly Fitz, 8 Jan 2003 
00037  * loris@cerlsoundgroup.org
00038  *
00039  * http://www.cerlsoundgroup.org/Loris/
00040  *
00041  */
00042 #include "Marker.h"
00043 #include "Partial.h"
00044 
00045 #if defined(NO_TEMPLATE_MEMBERS)
00046 #include "PartialList.h"
00047 #endif
00048  
00049 #include <string>
00050 #include <vector>
00051 
00052 //  begin namespace
00053 namespace Loris {
00054 
00055 // ---------------------------------------------------------------------------
00056 //  class SpcFile
00057 //
00058 //  Class SpcFile represents a collection of reassigned bandwidth-enhanced
00059 //  Partial data in a SPC-format envelope stream data file, used by the
00060 //  real-time bandwidth-enhanced additive synthesizer implemented on the
00061 //  Symbolic Sound Kyma Sound Design Workstation. Class SpcFile manages 
00062 //  file I/O and conversion between Partials and envelope parameter streams.
00063 //  
00064 class SpcFile
00065 {
00066 //  -- public interface --
00067 public:
00068 
00069 //  -- types --
00070     typedef std::vector< Marker > markers_type;
00071     typedef std::vector< Partial > partials_type;
00072 
00073 //  -- construction --
00074     explicit SpcFile( const std::string & filename );
00075     /*  Initialize an instance of SpcFile by importing envelope parameter 
00076         streams from the file having the specified filename or path.
00077     */
00078 
00079 #if !defined(NO_TEMPLATE_MEMBERS)
00080     template<typename Iter>
00081     SpcFile( Iter begin_partials, Iter end_partials, double midiNoteNum = 60  );
00082 #else
00083     SpcFile( PartialList::const_iterator begin_partials, 
00084              PartialList::const_iterator end_partials,
00085              double midiNoteNum = 60  );
00086 #endif
00087     /*  Initialize an instance of SpcFile with copies of the Partials
00088         on the specified half-open (STL-style) range.
00089 
00090         If compiled with NO_TEMPLATE_MEMBERS defined, this member accepts
00091         only PartialList::const_iterator arguments.
00092     */
00093 
00094     explicit SpcFile( double midiNoteNum = 60 );
00095     /*  Initialize an instance of SpcFile having the specified fractional
00096         MIDI note number, and no Partials (or envelope parameter streams). 
00097     */
00098      
00099     //  copy, assign, and delete are compiler-generated
00100     
00101 //  -- access --
00102     markers_type & markers( void );
00103     const markers_type & markers( void ) const;
00104     /*  Return a reference to the MarkerContainer (see Marker.h) for this SpcFile. 
00105      */
00106      
00107     double midiNoteNumber( void ) const;
00108     /*  Return the fractional MIDI note number assigned to this SpcFile. 
00109         If the sound has no definable pitch, note number 60.0 is used.
00110      */
00111     
00112     const partials_type & partials( void ) const;
00113     /*  Return a read-only (const) reference to the bandwidth-enhanced
00114         Partials represented by the envelope parameter streams in this SpcFile.
00115      */
00116     
00117     double sampleRate( void ) const;
00118     /*  Return the sampling freqency in Hz for the spc data in this
00119         SpcFile. This is the rate at which Kyma must be running to ensure
00120         proper playback of bandwidth-enhanced Spc data.
00121     */
00122     
00123 //  -- mutation --
00124     void addPartial( const Loris::Partial & p );
00125     /*  Add the specified Partial to the enevelope parameter streams
00126         represented by this SpcFile. 
00127         
00128         A SpcFile can contain only one Partial having any given (non-zero) 
00129         label, so an added Partial will replace a Partial having the 
00130         same label, if such a Partial exists.
00131 
00132         This may throw an InvalidArgument exception if an attempt is made
00133         to add unlabeled Partials, or Partials labeled higher than the
00134         allowable maximum.
00135      */
00136      
00137     void addPartial( const Loris::Partial & p, int label );
00138     /*  Add a Partial, assigning it the specified label (and position in the
00139         Spc data).
00140         
00141         A SpcFile can contain only one Partial having any given (non-zero) 
00142         label, so an added Partial will replace a Partial having the 
00143         same label, if such a Partial exists.
00144 
00145         This may throw an InvalidArgument exception if an attempt is made
00146         to add unlabeled Partials, or Partials labeled higher than the
00147         allowable maximum.
00148      */
00149      
00150 #if !defined(NO_TEMPLATE_MEMBERS)
00151     template<typename Iter>
00152     void addPartials( Iter begin_partials, Iter end_partials  );
00153 #else
00154     void addPartials( PartialList::const_iterator begin_partials, 
00155                       PartialList::const_iterator end_partials  );
00156 #endif
00157     /*  Add all Partials on the specified half-open (STL-style) range
00158         to the enevelope parameter streams represented by this SpcFile. 
00159         
00160         A SpcFile can contain only one Partial having any given (non-zero) 
00161         label, so an added Partial will replace a Partial having the 
00162         same label, if such a Partial exists.
00163 
00164         If compiled with NO_TEMPLATE_MEMBERS defined, this member accepts
00165         only PartialList::const_iterator arguments.
00166 
00167         This may throw an InvalidArgument exception if an attempt is made
00168         to add unlabeled Partials, or Partials labeled higher than the
00169         allowable maximum.
00170      */
00171 
00172     void setMidiNoteNumber( double nn );
00173     /*  Set the fractional MIDI note number assigned to this SpcFile. 
00174         If the sound has no definable pitch, use note number 60.0 (the default).
00175      */
00176      
00177     void setSampleRate( double rate );
00178     /*  Set the sampling freqency in Hz for the spc data in this
00179         SpcFile. This is the rate at which Kyma must be running to ensure
00180         proper playback of bandwidth-enhanced Spc data.
00181         
00182         The default sample rate is 44100 Hz.
00183     */
00184         
00185 //  -- export --
00186     void write( const std::string & filename, double endApproachTime = 0 );
00187     /*  Export the phase-correct bandwidth-enhanced envelope parameter 
00188         streams represented by this SpcFile to the file having the specified 
00189         filename or path. 
00190         
00191         A nonzero endApproachTime indicates that the Partials do not include a
00192         release or decay, but rather end in a static spectrum corresponding to the
00193         final Breakpoint values of the partials. The endApproachTime specifies how
00194         long before the end of the sound the amplitude, frequency, and bandwidth
00195         values are to be modified to make a gradual transition to the static spectrum.
00196         
00197         If the endApproachTime is not specified, it is assumed to be zero, 
00198         corresponding to Partials that decay or release normally.
00199     */
00200 
00201     void writeSinusoidal( const std::string & filename, double endApproachTime = 0 );
00202     /*  Export the pure sinsoidal (omitting phase and bandwidth data) envelope 
00203         parameter streams represented by this SpcFile to the file having the 
00204         specified filename or path. 
00205         
00206         A nonzero endApproachTime indicates that the Partials do not include a
00207         release or decay, but rather end in a static spectrum corresponding to the
00208         final Breakpoint values of the partials. The endApproachTime specifies how
00209         long before the end of the sound the amplitude, frequency, and bandwidth
00210         values are to be modified to make a gradual transition to the static spectrum.
00211         
00212         If the endApproachTime is not specified, it is assumed to be zero, 
00213         corresponding to Partials that decay or release normally.
00214     */
00215 
00216     void write( const std::string & filename, bool enhanced,
00217                 double endApproachTime = 0 );
00218     /*  Export the envelope parameter streams represented by this SpcFile to
00219         the file having the specified filename or path. Export phase-correct 
00220         bandwidth-enhanced envelope parameter streams if enhanced is true 
00221         (the default), or pure sinsoidal streams otherwise.
00222     
00223         A nonzero endApproachTime indicates that the Partials do not include a
00224         release or decay, but rather end in a static spectrum corresponding to the
00225         final Breakpoint values of the partials. The endApproachTime specifies how
00226         long before the end of the sound the amplitude, frequency, and bandwidth
00227         values are to be modified to make a gradual transition to the static spectrum.
00228         
00229         If the endApproachTime is not specified, it is assumed to be zero, 
00230         corresponding to Partials that decay or release normally.
00231         
00232         This version of write is deprecated, use the two-argument
00233         versions write and writeSinusoidal. 
00234     */
00235 
00236 private:
00237 //  -- implementation --
00238     partials_type partials_;        //  Partials to store in Spc format
00239     markers_type markers_;      //  AIFF Markers
00240 
00241     double notenum_, rate_;     // MIDI note number and sample rate
00242     
00243     static const int MinNumPartials;    //  32
00244     static const double DefaultRate;    //  44kHz
00245 
00246 //  -- helpers --
00247     void readSpcData( const std::string & filename );
00248     void growPartials( partials_type::size_type sz );
00249     
00250 };  //  end of class SpcFile
00251 
00252 
00253 // ---------------------------------------------------------------------------
00254 //  constructor from Partial range
00255 // ---------------------------------------------------------------------------
00256 //  Initialize an instance of SpcFile with copies of the Partials
00257 //  on the specified half-open (STL-style) range. If the MIDI
00258 //  note number is not specified, then note number 60 is used.
00259 //
00260 //  If compiled with NO_TEMPLATE_MEMBERS defined, this member accepts
00261 //  only PartialList::const_iterator arguments.
00262 //
00263 #if !defined(NO_TEMPLATE_MEMBERS)
00264 template< typename Iter >
00265 SpcFile::SpcFile( Iter begin_partials, Iter end_partials, double midiNoteNum  ) :
00266 #else
00267 SpcFile::SpcFile( PartialList::const_iterator begin_partials, 
00268                   PartialList::const_iterator end_partials,
00269                   double midiNoteNum ) :
00270 #endif
00271 //  initializers:
00272     notenum_( midiNoteNum ),
00273     rate_( DefaultRate )
00274 {
00275     growPartials( MinNumPartials );
00276     addPartials( begin_partials, end_partials );
00277 }
00278 
00279 // ---------------------------------------------------------------------------
00280 //  addPartials 
00281 // ---------------------------------------------------------------------------
00282 //  Add all Partials on the specified half-open (STL-style) range
00283 //  to the enevelope parameter streams represented by this SpcFile. 
00284 //  
00285 //  A SpcFile can contain only one Partial having any given (non-zero) 
00286 //  label, so an added Partial will replace a Partial having the 
00287 //  same label, if such a Partial exists.
00288 //
00289 //  If compiled with NO_TEMPLATE_MEMBERS defined, this member accepts
00290 //  only PartialList::const_iterator arguments.
00291 //
00292 //  This may throw an InvalidArgument exception if an attempt is made
00293 //  to add unlabeled Partials, or Partials labeled higher than the
00294 //  allowable maximum.
00295 //
00296 #if !defined(NO_TEMPLATE_MEMBERS)
00297 template<typename Iter>
00298 void SpcFile::addPartials( Iter begin_partials, Iter end_partials  )
00299 #else
00300 void SpcFile::addPartials( PartialList::const_iterator begin_partials, 
00301                            PartialList::const_iterator end_partials  )
00302 #endif
00303 {
00304     while ( begin_partials != end_partials )
00305     {
00306         addPartial( *(begin_partials++) );
00307     }
00308 }
00309 
00310 }   //  end of namespace Loris
00311 
00312 

Generated on Thu Apr 14 22:01:55 2005 for Loris by doxygen 1.3.4