Example #1
0
// Overrides the method in SMACsdec. Necessary due to the way IMA works. This will not be necessary
// for many codecs.
void	SMACIMAsdec::GetSourceData(SoundComponentData** outData)
{
	//	initialize the return value
	*outData = NULL;
	
	//	stuff as many packets as we can into the decoder
	UInt32 theError = 0;
	void*	theInputData = NULL;
	UInt32	theInputDataByteSize = 0;
	UInt32	theInputDataFrameSize = 0;
#if	TARGET_API_MAC_OSX
	bool threadLocked;
#endif

#if !(TARGET_MAC_OS && IS_COMPILER_WORKING)
	UInt32 totalFloats;
#endif
#if	TARGET_API_MAC_OSX
	// Lock the thread. The last thing we want is to have our state change in the middle of
	// a decode -- it will typically cause a crash
	threadLocked = mThreadStateGuard->Lock();
#endif
	//	prime things with the current packet
	GetCurrentInputPacket(theInputData, theInputDataByteSize, theInputDataFrameSize);
	// Trying to mimic Decompressor.c in this case
    if((theInputData == NULL) || (theInputDataFrameSize == 0 && theInputDataByteSize == 0) )
    {
    	// silence with non-zero duration.
 		mOutputData.buffer = NULL;
		*outData = mSourceData;
    }
    else
    {
		// On more complex decoders this isn't always necessary
		if (!mDecoder)
		{
			mNumChannels = mOutputData.numChannels = mSourceData->numChannels;
			mSampleRate = (mSourceData->sampleRate) >> 16;
			CreateIMADecoder();
		}
		
		//	loop and stuff the decoder with packets
		bool isDone = false;
		while((theInputData != NULL) && (theInputDataByteSize != 0) && (!isDone))
		{
			//	give the current packet to the decoder
			UInt32	theNumberInputPackets = 1;
			UInt32	theNumberInputBytesConsumed = theInputDataByteSize;
			AudioStreamPacketDescription theInputPacketDescription = { 0, 0, theInputDataByteSize };
			theError = AudioCodecAppendInputData(mDecoder, theInputData, &theNumberInputBytesConsumed, &theNumberInputPackets, &theInputPacketDescription);
			ThrowIfError(theError, (CAException)theError, "SMACIMAsdec::GetSourceData: got an error from AudioCodecAppendInputData");
			
			//	we know that the decoder is full if it ever says that it didn't take any data from the input buffer
			if(theNumberInputBytesConsumed > 0 && theNumberInputBytesConsumed == theInputDataByteSize)
			{
				//	consume the data the decoder used
				ConsumeCurrentInputPacket(theInputDataByteSize, 0);
				
				//	get the next packet
				GetCurrentInputPacket(theInputData, theInputDataByteSize, theInputDataFrameSize);
			}
			else if (theNumberInputBytesConsumed > 0)
			{
				ConsumeCurrentInputPacket(theNumberInputBytesConsumed, 0);
				isDone = true;
			}
			else
			{
				isDone = true;
			}
		}
		//	the decoder is as full of data as we can make it at this time,
		//	so pull out 1 packet of output data
		UInt32 theOutputDataByteSize = mPacketFrameSize * sizeof(float) * mOutputData.numChannels;
		UInt32 theNumberOutputFrames = mPacketFrameSize;
		UInt32 theDecoderStatus = kAudioCodecProduceOutputPacketFailure;
		theError = AudioCodecProduceOutputPackets(mDecoder, mFloatBuffer, &theOutputDataByteSize, &theNumberOutputFrames, NULL, &theDecoderStatus);
		ThrowIfError(theError, (CAException)theError, "SMACIMAsdec::GetSourceData: got an error from AudioCodecProduceOutputPackets");
		
		//	set up the return values if we got a packet back from the decoder
		if(theNumberOutputFrames)
		{
// gcc 2.95 doesn't work right in this case, so we guard against it
#if TARGET_MAC_OS && IS_COMPILER_WORKING
			Float32ToNativeInt16(mHasAltiVec, mFloatBuffer, ((short *)mOutputBuffer), theOutputDataByteSize >> 2);
#else
			totalFloats = theOutputDataByteSize >> 2;
			for (unsigned int i = 0; i < totalFloats; i++)
			{
				((short *)mOutputBuffer)[i] = (SInt16)(32768.0 * mFloatBuffer[i]);
			}
#endif
			mOutputData.buffer = mOutputBuffer;
			if (mOutputData.numChannels == 2) // It's either 1 or 2 here in SMAC land
			{
				mOutputData.sampleCount = (theOutputDataByteSize >> 3); // Yes, these really are frames.
			}
			else
			{
Example #2
0
void	SMACsdec::GetSourceData(SoundComponentData** outData)
{
	//	initialize the return value
	*outData = NULL;
	
	//	stuff as many packets as we can into the decoder
	UInt32 theError = 0;
	void*	theInputData = NULL;
	UInt32	theInputDataByteSize = 0;
	UInt32	theInputDataFrameSize = 0;
#if	TARGET_API_MAC_OSX
	bool threadLocked;
#endif

#if !(TARGET_MAC_OS && IS_COMPILER_WORKING)
	UInt32 totalFloats;
#endif

#if	TARGET_API_MAC_OSX
	// Lock the thread. The last thing we want is to have our state change in the middle of
	// a decode -- it will typically cause a crash
	threadLocked = mThreadStateMutex->Lock();
#endif
	//	prime things with the current packet
	GetCurrentInputPacket(theInputData, theInputDataByteSize, theInputDataFrameSize);
	// Trying to mimic Decompressor.c in this case
    if((theInputData == NULL) || (theInputDataFrameSize == 0 && theInputDataByteSize == 0) )
    {
    	// silence with non-zero duration.
 		mOutputData.buffer = NULL;
		*outData = mSourceData;
    }
    else
    {
		//	loop and stuff the decoder with packets
		bool isDone = false;
		while((theInputData != NULL) && (theInputDataByteSize != 0) && (!isDone))
		{
			//	give the current packet to the decoder
			UInt32	theNumberInputPackets = 1;
			UInt32	theNumberInputBytesConsumed = theInputDataByteSize;
			AudioStreamPacketDescription theInputPacketDescription = { 0, 0, theInputDataByteSize };
			theError = AudioCodecAppendInputData(mDecoder, theInputData, &theNumberInputBytesConsumed, &theNumberInputPackets, &theInputPacketDescription);
			//printf("mDecoder == %lu, Appended %ld bytes in %ld packets\n", (UInt32)(&mDecoder), theNumberInputBytesConsumed, theNumberInputPackets);
			ThrowIfError(theError, (CAException)theError, "SMACsdec::GetSourceData: got an error from AudioCodecAppendInputData");
			
			//	we know that the decoder is full if it ever says that it didn't take any data from the input buffer
			if( (theNumberInputBytesConsumed > 0) && (theNumberInputBytesConsumed == theInputDataByteSize) )
			{
				//	consume the data the decoder used
				ConsumeCurrentInputPacket(theInputDataByteSize, 0);
				
				//	get the next packet
				GetCurrentInputPacket(theInputData, theInputDataByteSize, theInputDataFrameSize);
			}
			else if (theNumberInputBytesConsumed > 0)
			{
				ConsumeCurrentInputPacket(theNumberInputBytesConsumed, 0);
				isDone = true;
			}
			else
			{
				isDone = true;
			}
		}
		//	the decoder is as full of data as we can make it at this time,
		//	so pull out 1 packet of output data
		UInt32 theOutputDataByteSize = mPacketFrameSize * sizeof(float) * mOutputData.numChannels;
		UInt32 theNumberOutputFrames = mPacketFrameSize;
		UInt32 theDecoderStatus = kAudioCodecProduceOutputPacketFailure;
		theError = AudioCodecProduceOutputPackets(mDecoder, mFloatBuffer, &theOutputDataByteSize, &theNumberOutputFrames, NULL, &theDecoderStatus);
		//printf ("        theNumberOutputFrames == %ld\n",theNumberOutputFrames);
		ThrowIfError(theError, (CAException)theError, "SMACsdec::GetSourceData: got an error from AudioCodecProduceOutputPackets");
		
		//	set up the return values if we got a packet back from the decoder
		if(theNumberOutputFrames)
		{
			//theNumberOutputFrames = theOutputDataByteSize / mOutputData.numChannels / sizeof(float);
		//	ThrowIfError(theNumberOutputFrames != theOutputDataByteSize / mOutputData.numChannels / sizeof(float), "SMACsdec::GetSourceData: got an error from AudioCodecProduceOutputPackets");

#if TARGET_MAC_OS && IS_COMPILER_WORKING
			Float32ToNativeInt16(mHasAltiVec, mFloatBuffer, ((short *)mOutputBuffer), theOutputDataByteSize >> 2);
#else
			totalFloats = theOutputDataByteSize >> 2;
			for (unsigned int i = 0; i < totalFloats; i++)
			{
				((short *)mOutputBuffer)[i] = (SInt16)(32768.0 * mFloatBuffer[i]);
			}
#endif
			mOutputData.buffer = mOutputBuffer;
			if (mOutputData.numChannels == 2) // It's either 1 or 2 here in SMAC land
			{
				mOutputData.sampleCount = (theOutputDataByteSize >> 3); // These really are frames. It's a QuickTime/SoundManager ism
			}
			else
			{
				mOutputData.sampleCount = (theOutputDataByteSize >> 2);
			}
			*outData = &mOutputData;
			
	#if	CaptureDataToFile
			if(mOutputFileRefNum != -1)
			{
				UInt32 theActualBytesWritten = 0;
				FSWriteFork(mOutputFileRefNum, fsAtMark, 0, theOutputDataByteSize, mOutputBuffer, &theActualBytesWritten);
			}
	#endif
		}