/*=============================================================================
	CAAudioConverter.h
	
	$Log: CAAudioConverter.h,v $
	Revision 1.1  2004/03/16 23:49:28  dwyatt
	initial checkin
	
	created Thu Mar 11 2004, Doug Wyatt
	Copyright (c) 2004 Apple Computer, Inc.  All Rights Reserved

	$NoKeywords: $
=============================================================================*/

#ifndef __CAAudioConverter_h__
#define __CAAudioConverter_h__

#include <AudioToolbox/AudioConverter.h>
#include "CAXException.h"
#include "CAStreamBasicDescription.h"

class CAAudioConverter {
public:
	CAAudioConverter(const AudioStreamBasicDescription &inFormat, const AudioStreamBasicDescription &outFormat)
	{
		XThrowIfError(AudioConverterNew(&inFormat, &outFormat, &mConverter), "AudioConverterNew");
		mInputFormat = inFormat;
		mOutputFormat = outFormat;
	}
	
	virtual ~CAAudioConverter()
	{
		if (mConverter) {
			verify_noerr(AudioConverterDispose(mConverter));
			mConverter = NULL;
		}
	}
	
	virtual OSStatus	Reset () { return AudioConverterReset(mConverter); }

	OSStatus	SetProperty(AudioConverterPropertyID	inPropertyID,
							UInt32						inPropertyDataSize,
							const void *				inPropertyData)
	{
		return AudioConverterSetProperty(mConverter, inPropertyID, inPropertyDataSize, inPropertyData);
	}
	
	OSStatus	GetProperty(AudioConverterPropertyID	inPropertyID,
							UInt32 &					ioPropertyDataSize,
							void *						outPropertyData)
	{
		return AudioConverterGetProperty(mConverter, inPropertyID, &ioPropertyDataSize, outPropertyData);
	}

	OSStatus	GetPropertyInfo(AudioConverterPropertyID	inPropertyID,
								UInt32 &					outPropertyDataSize,
								Boolean &					outWritable)
	{
		return AudioConverterGetPropertyInfo(mConverter, inPropertyID, &outPropertyDataSize, &outWritable);
	}

	OSStatus	FillComplexBuffer(	UInt32 &							ioOutputDataPacketSize,
									AudioBufferList &					outOutputData,
									AudioStreamPacketDescription*		outPacketDescription)
	{
		OSStatus err;
		err = AudioConverterFillComplexBuffer(mConverter, InputProc, this, &ioOutputDataPacketSize, &outOutputData, outPacketDescription);
		return err;
	}
	
	const CAStreamBasicDescription &	GetInputFormat()	{ return mInputFormat; }

	const CAStreamBasicDescription &	GetOutputFormat()	{ return mOutputFormat; }	
	
protected:
	virtual OSStatus	ProvideInput(	
								UInt32 &						ioNumberDataPackets,
								AudioBufferList &				ioData,
								AudioStreamPacketDescription**	outDataPacketDescription) = 0;
	
private:
	static OSStatus	InputProc(	AudioConverterRef				inAudioConverter,
								UInt32*							ioNumberDataPackets,
								AudioBufferList*				ioData,
								AudioStreamPacketDescription**	outDataPacketDescription,
								void*							inUserData)
	{
		OSStatus err;
		try {
			CAAudioConverter *This = static_cast<CAAudioConverter *>(inUserData);
			err = This->ProvideInput(*ioNumberDataPackets, *ioData, outDataPacketDescription);
		}
		catch (OSStatus err) {
			return err;
		}
		catch (...) {
			return -1;
		}
		return err;
	}

#if DEBUG
public:
	void Show()
	{
		CAShow(mConverter);
	}
#endif

protected:
	AudioConverterRef			mConverter;
	CAStreamBasicDescription	mInputFormat, mOutputFormat;
};


#endif // __CAAudioConverter_h__
