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-2010 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 * AiffData.h 00024 * 00025 * Declarations of import and export functions. 00026 * 00027 * Kelly Fitz, 17 Sept 2003 00028 * loris@cerlsoundgroup.org 00029 * 00030 * http://www.cerlsoundgroup.org/Loris/ 00031 * 00032 */ 00033 00034 #include "Marker.h" 00035 00036 #include <string> 00037 #include <vector> 00038 00039 // in case configure wasn't run (no config.h), 00040 // pick some (hopefully-) reasonable values for 00041 // these things and hope for the best... 00042 #if ! defined( SIZEOF_SHORT ) 00043 #define SIZEOF_SHORT 2 00044 #endif 00045 00046 #if ! defined( SIZEOF_INT ) 00047 #define SIZEOF_INT 4 00048 #endif 00049 00050 #if ! defined( SIZEOF_LONG ) 00051 #define SIZEOF_LONG 4 // not for DEC Alpha! 00052 #endif 00053 00054 00055 #if SIZEOF_SHORT == 2 00056 typedef short Int_16; 00057 typedef unsigned short Uint_16; 00058 #elif SIZEOF_INT == 2 00059 typedef int Int_16; 00060 typedef unsigned int Uint_16; 00061 #else 00062 #error "cannot find an appropriate type for 16-bit integers" 00063 #endif 00064 00065 #if SIZEOF_INT == 4 00066 typedef int Int_32; 00067 typedef unsigned int Uint_32; 00068 #elif SIZEOF_LONG == 4 00069 typedef long Int_32; 00070 typedef unsigned long Uint_32; 00071 #else 00072 #error "cannot find an appropriate type for 32-bit integers" 00073 #endif 00074 00075 00076 // begin namespace 00077 namespace Loris { 00078 00079 // -- chunk types -- 00080 enum 00081 { 00082 ContainerId = 0x464f524d, // 'FORM' 00083 AiffType = 0x41494646, // 'AIFF' 00084 CommonId = 0x434f4d4d, // 'COMM' 00085 ApplicationSpecificId = 0x4150504c, // 'APPL' 00086 SosEnvelopesId = 0x534f5365, // 'SOSe' 00087 SoundDataId = 0x53534e44, // 'SSND' 00088 InstrumentId = 0x494e5354, // 'INST' 00089 MarkerId = 0x4d41524b // 'MARK' 00090 }; 00091 00092 typedef Uint_32 ID; 00093 typedef char Byte; 00094 00095 struct CkHeader 00096 { 00097 ID id; 00098 Uint_32 size; 00099 00100 // providing this default constructor 00101 // gives clients a way to determine whether 00102 // a chunk has been read and assigned: 00103 CkHeader( void ) : id(0), size(0) {} 00104 }; 00105 00106 struct ContainerCk 00107 { 00108 CkHeader header; 00109 ID formType; 00110 }; 00111 00112 struct CommonCk 00113 { 00114 CkHeader header; 00115 Int_16 channels; // number of channels 00116 Int_32 sampleFrames; // channel independent sample frames 00117 Int_16 bitsPerSample; // number of bits per sample 00118 double srate; // sampling rate (stored in IEEE 10 byte format) 00119 }; 00120 00121 struct SoundDataCk 00122 { 00123 CkHeader header; 00124 Uint_32 offset; 00125 Uint_32 blockSize; 00126 00127 // sample frames follow 00128 std::vector< Byte > sampleBytes; 00129 }; 00130 00131 struct MarkerCk 00132 { 00133 CkHeader header; 00134 Uint_16 numMarkers; 00135 00136 struct Marker 00137 { 00138 Uint_16 markerID; 00139 Uint_32 position; // position in uncompressed samples 00140 std::string markerName; 00141 }; 00142 00143 std::vector< MarkerCk::Marker > markers; 00144 }; 00145 00146 struct InstrumentCk 00147 { 00148 CkHeader header; 00149 Byte baseNote; /* all notes are MIDI note numbers */ 00150 Byte detune; /* cents off, only -50 to +50 are significant */ 00151 Byte lowNote; 00152 Byte highNote; 00153 Byte lowVelocity; /* 1 to 127 */ 00154 Byte highVelocity; /* 1 to 127 */ 00155 Int_16 gain; /* in dB, 0 is normal */ 00156 00157 struct Loop 00158 { 00159 Int_16 playMode; /* 0 - no loop, 1 - forward looping, 2 - backward looping */ 00160 Uint_16 beginLoop; /* this is a reference to a markerID, so you always 00161 تتتتتتتتتتتتتتتتتتتتتتتتتتتتتتتت have to work with MARK and INST together!! */ 00162 Uint_16 endLoop; 00163 }; 00164 00165 Loop sustainLoop; 00166 Loop releaseLoop; 00167 }; 00168 00169 00170 struct SosEnvelopesCk 00171 { 00172 CkHeader header; 00173 Int_32 signature; // For SOS, should be 'SOSe' 00174 Int_32 enhanced; // 0 for sine-only, 1 for bandwidth-enhanced 00175 Int_32 validPartials; // Number of partials with data in them; the file must 00176 // be padded out to the next higher 2**n partials; 00177 // this number is doubled for enhanced files 00178 00179 // skip validPartials * sizeof(Int_32) bytes of junk here 00180 Int_32 resolution; // frame duration in microseconds 00181 Int_32 quasiHarmonic; // how many of the partials are quasiharmonic 00182 // skip 00183 // (4*LargestLabel + 8 - validPartials - 2) * sizeof(Int_32) 00184 // bytes of junk here 00185 00186 /* 00187 // this stuff is unbelievably nasty! 00188 00189 #define initPhaseLth ( 4*LargestLabel + 8 ) 00190 Int_32 initPhase[initPhaseLth]; // obsolete initial phase array; is VARIABLE LENGTH array 00191 // this is big enough for a max of 512 enhanced partials plus values below 00192 // Int_32 resolution; // frame duration in microseconds 00193 #define SOSresolution( es ) initPhase[ spcEI.enhanced \ 00194 ? 2 * spcEI.numPartials : spcEI.numPartials] 00195 // follows the initPhase[] array 00196 00197 00198 // Int_32 quasiHarmonic; // how many of the partials are quasiharmonic 00199 #define SOSquasiHarmonic( es ) initPhase[ spcEI.enhanced \ 00200 ? 2 * spcEI.numPartials + 1 : spcEI.numPartials + 1] 00201 // follows the initPhase[] array 00202 */ 00203 }; 00204 00205 // --------------------------------------------------------------------------- 00206 // readChunkHeader 00207 // --------------------------------------------------------------------------- 00208 // Read the id and chunk size from the current file position. 00209 // Let exceptions propogate. 00210 // 00211 std::istream & 00212 readChunkHeader( std::istream & s, CkHeader & h ); 00213 00214 00215 // --------------------------------------------------------------------------- 00216 // readApplicationSpecifcData 00217 // --------------------------------------------------------------------------- 00218 // Read the data in the ApplicationSpecific chunk, assume the stream is 00219 // correctly positioned, and that the chunk header has already been read. 00220 // 00221 // Look for data specific to SPC files. Any other kind of Application 00222 // Specific data is ignored. 00223 // 00224 std::istream & 00225 readApplicationSpecifcData( std::istream & s, SosEnvelopesCk & ck, unsigned long chunkSize ); 00226 00227 00228 // --------------------------------------------------------------------------- 00229 // readCommonData 00230 // --------------------------------------------------------------------------- 00231 // Read the data in the Common chunk, assume the stream is correctly 00232 // positioned, and that the chunk header has already been read. 00233 // 00234 std::istream & 00235 readCommonData( std::istream & s, CommonCk & ck, unsigned long chunkSize ); 00236 00237 // --------------------------------------------------------------------------- 00238 // readContainer 00239 // --------------------------------------------------------------------------- 00240 // 00241 std::istream & 00242 readContainer( std::istream & s, ContainerCk & ck, unsigned long chunkSize ); 00243 00244 // --------------------------------------------------------------------------- 00245 // readInstrumentData 00246 // --------------------------------------------------------------------------- 00247 // 00248 std::istream & 00249 readInstrumentData( std::istream & s, InstrumentCk & ck, unsigned long chunkSize ); 00250 00251 // --------------------------------------------------------------------------- 00252 // readMarkerData 00253 // --------------------------------------------------------------------------- 00254 // 00255 std::istream & 00256 readMarkerData( std::istream & s, MarkerCk & ck, unsigned long chunkSize ); 00257 00258 // --------------------------------------------------------------------------- 00259 // readSampleData 00260 // --------------------------------------------------------------------------- 00261 // Read the data in the Sound Data chunk, assume the stream is correctly 00262 // positioned, and that the chunk header has already been read. 00263 // 00264 std::istream & 00265 readSampleData( std::istream & s, SoundDataCk & ck, unsigned long chunkSize ); 00266 00267 // --------------------------------------------------------------------------- 00268 // configureCommonCk 00269 // --------------------------------------------------------------------------- 00270 void 00271 configureCommonCk( CommonCk & ck, unsigned long nFrames, unsigned int nChans, 00272 unsigned int bps, double srate ); 00273 00274 // --------------------------------------------------------------------------- 00275 // configureContainer 00276 // --------------------------------------------------------------------------- 00277 // dataSize is the combined size of all other chunks in file. Configure 00278 // them first, then add their sizes (with headers!). 00279 // 00280 void 00281 configureContainer( ContainerCk & ck, unsigned long dataSize ); 00282 00283 // --------------------------------------------------------------------------- 00284 // configureInstrumentCk 00285 // --------------------------------------------------------------------------- 00286 void 00287 configureInstrumentCk( InstrumentCk & ck, double midiNoteNum ); 00288 00289 // --------------------------------------------------------------------------- 00290 // configureMarkerCk 00291 // --------------------------------------------------------------------------- 00292 void 00293 configureMarkerCk( MarkerCk & ck, const std::vector< Marker > & markers, 00294 double srate ); 00295 00296 // --------------------------------------------------------------------------- 00297 // configureSoundDataCk 00298 // --------------------------------------------------------------------------- 00299 // 00300 void 00301 configureSoundDataCk( SoundDataCk & ck, const std::vector< double > & samples, 00302 unsigned int bps ); 00303 00304 // --------------------------------------------------------------------------- 00305 // writeCommon 00306 // --------------------------------------------------------------------------- 00307 // 00308 std::ostream & 00309 writeCommonData( std::ostream & s, const CommonCk & ck ); 00310 00311 // --------------------------------------------------------------------------- 00312 // writeContainer 00313 // --------------------------------------------------------------------------- 00314 // 00315 std::ostream & 00316 writeContainer( std::ostream & s, const ContainerCk & ck ); 00317 00318 // --------------------------------------------------------------------------- 00319 // writeInstrumentData 00320 // --------------------------------------------------------------------------- 00321 std::ostream & 00322 writeInstrumentData( std::ostream & s, const InstrumentCk & ck ); 00323 00324 // --------------------------------------------------------------------------- 00325 // writeMarkerData 00326 // --------------------------------------------------------------------------- 00327 std::ostream & 00328 writeMarkerData( std::ostream & s, const MarkerCk & ck ); 00329 00330 // --------------------------------------------------------------------------- 00331 // writeSampleData 00332 // --------------------------------------------------------------------------- 00333 // 00334 std::ostream & 00335 writeSampleData( std::ostream & s, const SoundDataCk & ck ); 00336 00337 // --------------------------------------------------------------------------- 00338 // convertBytesToSamples 00339 // --------------------------------------------------------------------------- 00340 // Convert sample bytes to double precision floating point samples 00341 // (-1.0, 1.0). The samples vector is resized to fit exactly as many 00342 // samples as are represented in the bytes vector, and any prior 00343 // contents are overwritten. 00344 // 00345 void 00346 convertBytesToSamples( const std::vector< Byte > & bytes, 00347 std::vector< double > & samples, unsigned int bps ); 00348 00349 // --------------------------------------------------------------------------- 00350 // convertSamplesToBytes 00351 // --------------------------------------------------------------------------- 00352 // Convert floating point samples (-1.0, 1.0) to bytes. 00353 // The bytes vector is resized to fit exactly as many 00354 // samples as are stored in the samples vector, and any prior 00355 // contents are overwritten. 00356 // 00357 void 00358 convertSamplesToBytes( const std::vector< double > & samples, 00359 std::vector< Byte > & bytes, unsigned int bps ); 00360 00361 } // end of namespace