root/trunk/SMAC/SMACsdec.cpp

Revision 1, 23.8 kB (checked in by gbooker, 3 years ago)

Initial Import

Line 
1 /*      Copyright:      © Copyright 2004 Apple Computer, Inc. All rights reserved.
2
3         Disclaimer:     IMPORTANT:  This Apple software is supplied to you by Apple Computer, Inc.
4                         ("Apple") in consideration of your agreement to the following terms, and your
5                         use, installation, modification or redistribution of this Apple software
6                         constitutes acceptance of these terms.  If you do not agree with these terms,
7                         please do not use, install, modify or redistribute this Apple software.
8
9                         In consideration of your agreement to abide by the following terms, and subject
10                         to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
11                         copyrights in this original Apple software (the "Apple Software"), to use,
12                         reproduce, modify and redistribute the Apple Software, with or without
13                         modifications, in source and/or binary forms; provided that if you redistribute
14                         the Apple Software in its entirety and without modifications, you must retain
15                         this notice and the following text and disclaimers in all such redistributions of
16                         the Apple Software.  Neither the name, trademarks, service marks or logos of
17                         Apple Computer, Inc. may be used to endorse or promote products derived from the
18                         Apple Software without specific prior written permission from Apple.  Except as
19                         expressly stated in this notice, no other rights or licenses, express or implied,
20                         are granted by Apple herein, including but not limited to any patent rights that
21                         may be infringed by your derivative works or by other works in which the Apple
22                         Software may be incorporated.
23
24                         The Apple Software is provided by Apple on an "AS IS" basis.  APPLE MAKES NO
25                         WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
26                         WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
27                         PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
28                         COMBINATION WITH YOUR PRODUCTS.
29
30                         IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
31                         CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
32                         GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33                         ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
34                         OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
35                         (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
36                         ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 */
38 /*=============================================================================
39         SMACsdec.cpp
40
41 =============================================================================*/
42
43 #if USE_DIRECT_DRMZ
44 // this works because all our sound component calls are to our source
45 #define SoundComponentSetSource                 drmzDecomp_SetSource
46 #define SoundComponentSetOutput                 drmzDecomp_SetOutput
47 #define SoundComponentGetInfo                   drmzDecomp_GetInfo
48 #define SoundComponentSetInfo                   drmzDecomp_SetInfo
49 #define SoundComponentPlaySourceBuffer  drmzDecomp_PlaySourceBuffer
50 #define SoundComponentStopSource                drmzDecomp_StopSource
51 #define SoundComponentGetSourceData             drmzDecomp_GetSourceData
52 #endif
53
54 #if USE_DIRECT_ADEC
55 // remap calls to AudioCodec interface thru our protected class interface
56 #define AudioCodecVersion                               DirectAudioCodecVersion
57 #define AudioCodecGetPropertyInfo               DirectAudioCodecGetPropertyInfo
58 #define AudioCodecGetProperty                   DirectAudioCodecGetProperty
59 #define AudioCodecSetProperty                   DirectAudioCodecSetProperty
60 #define AudioCodecInitialize                    DirectAudioCodecInitialize
61 #define AudioCodecUninitialize                  DirectAudioCodecUninitialize
62 #define AudioCodecAppendInputData               DirectAudioCodecAppendInputData
63 #define AudioCodecProduceOutputPackets  DirectAudioCodecProduceOutputPackets
64 #define AudioCodecReset                                 DirectAudioCodecReset
65 #endif
66
67 //=============================================================================
68 //      Includes
69 //=============================================================================
70 #include <CAConditionalMacros.h>
71
72 #if     !TARGET_API_MAC_OSX || USE_QTML_HEADERS
73 #include <SndEnv.h>
74 #else
75 #include <CoreServices/CoreServices.h>
76 #endif
77
78 #include <string.h>
79
80 #include "SMACsdec.h"
81 #include "CADebugMacros.h"
82 #include "CAException.h"
83 #include "SMACSCDUtility.h"
84
85 #if defined( __GNUC__ )
86     #if( __GNUC__ < 3 )
87         #define IS_COMPILER_WORKING     0
88     #else
89         #define IS_COMPILER_WORKING     1
90     #endif
91 #else
92     #define IS_COMPILER_WORKING 1
93 #endif
94
95 #if TARGET_MAC_OS && IS_COMPILER_WORKING
96 #include "PCMBlitterLibDispatch.h"
97 #endif
98
99 // from transform.h
100 #define CAST(         type, expression) ( (type)(expression) )
101 #define ROUND(e)        CAST(short, e);
102 #define ROUND_TO_DESK(Src, Dest)                                                        \
103 {                                                                                                               \
104         if(Src>32767)                                                                           \
105                 Dest = 32767;                                                                   \
106         else if (Src < -32768)                                                          \
107                 Dest = -32768;                                                                  \
108         else                                                                                            \
109                 Dest = ROUND(Src);                                                              \
110 }
111
112
113 //=============================================================================
114 //      SMACsdec
115 //=============================================================================
116
117 SMACsdec::SMACsdec(ComponentInstance inSelf)
118 :
119         mSelf(inSelf),
120         mSourceComponent(NULL),
121         mDecoder(NULL),
122         mSourceID(0),
123         mSourceData(NULL),
124         mPacketFrameSize(0),
125         mFloatBuffer(NULL),
126         mOutputBuffer(NULL)
127 #if     CaptureDataToFile
128         ,mOutputFileRefNum(-1)
129 #endif
130 {
131         memset(&mOutputData, 0, sizeof(SoundComponentData));
132         mOutputData.format = k16BitNativeEndianFormat;
133         mOutputData.sampleSize = 16;
134
135 #if TARGET_API_MAC_OSX && TARGET_CPU_PPC       
136         mHasAltiVec = SMACSCDUtility::HasAltiVec();
137 #else
138         mHasAltiVec = false;
139 #endif
140        
141 #if     TARGET_API_MAC_OSX
142         mThreadStateMutex = new CAMutex("SMACsdec::mThreadStateMutex");
143 #endif
144
145 #if     CaptureDataToFile
146         FSRef theFSRef;
147         FSRef theParentRef;
148         UniChar theFileName[] = { 'o', 'u', 't', 'p', 'u', 't', '.', 's', 'd', '2' };
149         OSStatus theError = FSPathMakeRef((const UInt8*)"/Volumes/Annex/Users/moorf/output.sd2", &theFSRef, NULL);
150         if(theError != fnfErr)
151         {
152                 FSDeleteObject(&theFSRef);
153         }
154         theError = FSPathMakeRef((const UInt8*)"/Volumes/Annex/Users/moorf", &theParentRef, NULL);
155         theError = FSCreateFileUnicode(&theParentRef, 10, theFileName, kFSCatInfoNone, NULL, &theFSRef, NULL);
156         theError = FSOpenFork(&theFSRef, 0, NULL, fsRdWrPerm, &mOutputFileRefNum);
157         if(theError != 0)
158         {
159                 mOutputFileRefNum = -1;
160         }
161 #endif
162 }
163
164 SMACsdec::~SMACsdec()
165 {
166         if(mDecoder != NULL)
167         {
168 #if USE_DIRECT_ADEC
169                 DirectAudioCodecClose(mDecoder);
170 #else
171                 CloseComponent(mDecoder);
172 #endif
173         }
174        
175         delete[] mOutputBuffer;
176         delete[] mFloatBuffer;
177
178 #if     TARGET_API_MAC_OSX
179         delete mThreadStateMutex;
180         mThreadStateMutex = NULL;
181 #endif
182        
183 #if     CaptureDataToFile
184         if(mOutputFileRefNum != -1)
185         {
186                 FSCloseFork(mOutputFileRefNum);
187         }
188 #endif
189 }
190
191 void    SMACsdec::SetSource(SoundSource inSourceID, ComponentInstance inSourceComponent)
192 {
193         mSourceID = inSourceID;
194         mSourceComponent = inSourceComponent;
195         mSourceData = NULL;
196        
197         SoundComponentData* theSourceData;
198         ComponentResult theError = SoundComponentSetOutput(mSourceComponent, &mOutputData, &theSourceData);
199         ThrowIfError(theError, (CAException)theError, "SMACsdec::SetSource: got an error from SoundComponentSetOutput");
200 }
201
202 void    SMACsdec::SetOutput(SoundComponentData* inRequested, SoundComponentData** outActual)
203 {
204         if((inRequested->format == mOutputData.format) && (inRequested->sampleSize == mOutputData.sampleSize))
205         {
206                 mOutputData = *inRequested;
207         }
208         else
209         {
210                 *outActual = &mOutputData;
211                 throw static_cast<ComponentResult>(paramErr);
212         }
213 }
214
215 void    SMACsdec::PlaySourceBuffer(SoundSource inSourceID, SoundParamBlock* inPB, SInt32 inActions)
216 {
217         //      get rid of the input data
218         mSourceData = NULL;
219         mOutputData.sampleCount = 0;
220
221         ComponentResult theError = SoundComponentPlaySourceBuffer(mSourceComponent, inSourceID, inPB, inActions);
222         ThrowIfError(theError, (CAException)theError, "SMACsdec::PlaySourceBuffer: got an error from SoundComponentPlaySourceBuffer");
223 }
224
225 void    SMACsdec::StopSource(SInt16 inNumberSources, SoundSource*       inSources)
226 {
227         //      get rid of the input data
228         mSourceData = NULL;
229         mOutputData.sampleCount = 0;
230        
231         //      reset the decoder
232         if(mDecoder != NULL)
233         {
234                 AudioCodecReset(mDecoder);
235         }
236        
237         ComponentResult theError = SoundComponentStopSource(mSourceComponent, inNumberSources, inSources);
238         ThrowIfError(theError, (CAException)theError, "SMACsdec::StopSource: got an error from SoundComponentStopSource");
239 }
240
241 void    SMACsdec::GetInfo(SoundSource inSourceID, OSType inSelector, void* outData)
242 {
243         switch(inSelector)
244         {
245                 case siCompressionFactor:
246                         GetCompressionInfo(*static_cast<CompressionInfo*>(outData));
247                         break;
248                
249                 case siDecompressionParams:
250                         GetDecompressionParams(outData);
251                         break;
252        
253                 default:
254                         ThrowIf(mSourceComponent == NULL, siUnknownInfoType, "SMACsdec::GetInfo: no source to pass request to")
255                         ComponentResult theError = SoundComponentGetInfo(mSourceComponent, inSourceID, inSelector, outData);
256                         ThrowIfError(theError, (CAException)theError, "SMACsdec::GetInfo: got an error from SoundComponentGetInfo");
257                         break;
258         };
259 }
260
261 void    SMACsdec::SetInfo(SoundSource inSourceID, OSType inSelector, void* inData)
262 {
263     switch(inSelector)
264         {
265                 case siDecompressionParams:
266                         {
267                         #if     TARGET_API_MAC_OSX
268                                 // Lock the thread if we can as we are going to completely replace the decoder
269                                 bool threadLocked;
270
271                                 threadLocked = mThreadStateMutex->Lock();
272                         #endif
273
274                                 //      process the the new params and produce an initialized
275                                 //      AudioCodec instance
276                                 ComponentInstance theDecoder = SetDecompressionParams(inData);
277                                 ThrowIf(theDecoder == NULL, badFormat, "SMACsdec::SetInfo: siDecompressionParams didn't generate a decoder");
278
279                                 //      get rid of the input data
280                                 mSourceData = NULL;
281                                 mOutputData.sampleCount = 0;
282        
283                                 //      close the old decoder if necessary
284                                 if((mDecoder != NULL) && (theDecoder != mDecoder))
285                                 {
286 #if USE_DIRECT_ADEC
287                                         DirectAudioCodecClose(mDecoder);
288 #else
289                                         CloseComponent(mDecoder);
290 #endif
291                                 }
292                                
293                                 //      use the new one
294                                 mDecoder = theDecoder;
295                                
296                                 //      get the number of frames in 1 packet of data
297                                 UInt32 theSize = sizeof(UInt32);
298                                 ComponentResult theError = AudioCodecGetProperty(mDecoder, kAudioCodecPropertyPacketFrameSize, &theSize, &mPacketFrameSize);
299                                 ThrowIfError(theError, (CAException)theError, "SMACsdec::SetInfo: siDecompressionParams got an error from AudioCodecGetProperty");
300                                
301                                 //      toss the old output buffer
302                                 delete[] mOutputBuffer;
303                                 delete[] mFloatBuffer;
304                                
305                                 //      allocate enough space for 1 packet of data, since that's
306                                 //      that's all this component will produce per call to GetSourceData
307                                 //      note that this is going to be 16 bit integer
308                                 mOutputBuffer = new Byte[mPacketFrameSize * 2 * mOutputData.numChannels];
309                 mFloatBuffer = new float[mPacketFrameSize * mOutputData.numChannels];
310                                
311                         #if     TARGET_API_MAC_OSX
312                                 // If we need to, unlock the thread
313                                 if(threadLocked)
314                                 {
315                                         mThreadStateMutex->Unlock();
316                                 }
317                         #endif
318                         }
319                         break;
320
321                 default:
322                         ThrowIf(mSourceComponent == NULL, siUnknownInfoType, "SMACsdec::SetInfo: no source to pass request to")
323                         ComponentResult theError = SoundComponentSetInfo(mSourceComponent, inSourceID, inSelector, inData);
324                         throw theError;
325                         break;
326         };
327 }
328
329 void    SMACsdec::GetSourceData(SoundComponentData** outData)
330 {
331         //      initialize the return value
332         *outData = NULL;
333        
334         //      stuff as many packets as we can into the decoder
335         UInt32 theError = 0;
336         void*   theInputData = NULL;
337         UInt32  theInputDataByteSize = 0;
338         UInt32  theInputDataFrameSize = 0;
339 #if     TARGET_API_MAC_OSX
340         bool threadLocked;
341 #endif
342
343 #if !(TARGET_MAC_OS && IS_COMPILER_WORKING)
344         UInt32 totalFloats;
345 #endif
346
347 #if     TARGET_API_MAC_OSX
348         // Lock the thread. The last thing we want is to have our state change in the middle of
349         // a decode -- it will typically cause a crash
350         threadLocked = mThreadStateMutex->Lock();
351 #endif
352         //      prime things with the current packet
353         GetCurrentInputPacket(theInputData, theInputDataByteSize, theInputDataFrameSize);
354         // Trying to mimic Decompressor.c in this case
355     if((theInputData == NULL) || (theInputDataFrameSize == 0 && theInputDataByteSize == 0) )
356     {
357         // silence with non-zero duration.
358                 mOutputData.buffer = NULL;
359                 *outData = mSourceData;
360     }
361     else
362     {
363                 //      loop and stuff the decoder with packets
364                 bool isDone = false;
365                 while((theInputData != NULL) && (theInputDataByteSize != 0) && (!isDone))
366                 {
367                         //      give the current packet to the decoder
368                         UInt32  theNumberInputPackets = 1;
369                         UInt32  theNumberInputBytesConsumed = theInputDataByteSize;
370                         AudioStreamPacketDescription theInputPacketDescription = { 0, 0, theInputDataByteSize };
371                         theError = AudioCodecAppendInputData(mDecoder, theInputData, &theNumberInputBytesConsumed, &theNumberInputPackets, &theInputPacketDescription);
372                         //printf("mDecoder == %lu, Appended %ld bytes in %ld packets\n", (UInt32)(&mDecoder), theNumberInputBytesConsumed, theNumberInputPackets);
373                         ThrowIfError(theError, (CAException)theError, "SMACsdec::GetSourceData: got an error from AudioCodecAppendInputData");
374                        
375                         //      we know that the decoder is full if it ever says that it didn't take any data from the input buffer
376                         if( (theNumberInputBytesConsumed > 0) && (theNumberInputBytesConsumed == theInputDataByteSize) )
377                         {
378                                 //      consume the data the decoder used
379                                 ConsumeCurrentInputPacket(theInputDataByteSize, 0);
380                                
381                                 //      get the next packet
382                                 GetCurrentInputPacket(theInputData, theInputDataByteSize, theInputDataFrameSize);
383                         }
384                         else if (theNumberInputBytesConsumed > 0)
385                         {
386                                 ConsumeCurrentInputPacket(theNumberInputBytesConsumed, 0);
387                                 isDone = true;
388                         }
389                         else
390                         {
391                                 isDone = true;
392                         }
393                 }
394                 //      the decoder is as full of data as we can make it at this time,
395                 //      so pull out 1 packet of output data
396                 UInt32 theOutputDataByteSize = mPacketFrameSize * sizeof(float) * mOutputData.numChannels;
397                 UInt32 theNumberOutputFrames = mPacketFrameSize;
398                 UInt32 theDecoderStatus = kAudioCodecProduceOutputPacketFailure;
399                 theError = AudioCodecProduceOutputPackets(mDecoder, mFloatBuffer, &theOutputDataByteSize, &theNumberOutputFrames, NULL, &theDecoderStatus);
400                 //printf ("        theNumberOutputFrames == %ld\n",theNumberOutputFrames);
401                 ThrowIfError(theError, (CAException)theError, "SMACsdec::GetSourceData: got an error from AudioCodecProduceOutputPackets");
402                
403                 //      set up the return values if we got a packet back from the decoder
404                 if(theNumberOutputFrames)
405                 {
406                         //theNumberOutputFrames = theOutputDataByteSize / mOutputData.numChannels / sizeof(float);
407                 //      ThrowIfError(theNumberOutputFrames != theOutputDataByteSize / mOutputData.numChannels / sizeof(float), "SMACsdec::GetSourceData: got an error from AudioCodecProduceOutputPackets");
408
409 #if TARGET_MAC_OS && IS_COMPILER_WORKING
410                         Float32ToNativeInt16(mHasAltiVec, mFloatBuffer, ((short *)mOutputBuffer), theOutputDataByteSize >> 2);
411 #else
412                         totalFloats = theOutputDataByteSize >> 2;
413                         for (unsigned int i = 0; i < totalFloats; i++)
414                         {
415                                 ((short *)mOutputBuffer)[i] = (SInt16)(32768.0 * mFloatBuffer[i]);
416                         }
417 #endif
418                         mOutputData.buffer = mOutputBuffer;
419                         if (mOutputData.numChannels == 2) // It's either 1 or 2 here in SMAC land
420                         {
421                                 mOutputData.sampleCount = (theOutputDataByteSize >> 3); // These really are frames. It's a QuickTime/SoundManager ism
422                         }
423                         else
424                         {
425                                 mOutputData.sampleCount = (theOutputDataByteSize >> 2);
426                         }
427                         *outData = &mOutputData;
428                        
429         #if     CaptureDataToFile
430                         if(mOutputFileRefNum != -1)
431                         {
432                                 UInt32 theActualBytesWritten = 0;
433                                 FSWriteFork(mOutputFileRefNum, fsAtMark, 0, theOutputDataByteSize, mOutputBuffer, &theActualBytesWritten);
434                         }
435         #endif
436                 }
437                 else
438                 {
439                         mOutputData.buffer = NULL;
440                         mOutputData.sampleCount = 0;
441                         *outData = &mOutputData;
442                 }
443     }
444 #if     TARGET_API_MAC_OSX
445         if(threadLocked)
446         {
447                 mThreadStateMutex->Unlock();
448         }
449 #endif
450 }
451
452 void    SMACsdec::GetCurrentInputPacket(void*& outPacketData, UInt32& outPacketDataByteSize, UInt32& outPacketDataFrameSize)
453 {
454         //      This method is called to get a pointer to the next packet of input data.
455         //      The only failure cases for the returned values are as follows:
456         //              - outPacketData is NULL
457         //              - outPacketData is not NULL, but outPacketDataByteSize and outPacketDataFrameSize
458         //                      are both equal to zero
459         //      Note that this method does not consume the data, it merely returns points to it. Use
460         //      ConsumeCurrentInputPacket to mark input data as consumed.
461
462         //      set up the return values
463         outPacketData = NULL;
464         outPacketDataByteSize = 0;
465         outPacketDataFrameSize = 0;
466        
467         //      check to see if we need to get more data from the source component
468         if(SMACSCDUtility::NeedMoreSourceData(mSourceData))
469         {
470                 if(mSourceData != NULL)
471                 {
472                         mSourceData->sampleCount = 0;
473                 }
474                 //      we do, so get it from the source component
475                 UInt32 theError = SoundComponentGetSourceData(mSourceComponent, &mSourceData);
476                 ThrowIfError(theError, (CAException)theError, "SMACsdec::GetCurrentInputPacket: got an error from SoundComponentGetSourceData");
477         // We pass this on as QuickTime will not be happy if we don't.
478         // Note that this is not necessarily what the sample rate is in the original file.
479         mOutputData.sampleRate = mSourceData->sampleRate;
480     }
481        
482         //      if we have some data from the source component, dole out the first packet
483         if(!SMACSCDUtility::NeedMoreSourceData(mSourceData))
484         {
485                 if(SMACSCDUtility::IsSoundComponentData(mSourceData))
486                 {
487                         //      this is a normal SoundComponentData with no packetization info,
488                         //      so return the whole buffer
489                         outPacketData = mSourceData->buffer;
490                         outPacketDataByteSize = mSourceData->numChannels * (mSourceData->sampleSize >> 3) * mSourceData->sampleCount;
491                         outPacketDataFrameSize = mSourceData->sampleCount;
492                 }
493                 else
494                 {
495                         //      this is an ExtendedSoundComponentData
496                         ExtendedSoundComponentData* theExtendedSourceData = reinterpret_cast<ExtendedSoundComponentData*>(mSourceData);
497                        
498                         //      it may or may not have packetization info in it
499                         if(static_cast<UInt32>(theExtendedSourceData->recordSize) < sizeof(ExtendedSoundComponentData))
500                         {
501                                 //      it's an old ExtendedSoundComponentData which doesn't have the packetization
502                                 //      info, so return the whole buffer
503                                 outPacketData = theExtendedSourceData->desc.buffer;
504                                 if(theExtendedSourceData->extendedFlags & kExtendedSoundBufferSizeValid)
505                                 {
506                                         outPacketDataByteSize = theExtendedSourceData->bufferSize;
507                                 }
508                                 if(!(theExtendedSourceData->extendedFlags & kExtendedSoundSampleCountNotValid))
509                                 {
510                                         outPacketDataFrameSize = theExtendedSourceData->desc.sampleCount;
511                                 }
512                         }
513                         else
514                         {
515                                 //      it's a new ExtendedSoundComponentData which may have the packetization info
516                                 if(theExtendedSourceData->extendedFlags & kExtendedSoundCommonFrameSizeValid)
517                                 {
518                                         //      all the packets are the same size, so return the current one
519                                         //      note that we don't know how many frames are in this buffer
520                                         //      also note that the buffer size field has to be valid
521                                         ThrowIf(!(theExtendedSourceData->extendedFlags & kExtendedSoundBufferSizeValid), -50, "SMACsdec::GetCurrentInputPacket: need kExtendedSoundBufferSizeValid set for common packet sizes to work");
522                                         outPacketData = theExtendedSourceData->desc.buffer;
523                                         outPacketDataByteSize = theExtendedSourceData->commonFrameSize;
524                                 }
525                                 else if(theExtendedSourceData->extendedFlags & kExtendedSoundFrameSizesValid)
526                                 {
527                                         //      the packets are sized according to theExtendedSourceData->frameSizesArray
528                                         //      note that we don't know how many frames are in this buffer
529                                         ThrowIf(!(theExtendedSourceData->extendedFlags & kExtendedSoundBufferSizeValid), -50, "SMACsdec::GetCurrentInputPacket: need kExtendedSoundBufferSizeValid set for arbitrary packet sizes to work");
530                                         outPacketData = theExtendedSourceData->desc.buffer;
531                                         outPacketDataByteSize = *(theExtendedSourceData->frameSizesArray);
532                                 }
533                                 else
534                                 {
535                                         //      there isn't any packetization info, so return the whole buffer
536                                         outPacketData = theExtendedSourceData->desc.buffer;
537                                         if(theExtendedSourceData->extendedFlags & kExtendedSoundBufferSizeValid)
538                                         {
539                                                 outPacketDataByteSize = theExtendedSourceData->bufferSize;
540                                         }
541                                         if(!(theExtendedSourceData->extendedFlags & kExtendedSoundSampleCountNotValid))
542                                         {
543                                                 outPacketDataFrameSize = theExtendedSourceData->desc.sampleCount;
544                                         }
545                                 }
546                         }
547                 }
548         }
549 }
550
551 void    SMACsdec::ConsumeCurrentInputPacket(UInt32 inPacketDataByteSize, UInt32 inPacketDataFrameSize)
552 {
553         //      This method is called in order to consume the current packet of input data.
554         //      Note that this routine enforces all the expectations as far as packetization
555         //      is concerned. This routine will throw exceptions if things are even slightly
556         //      amiss.
557
558         //      can only consume data if we have it
559         if(mSourceData != NULL)
560         {
561                 if(SMACSCDUtility::IsSoundComponentData(mSourceData))
562                 {
563                         //      this is a normal SoundComponentData with no packetization info,
564                         //      so consume the amount indicated, making sure that the two notions
565                         //      of the amount to consume are the same
566                         ThrowIf(inPacketDataByteSize != (inPacketDataFrameSize * mSourceData->numChannels * (mSourceData->sampleSize >> 3)), -50, "SMACsdec::ConsumeCurrentInputPacket: concept of how much data to consume doesn't match for the normal case");
567                         mSourceData->buffer += inPacketDataByteSize;
568                         mSourceData->sampleCount -= inPacketDataFrameSize;
569                 }
570                 else
571                 {
572                         //      this is an ExtendedSoundComponentData
573                         ExtendedSoundComponentData* theExtendedSourceData = reinterpret_cast<ExtendedSoundComponentData*>(mSourceData);
574                        
575                         //      it may or may not have packetization info in it
576                         if(static_cast<UInt32>(theExtendedSourceData->recordSize) < sizeof(ExtendedSoundComponentData))
577                         {
578                                 //      it's an old ExtendedSoundComponentData which doesn't have the packetization
579                                 //      so consume the amount indicated
580                                 theExtendedSourceData->desc.buffer += inPacketDataByteSize;
581                                 if(theExtendedSourceData->extendedFlags & kExtendedSoundBufferSizeValid)
582                                 {
583                                         theExtendedSourceData->bufferSize -= inPacketDataByteSize;
584                                 }
585                                 if(!(theExtendedSourceData->extendedFlags & kExtendedSoundSampleCountNotValid))
586                                 {
587                                         theExtendedSourceData->desc.sampleCount -= inPacketDataFrameSize;
588                                 }
589                         }
590                         else
591                         {
592                                 //      it's a new ExtendedSoundComponentData which may have the packetization info
593                                 if(theExtendedSourceData->extendedFlags & kExtendedSoundCommonFrameSizeValid)
594                                 {
595                                         //      all the packets are the same size, so check to be sure that we are
596                                         //      consuming the correct amount, noting that we have no clue how many
597                                         //      frames of data this is
598                                         ThrowIf(inPacketDataByteSize != static_cast<UInt32>(theExtendedSourceData->commonFrameSize), -50, "SMACsdec::ConsumeCurrentInputPacket: asked to consume something different from the common packet size");
599                                         ThrowIf(!(theExtendedSourceData->extendedFlags & kExtendedSoundBufferSizeValid), -50, "SMACsdec::ConsumeCurrentInputPacket: need kExtendedSoundBufferSizeValid set for common packet sizes to work");
600                                         theExtendedSourceData->desc.buffer += inPacketDataByteSize;
601                                         theExtendedSourceData->bufferSize -= inPacketDataByteSize;
602                                 }
603                                 else if(theExtendedSourceData->extendedFlags & kExtendedSoundFrameSizesValid)
604                                 {
605                                         //      the packets are sized according to theExtendedSourceData->frameSizesArray,
606                                         //      so check to be sure we are consuming the correct amount of data, noting that
607                                         //      we have no clue how many frames of data this is
608                                         ThrowIf(inPacketDataByteSize != static_cast<UInt32>(*(theExtendedSourceData->frameSizesArray)), -50, "SMACsdec::ConsumeCurrentInputPacket: asked to consume something different from the first packet size in theExtendedSourceData->frameSizesArray");
609                                         ThrowIf(!(theExtendedSourceData->extendedFlags & kExtendedSoundBufferSizeValid), -50, "SMACsdec::ConsumeCurrentInputPacket: need kExtendedSoundBufferSizeValid set for arbitrary packet sizes to work");
610                                         theExtendedSourceData->desc.buffer += inPacketDataByteSize;
611                                         theExtendedSourceData->frameSizesArray += 1;
612                                         theExtendedSourceData->bufferSize -= inPacketDataByteSize;
613                                 }
614                                 else
615                                 {
616                                         //      there isn't any packetization info, so consume the amount indicated
617                                         theExtendedSourceData->desc.buffer += inPacketDataByteSize;
618                                         if(theExtendedSourceData->extendedFlags & kExtendedSoundBufferSizeValid)
619                                         {
620                                                 theExtendedSourceData->bufferSize -= inPacketDataByteSize;
621                                         }
622                                         if(!(theExtendedSourceData->extendedFlags & kExtendedSoundSampleCountNotValid))
623                                         {
624                                                 theExtendedSourceData->desc.sampleCount -= inPacketDataFrameSize;
625                                         }
626                                 }
627                         }
628                 }
629         }
630 }
Note: See TracBrowser for help on using the browser.