/*============================================================================= FormatConverterClient.h $Log: FormatConverterClient.h,v $ Revision 2.10 2004/08/25 23:07:48 bills fix warning Revision 2.9 2003/11/21 22:27:18 dwyatt make Reset virtual Revision 2.8 2003/11/20 22:56:53 dwyatt __COREAUDIO_USE_FLAT_INCLUDES__ Revision 2.7 2003/04/09 23:03:08 dwyatt minor refactoring Revision 2.6 2003/02/07 22:40:28 dwyatt redo 3020740 so that channel map is correctly preserved even across destroy/rebuild converter Revision 2.5 2003/02/05 22:12:41 dwyatt Add support for channel map Revision 2.4 2002/11/05 02:32:42 bills implement Reset call to call AUConverterReset [dwyatt] Revision 2.3 2002/06/29 20:37:14 dwyatt add a method for CAShow Revision 2.2 2002/06/14 09:03:39 dwyatt don't verify_noerr in FillComplexBuffer; failure is happening and the signal is confusing things badly Revision 2.1 2002/06/11 16:58:08 dwyatt return error from input proc Revision 2.0 2002/06/06 06:52:27 dwyatt moved from Utility Revision 1.3 2002/06/02 00:51:32 dwyatt fixes to complex conversions Revision 1.2 2002/05/20 02:19:30 dwyatt AudioUnit V2 Revision 1.1.4.2 2002/04/22 18:04:24 dwyatt more v2 work Revision 1.1.4.1 2002/04/18 06:53:36 dwyatt initial checkin of deinterleave munge Revision 1.1 2001/12/17 13:30:32 luke copied from Source/Utility for inclusion in SDK Revision 1.8 2001/10/25 00:01:55 bills add back constructor needed for Puma build Revision 1.7 2001/10/20 01:19:53 dwyatt cache the src/dest formats in members Revision 1.6 2001/10/17 19:12:10 dwyatt add project Revision 1.5 2001/08/18 11:27:10 dwyatt add GetProperty wrapper method [2754217] Revision 1.4 2001/08/13 22:04:01 dwyatt check_noerr debugging macro removes code in production builds! Use verify_noerr! D'oh! Revision 1.3 2001/07/28 18:03:05 dwyatt use check_noerr instead of verify_noerr Revision 1.2 2001/07/26 21:31:18 dwyatt add SetProperty Revision 1.1 2001/07/24 19:26:00 dwyatt initial checkin created 18 Jul 2001, 6:49, Doug Wyatt Copyright (c) 2001 Apple Computer, Inc. All Rights Reserved $NoKeywords: $ =============================================================================*/ #ifndef __FormatConverterClient_h__ #define __FormatConverterClient_h__ #if !defined(__COREAUDIO_USE_FLAT_INCLUDES__) #include #else #include #endif #include extern "C" void CAShow(void *); // ____________________________________________________________________________ // // FormatConverterClient // C++ wrapper for an AudioConverter class FormatConverterClient { public: FormatConverterClient() : mConverter(NULL) { } // ONLY NEEDED FOR Puma build - should be removed.... FormatConverterClient(const AudioStreamBasicDescription &src, const AudioStreamBasicDescription &dest) : mConverter(NULL) { Initialize(src, dest); } virtual ~FormatConverterClient() { Destroy(); } virtual OSStatus Initialize(const AudioStreamBasicDescription &src, const AudioStreamBasicDescription &dest) { OSStatus err; Destroy(); err = AudioConverterNew(&src, &dest, &mConverter); if (err) return err; mInputFormat = src; mOutputFormat = dest; return noErr; } void Destroy() { if (mConverter) { verify_noerr(AudioConverterDispose(mConverter)); mConverter = NULL; } } virtual OSStatus Reset () { return (mConverter ? AudioConverterReset (mConverter) : noErr); } 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); } void SetQuality(UInt32 inQuality) { SetProperty(kAudioConverterSampleRateConverterQuality, sizeof(UInt32), &inQuality ); } #if 0 OSStatus ConvertBuffer(void *src, UInt32 srcSize, void *dest, UInt32 destSize) { OSStatus err; verify_noerr(err = AudioConverterConvertBuffer(mConverter, srcSize, src, &destSize, dest)); return err; } OSStatus FillBuffer( UInt32& ioOutputDataSize, void* outOutputData) { OSStatus err; verify_noerr(err = AudioConverterFillBuffer(mConverter, InputProc, this, &ioOutputDataSize, outOutputData)); return err; } #endif OSStatus FillComplexBuffer( UInt32 & ioOutputDataPacketSize, AudioBufferList & outOutputData, AudioStreamPacketDescription* outPacketDescription) { OSStatus err; err = AudioConverterFillComplexBuffer(mConverter, InputProc, this, &ioOutputDataPacketSize, &outOutputData, outPacketDescription); //printf("\n\nFillComplexBuffer returned %ld packets\n", ioOutputDataPacketSize); //DumpBufferList(outOutputData); return err; } const AudioStreamBasicDescription & GetInputFormat() { return mInputFormat; } const AudioStreamBasicDescription & GetOutputFormat() { return mOutputFormat; } protected: virtual OSStatus FormatConverterInputProc( UInt32 & ioNumberDataPackets, AudioBufferList & ioData, AudioStreamPacketDescription** outDataPacketDescription) = 0; private: static OSStatus InputProc( AudioConverterRef inAudioConverter, UInt32* ioNumberDataPackets, AudioBufferList* ioData, AudioStreamPacketDescription** outDataPacketDescription, void* inUserData) { OSStatus err; try { FormatConverterClient *This = (FormatConverterClient *)inUserData; AudioBuffer *buf = ioData->mBuffers; UInt32 nBytes = *ioNumberDataPackets * This->mInputFormat.mBytesPerPacket; for (UInt32 i = ioData->mNumberBuffers; i--; ++buf) { buf->mDataByteSize = nBytes; } //printf("\n\nInputProc - %ld packets, %ld bytes\n", *ioNumberDataPackets, nBytes); err = This->FormatConverterInputProc(*ioNumberDataPackets, *ioData, outDataPacketDescription); //DumpBufferList(*ioData); } catch (OSStatus res) { return res; } catch (...) { return -1; } return err; } #if DEBUG public: void Show() { CAShow(mConverter); } static void DumpBufferList(AudioBufferList &abl) { printf("%ld buffers:\n", abl.mNumberBuffers); AudioBuffer *buf = abl.mBuffers; for (UInt32 i = 0; i < abl.mNumberBuffers; ++i, ++buf) { printf("buffer[%ld]:\n", i); DumpBuffer(buf); } } static void DumpBuffer(AudioBuffer *buf) { printf(" channels=%ld, ptr=0x%X, size=%ld\n", buf->mNumberChannels, int(buf->mData), buf->mDataByteSize); Float32 *p = static_cast(buf->mData); for (int i = buf->mDataByteSize / sizeof(Float32); i--; ++p) printf("%f\n", *p); } #endif protected: AudioConverterRef mConverter; AudioStreamBasicDescription mInputFormat, mOutputFormat; }; #endif // __FormatConverterClient_h__