esp_wavepcm.h

Go to the documentation of this file.
00001 
00007 /*
00008  *  Copyright (c) 2003, Matt Beard
00009  *
00010  *  This software is provided 'as-is', without any express or implied warranty.
00011  *  In no event will the authors be held liable for any damages arising from
00012  *  the use of this software.
00013  *
00014  *  Permission is granted to anyone to use this software for any purpose,
00015  *  including commercial applications, and to alter it and redistribute it
00016  *  freely, subject to the following restrictions:
00017  *
00018  *    1. The origin of this software must not be misrepresented; you must
00019  *       not claim that you wrote the original software. If you use this
00020  *       software in a product, an acknowledgment in the product
00021  *       documentation would be appreciated but is not required.
00022  *  
00023  *    2. Altered source versions must be plainly marked as such, and must
00024  *       not be misrepresented as being the original software.
00025  *  
00026  *    3. This notice may not be removed or altered from any source
00027  *       distribution.
00028  */
00029 
00030 #ifndef MXFLIB__ESP_WAVEPCM_H
00031 #define MXFLIB__ESP_WAVEPCM_H
00032 
00033 #include <math.h>   // For "floor"
00034 
00035 
00036 namespace mxflib
00037 {
00038     class WAVE_PCM_EssenceSubParser : public EssenceSubParserBase
00039     {
00040     protected:
00041         UInt32 SampleRate;                                  
00042         Rational UseEditRate;                               
00043 
00044         Position DataStart;                                 
00045         Length DataSize;                                    
00046         Position CurrentPosition;                           
00047         Position BytePosition;                              
00048 
00054         size_t CachedDataSize;                              
00055         UInt64 CachedCount;                                 
00056 
00057         int SampleSize;                                     
00058         UInt32 ConstSamples;                                
00059         int SampleSequenceSize;                             
00060         UInt32 *SampleSequence;                             
00061         int SequencePos;                                    
00062 
00063         MDObjectParent CurrentDescriptor;                   
00064 
00066     public:
00068         class ESP_EssenceSource : public EssenceSubParserBase::ESP_EssenceSource
00069         {
00070         protected:
00071             size_t BytesRemaining;                          
00072 
00073         public:
00075             ESP_EssenceSource(EssenceSubParserPtr TheCaller, FileHandle InFile, UInt32 UseStream, UInt64 Count = 1/*, IndexTablePtr UseIndex = NULL*/)
00076                 : EssenceSubParserBase::ESP_EssenceSource(TheCaller, InFile, UseStream, Count/*, UseIndex*/) 
00077             {
00078                 BytesRemaining = 0;
00079             };
00080 
00082 
00084             virtual size_t GetEssenceDataSize(void) 
00085             {
00086                 WAVE_PCM_EssenceSubParser *pCaller = SmartPtr_Cast(Caller, WAVE_PCM_EssenceSubParser);
00087                 return pCaller->ReadInternal(File, Stream, RequestedCount);
00088             };
00089 
00091 
00096             virtual DataChunkPtr GetEssenceData(size_t Size = 0, size_t MaxSize = 0);
00097 
00099 
00105             virtual bool EndOfItem(void) 
00106             { 
00107                 // Items end when there is no data remaining from the last read
00108                 return !BytesRemaining;
00109             }
00110 
00112             virtual int GetBERSize(void) 
00113             { 
00114                 WAVE_PCM_EssenceSubParser *pCaller = SmartPtr_Cast(Caller, WAVE_PCM_EssenceSubParser);
00115 
00116                 if(pCaller->SelectedWrapping->ThisWrapType == WrappingOption::Clip) return 8;
00117                 return 4;
00118             }
00119         };
00120 
00121         // Give our essence source class privilaged access
00122         friend class WAVE_PCM_EssenceSubParser::ESP_EssenceSource;
00123 
00124     public:
00125         WAVE_PCM_EssenceSubParser()
00126         {
00127             SampleRate = 1;
00128             ConstSamples = 0;
00129             SampleSequenceSize = 0;
00130             SampleSequence = NULL;
00131             SequencePos = 0;
00132             DataStart = 0;
00133             DataSize = 0;
00134             CurrentPosition = 0;
00135             BytePosition = 0;
00136 
00137             // Use a sensible default if no edit rate is set - not ideal, but better than one sample!
00138             // It will always be possible to wrap at this rate, but the end of the data may not be a whole edit unit
00139             UseEditRate.Numerator = 1;
00140             UseEditRate.Denominator = 1;
00141 
00142             CachedDataSize = static_cast<size_t>(-1);
00143             CachedCount = 0;
00144         }
00145 
00147         virtual EssenceSubParserPtr NewParser(void) const { return new WAVE_PCM_EssenceSubParser; }
00148 
00150         virtual StringList HandledExtensions(void)
00151         {
00152             StringList ExtensionList;
00153 
00154             ExtensionList.push_back("WAV");
00155 
00156             return ExtensionList;
00157         }
00158 
00160         virtual EssenceStreamDescriptorList IdentifyEssence(FileHandle InFile);
00161 
00163         virtual WrappingOptionList IdentifyWrappingOptions(FileHandle InFile, EssenceStreamDescriptor &Descriptor);
00164 
00166 
00167         virtual void Use(UInt32 Stream, WrappingOptionPtr UseWrapping)
00168         {
00169             SelectedWrapping = UseWrapping;
00170 
00171             BytePosition = 0;
00172         }
00173 
00174 
00176 
00179         virtual bool SetEditRate(Rational EditRate)
00180         {
00181             // See if we can figure out a sequence for this rate
00182             bool Ret = CalcWrappingSequence(EditRate);
00183 
00184             // If we can then set the rate
00185             if(Ret)
00186             {
00187                 SequencePos = 0;
00188                 UseEditRate = EditRate;
00189             }
00190 
00191             return Ret;
00192         }
00193 
00195         virtual Rational GetEditRate(void) { return UseEditRate; }
00196 
00198 
00200         virtual Rational GetPreferredEditRate(void);
00201 
00203         virtual UInt32 GetBytesPerEditUnit(UInt32 KAGSize = 1)
00204         {
00205             // If we haven't determined the sample sequence we do it now
00206             if((ConstSamples == 0) && (SampleSequenceSize == 0)) CalcWrappingSequence(UseEditRate);
00207 
00208             UInt32 Ret = SampleSize*ConstSamples;
00209 
00210             if(Ret && (SelectedWrapping->ThisWrapType == WrappingOption::Frame))
00211             {
00212                 // FIXME: This assumes that 4-byte BER coding will be used - this needs to be adjusted or forced to be true!!
00213                 Ret += 16 + 4;
00214 
00215                 // Adjust for whole KAGs if required
00216                 if(KAGSize > 1)
00217                 {
00218                     // Work out how much short of the next KAG boundary we would be
00219                     UInt32 Remainder = Ret % KAGSize;
00220                     if(Remainder) Remainder = KAGSize - Remainder;
00221 
00222                     // Round up to the start of the next KAG
00223                     Ret += Remainder;
00224 
00225                     // If there is not enough space to fit a filler in the remaining space an extra KAG will be required
00226                     // DRAGONS: For very small KAGSizes we may need to add several KAGs
00227                     while((Remainder > 0) && (Remainder < 17))
00228                     {
00229                         Ret += KAGSize;
00230                         Remainder += KAGSize;
00231                     }
00232                 }
00233             }
00234 
00235             return Ret;
00236         }
00237 
00238 
00240         virtual Position GetCurrentPosition(void) { return CurrentPosition; }
00241 
00243         virtual DataChunkPtr Read(FileHandle InFile, UInt32 Stream, UInt64 Count = 1/*, IndexTablePtr Index = NULL*/);
00244 
00246         virtual EssenceSourcePtr GetEssenceSource(FileHandle InFile, UInt32 Stream, UInt64 Count = 1/*, IndexTablePtr Index = NULL*/)
00247         {
00248             return new ESP_EssenceSource(this, InFile, Stream, Count/*, Index*/);
00249         };
00250 
00252         virtual Length Write(FileHandle InFile, UInt32 Stream, MXFFilePtr OutFile, UInt64 Count = 1/*, IndexTablePtr Index = NULL*/);
00253 
00255 
00259         virtual std::string GetParserName(void) const { return "wavepcm"; }
00260 
00261 
00262     protected:
00264         bool CalcWrappingSequence(Rational EditRate);
00265 
00267         Position CalcCurrentPosition(void);
00268 
00270         MDObjectPtr BuildWaveAudioDescriptor(FileHandle InFile, UInt64 Start = 0);
00271 
00273         size_t ReadInternal(FileHandle InFile, UInt32 Stream, UInt64 Count);
00274     };
00275 }
00276 
00277 #endif // MXFLIB__ESP_WAVEPCM_H

Generated on Mon Apr 2 15:20:53 2007 for MXFLib by  doxygen 1.5.1-p1