From d6073e01c933c77f1e2bc3c3fe1126d617003549 Mon Sep 17 00:00:00 2001
From: John Glover <glover.john@gmail.com>
Date: Fri, 8 Jul 2011 18:06:21 +0100
Subject: Start adding Loris files

---
 src/loris/SpcFile.h | 368 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 368 insertions(+)
 create mode 100644 src/loris/SpcFile.h

(limited to 'src/loris/SpcFile.h')

diff --git a/src/loris/SpcFile.h b/src/loris/SpcFile.h
new file mode 100644
index 0000000..118b30d
--- /dev/null
+++ b/src/loris/SpcFile.h
@@ -0,0 +1,368 @@
+/*
+ * 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
+ *
+ *
+ * SpcFile.h
+ *
+ * Definition of SpcFile class for Partial import and export for
+ * real-time synthesis in Kyma.
+ *
+ * Spc files always represent a number of Partials that is a power of
+ * two. This is not necessary for purely-sinusoidal files, but might be
+ * (not clear) for enhanced data to be properly processed in Kyma. 
+ *
+ * All of this is kind of disgusting right now. This code has evolved 
+ * somewhat randomly, and we are awaiting full support for bandwidth-
+ * enhanced data in Kyma..
+ *
+ * Kelly Fitz, 8 Jan 2003 
+ * loris@cerlsoundgroup.org
+ *
+ * http://www.cerlsoundgroup.org/Loris/
+ *
+ */
+#include "Marker.h"
+#include "Partial.h"
+
+#if defined(NO_TEMPLATE_MEMBERS)
+#include "PartialList.h"
+#endif
+ 
+#include <string>
+#include <vector>
+
+//	begin namespace
+namespace Loris {
+
+// ---------------------------------------------------------------------------
+//	class SpcFile
+//
+//!	Class SpcFile represents a collection of reassigned bandwidth-enhanced
+//!	Partial data in a SPC-format envelope stream data file, used by the
+//!	real-time bandwidth-enhanced additive synthesizer implemented on the
+//!	Symbolic Sound Kyma Sound Design Workstation. Class SpcFile manages 
+//!	file I/O and conversion between Partials and envelope parameter streams.
+//	
+class SpcFile
+{
+//	-- public interface --
+public:
+
+//	-- types --
+
+	//! the type of the container of Markers
+	//! stored with an SpcFile
+	typedef std::vector< Marker > markers_type;		
+	
+	//! the type of the container of Partials
+	//! stored with an SpcFile
+	typedef std::vector< Partial > partials_type;	
+
+//	-- construction --
+
+	//!	Initialize an instance of SpcFile by importing envelope parameter 
+	//!	streams from the file having the specified filename or path.
+	//!
+	//! \param	filename the name of the file to import
+ 	explicit SpcFile( const std::string & filename );
+
+	//!	Initialize an instance of SpcFile with copies of the Partials
+	//!	on the specified half-open (STL-style) range.
+	//!
+	//!	If compiled with NO_TEMPLATE_MEMBERS defined, this member accepts
+	//!	only PartialList::const_iterator arguments.
+	//!
+	//! \param	begin_partials the beginning of a range of Partials to prepare
+	//!			for Spc export
+	//! \param	end_partials the end of a range of Partials to prepare
+	//!			for Spc export
+	//!	\param	midiNoteNum the fractional MIDI note number, if specified
+	//!			(default is 60)
+#if !defined(NO_TEMPLATE_MEMBERS)
+	template<typename Iter>
+	SpcFile( Iter begin_partials, Iter end_partials, double midiNoteNum = 60  );
+#else
+	SpcFile( PartialList::const_iterator begin_partials, 
+			 PartialList::const_iterator end_partials,
+			 double midiNoteNum = 60  );
+#endif
+
+	//!	Initialize an instance of SpcFile having the specified fractional
+	//!	MIDI note number, and no Partials (or envelope parameter streams). 
+	//!
+	//!	\param	midiNoteNum the fractional MIDI note number, if specified
+	//!			(default is 60)
+	explicit SpcFile( double midiNoteNum = 60 );
+	 
+	//	copy, assign, and delete are compiler-generated
+	
+//	-- access --
+
+	//!	Return a reference to the MarkerContainer (see Marker.h) for this SpcFile. 
+	markers_type & markers( void );
+	
+	//!	Return a reference to the MarkerContainer (see Marker.h) for this SpcFile. 
+	const markers_type & markers( void ) const;
+	 
+	//!	Return the fractional MIDI note number assigned to this SpcFile. 
+	//!	If the sound has no definable pitch, note number 60.0 is used.
+	double midiNoteNumber( void ) const;
+	
+	//!	Return a read-only (const) reference to the bandwidth-enhanced
+	//! Partials represented by the envelope parameter streams in this SpcFile.
+	const partials_type & partials( void ) const;
+	
+	//!	Return the sampling freqency in Hz for the spc data in this
+	//!	SpcFile. This is the rate at which Kyma must be running to ensure
+	//!	proper playback of bandwidth-enhanced Spc data.
+ 	double sampleRate( void ) const;
+	
+//	-- mutation --
+
+	//!	Add the specified Partial to the enevelope parameter streams
+	//!	represented by this SpcFile. 
+	//!	
+	//!	A SpcFile can contain only one Partial having any given (non-zero) 
+	//!	label, so an added Partial will replace a Partial having the 
+	//!	same label, if such a Partial exists.
+	//!
+	//!	This may throw an InvalidArgument exception if an attempt is made
+	//!	to add unlabeled Partials, or Partials labeled higher than the
+	//!	allowable maximum.
+	//!
+	//!	\param	p the Partial to add to this SpcFile
+	void addPartial( const Loris::Partial & p );
+	 
+	//!	Add a Partial, assigning it the specified label (and position in the
+	//!	Spc data).
+	//!	
+	//!	A SpcFile can contain only one Partial having any given (non-zero) 
+	//!	label, so an added Partial will replace a Partial having the 
+	//!	same label, if such a Partial exists.
+	//!
+	//!	This may throw an InvalidArgument exception if an attempt is made
+	//!	to add unlabeled Partials, or Partials labeled higher than the
+	//!	allowable maximum.
+	//!
+	//!	\param	p the Partial to add to this SpcFile
+	//! \param	label the label to associate with this Partial in 
+	//!			the Spc file (the Partial's own label is ignored).
+	void addPartial( const Loris::Partial & p, int label );
+	 
+	//!	Add all Partials on the specified half-open (STL-style) range
+	//!	to the enevelope parameter streams represented by this SpcFile. 
+	//!	
+	//!	A SpcFile can contain only one Partial having any given (non-zero) 
+	//!	label, so an added Partial will replace a Partial having the 
+	//!	same label, if such a Partial exists.
+	//!
+	//!	If compiled with NO_TEMPLATE_MEMBERS defined, this member accepts
+	//!	only PartialList::const_iterator arguments.
+	//!
+	//!	This may throw an InvalidArgument exception if an attempt is made
+	//!	to add unlabeled Partials, or Partials labeled higher than the
+	//!	allowable maximum.
+	//!
+	//! \param	begin_partials the beginning of a range of Partials
+	//!			to add to this Spc file
+	//! \param	end_partials the end of a range of Partials
+	//!			to add to this Spc file
+#if !defined(NO_TEMPLATE_MEMBERS)
+	template<typename Iter>
+	void addPartials( Iter begin_partials, Iter end_partials  );
+#else
+	void addPartials( PartialList::const_iterator begin_partials, 
+					  PartialList::const_iterator end_partials  );
+#endif
+
+	//!	Set the fractional MIDI note number assigned to this SpcFile. 
+	//!	If the sound has no definable pitch, use note number 60.0 
+	//! (the default).
+	void setMidiNoteNumber( double nn );
+
+	//!	Set the sampling freqency in Hz for the spc data in this
+	//!	SpcFile. This is the rate at which Kyma must be running to ensure
+	//!	proper playback of bandwidth-enhanced Spc data.
+	//!	
+	//!	The default sample rate is 44100 Hz.
+	void setSampleRate( double rate );
+	 	
+//	-- export --
+
+	//!	Export the phase-correct bandwidth-enhanced envelope parameter 
+	//!	streams represented by this SpcFile to the file having the specified 
+	//!	filename or path. 
+	//!	
+	//!	A nonzero endApproachTime indicates that the Partials do not include a
+	//!	release or decay, but rather end in a static spectrum corresponding to the
+	//!	final Breakpoint values of the partials. The endApproachTime specifies how
+	//!	long before the end of the sound the amplitude, frequency, and bandwidth
+	//!	values are to be modified to make a gradual transition to the static spectrum.
+	//!	
+	//!	If the endApproachTime is not specified, it is assumed to be zero, 
+	//!	corresponding to Partials that decay or release normally.
+	//!
+	//! \param	filename the name of the file to create
+	//! \param	endApproachTime the duration in seconds of the gradual transition
+	//!			to a static spectrum at the end of the sound (default 0)
+	void write( const std::string & filename, double endApproachTime = 0 );
+
+	//!	Export the pure sinsoidal (omitting phase and bandwidth data) envelope 
+	//!	parameter streams represented by this SpcFile to the file having the 
+	//!	specified filename or path. 
+	//!	
+	//!	A nonzero endApproachTime indicates that the Partials do not include a
+	//!	release or decay, but rather end in a static spectrum corresponding to the
+	//!	final Breakpoint values of the partials. The endApproachTime specifies how
+	//!	long before the end of the sound the amplitude, frequency, and bandwidth
+	//!	values are to be modified to make a gradual transition to the static spectrum.
+	//!	
+	//!	If the endApproachTime is not specified, it is assumed to be zero, 
+	//!	corresponding to Partials that decay or release normally.
+	//!
+	//! \param	filename the name of the file to create
+	//! \param	endApproachTime the duration in seconds of the gradual transition
+	//!			to a static spectrum at the end of the sound (default 0)
+	void writeSinusoidal( const std::string & filename, double endApproachTime = 0 );
+
+	//!	Export the envelope parameter streams represented by this SpcFile to
+	//!	the file having the specified filename or path. Export phase-correct 
+	//!	bandwidth-enhanced envelope parameter streams if enhanced is true 
+	//!	(the default), or pure sinsoidal streams otherwise.
+	//!
+	//!	A nonzero endApproachTime indicates that the Partials do not include a
+	//!	release or decay, but rather end in a static spectrum corresponding to the
+	//!	final Breakpoint values of the partials. The endApproachTime specifies how
+	//!	long before the end of the sound the amplitude, frequency, and bandwidth
+	//!	values are to be modified to make a gradual transition to the static spectrum.
+	//!	
+	//!	If the endApproachTime is not specified, it is assumed to be zero, 
+	//!	corresponding to Partials that decay or release normally.
+	//!	
+	//!	\deprecated This version of write is deprecated, use the two-argument
+	//!	versions write and writeSinusoidal. 
+	//!
+	//! \param	filename the name of the file to create
+	//! \param	enhanced flag indicating whether to export enhanced (true)
+	//!			or sinusoidal (false) data
+	//! \param	endApproachTime the duration in seconds of the gradual transition
+	//!			to a static spectrum at the end of the sound (default 0)
+	void write( const std::string & filename, bool enhanced,
+				double endApproachTime = 0 );
+
+private:
+//	-- implementation --
+	partials_type partials_;	//!	Partials to store in Spc format
+	markers_type markers_;		//!	AIFF Markers
+
+	double notenum_;			//! fractional MIDI note number
+	double rate_;				//! sample rate in Hz at which the data plays at the
+								//! correction default pitch
+	
+	static const int MinNumPartials;	//!	the minimum number of Partials to export (32)
+										//!	(if necessary, extra empty (silent) Partials
+										//! will be exported to make up the difference between
+										//!	the size of partials_ and the next larger power
+										//! of two, not less than MinNumPartials
+	static const double DefaultRate;	//!	the default Spc export sample rate in Hz (44kHz)
+
+//	-- helpers --
+	void readSpcData( const std::string & filename );
+	void growPartials( partials_type::size_type sz );
+	
+};	//	end of class SpcFile
+
+
+// ---------------------------------------------------------------------------
+//	constructor from Partial range
+// ---------------------------------------------------------------------------
+//!	Initialize an instance of SpcFile with copies of the Partials
+//!	on the specified half-open (STL-style) range.
+//!
+//!	If compiled with NO_TEMPLATE_MEMBERS defined, this member accepts
+//!	only PartialList::const_iterator arguments.
+//!
+//! \param	begin_partials the beginning of a range of Partials to prepare
+//!			for Spc export
+//! \param	end_partials the end of a range of Partials to prepare
+//!			for Spc export
+//!	\param	midiNoteNum the fractional MIDI note number, if specified
+//!			(default is 60)
+#if !defined(NO_TEMPLATE_MEMBERS)
+template< typename Iter >
+SpcFile::SpcFile( Iter begin_partials, Iter end_partials, double midiNoteNum  ) :
+#else
+SpcFile::SpcFile( PartialList::const_iterator begin_partials, 
+				  PartialList::const_iterator end_partials,
+				  double midiNoteNum ) :
+#endif
+//	initializers:
+	notenum_( midiNoteNum ),
+	rate_( DefaultRate )
+{
+	growPartials( MinNumPartials );
+	addPartials( begin_partials, end_partials );
+}
+
+// ---------------------------------------------------------------------------
+//	addPartials 
+// ---------------------------------------------------------------------------
+//!	Add all Partials on the specified half-open (STL-style) range
+//!	to the enevelope parameter streams represented by this SpcFile. 
+//!	
+//!	A SpcFile can contain only one Partial having any given (non-zero) 
+//!	label, so an added Partial will replace a Partial having the 
+//!	same label, if such a Partial exists.
+//!
+//!	If compiled with NO_TEMPLATE_MEMBERS defined, this member accepts
+//!	only PartialList::const_iterator arguments.
+//!
+//!	This may throw an InvalidArgument exception if an attempt is made
+//!	to add unlabeled Partials, or Partials labeled higher than the
+//!	allowable maximum.
+//!
+//! \param	begin_partials the beginning of a range of Partials
+//!			to add to this Spc file
+//! \param	end_partials the end of a range of Partials
+//!			to add to this Spc file
+#if !defined(NO_TEMPLATE_MEMBERS)
+template<typename Iter>
+void SpcFile::addPartials( Iter begin_partials, Iter end_partials  )
+#else
+void SpcFile::addPartials( PartialList::const_iterator begin_partials, 
+						   PartialList::const_iterator end_partials  )
+#endif
+{
+	while ( begin_partials != end_partials )
+	{
+	    // do not try to add unlabeled Partials, or 
+	    // Partials labeled beyond 256:
+	    if ( 0 != begin_partials->label() && 257 > begin_partials->label() )
+	    {
+		    addPartial( *begin_partials );
+		}
+		++begin_partials;
+	}
+}
+
+}	//	end of namespace Loris
+
+
-- 
cgit v1.2.3