char *CAStreamBasicDescription::AsString(char *buf, size_t bufsize) const
{
	char *theBuffer = buf;
	int nc;
	char formatID[5];
	*(UInt32 *)formatID = CFSwapInt32HostToBig(mFormatID);
	formatID[4] = '\0';
	nc = snprintf(buf, bufsize, "%2d ch, %6.0f Hz, '%-4.4s' (0x%08X) ", (int)NumberChannels(), mSampleRate, formatID, (int)mFormatFlags);
	buf += nc; bufsize -= nc;
	if (mFormatID == kAudioFormatLinearPCM)
    {
		bool isInt = !(mFormatFlags & kLinearPCMFormatFlagIsFloat);
		int wordSize = SampleWordSize();
		const char *endian = (wordSize > 1) ? 
			((mFormatFlags & kLinearPCMFormatFlagIsBigEndian) ? " big-endian" : " little-endian" ) : "";
		const char *sign = isInt ? 
			((mFormatFlags & kLinearPCMFormatFlagIsSignedInteger) ? " signed" : " unsigned") : "";
		const char *floatInt = isInt ? "integer" : "float";
		char packed[32];
		if (wordSize > 0 && PackednessIsSignificant()) 
        {
			if (mFormatFlags & kLinearPCMFormatFlagIsPacked)
				sprintf(packed, "packed in %d bytes", wordSize);
			else
				sprintf(packed, "unpacked in %d bytes", wordSize);
		} else
			packed[0] = '\0';
		const char *align = (wordSize > 0 && AlignmentIsSignificant()) ?
			((mFormatFlags & kLinearPCMFormatFlagIsAlignedHigh) ? " high-aligned" : " low-aligned") : "";
		const char *deinter = (mFormatFlags & kAudioFormatFlagIsNonInterleaved) ? ", deinterleaved" : "";
		const char *commaSpace = (packed[0]!='\0') || (align[0]!='\0') ? ", " : "";
		char bitdepth[20];

#if CA_PREFER_FIXED_POINT
		int fracbits = (mFormatFlags & kLinearPCMFormatFlagsSampleFractionMask) >> kLinearPCMFormatFlagsSampleFractionShift;
		if (fracbits > 0)
			sprintf(bitdepth, "%d.%d", (int)mBitsPerChannel - fracbits, fracbits);
		else
#endif
			sprintf(bitdepth, "%d", (int)mBitsPerChannel);
		
		nc = snprintf(buf, bufsize, "%s-bit%s%s %s%s%s%s%s",
			bitdepth, endian, sign, floatInt, 
			commaSpace, packed, align, deinter);
		//buf += nc; bufsize -= nc;
	} else if (mFormatID == 'alac') {	//	kAudioFormatAppleLossless
char *CAStreamBasicDescription::AsString(char *buf, size_t _bufsize) const
{
    int bufsize = (int)_bufsize;	// must be signed to protect against overflow
    char *theBuffer = buf;
    int nc;
    char formatID[24];
    CAStringForOSType (mFormatID, formatID);
    nc = snprintf(buf, bufsize, "%2d ch, %6.0f Hz, %s (0x%08X) ", (int)NumberChannels(), mSampleRate, formatID, (int)mFormatFlags);
    buf += nc;
    if ((bufsize -= nc) <= 0) goto exit;
    if (mFormatID == kAudioFormatLinearPCM) {
        bool isInt = !(mFormatFlags & kLinearPCMFormatFlagIsFloat);
        int wordSize = SampleWordSize();
        const char *endian = (wordSize > 1) ?
                             ((mFormatFlags & kLinearPCMFormatFlagIsBigEndian) ? " big-endian" : " little-endian" ) : "";
        const char *sign = isInt ?
                           ((mFormatFlags & kLinearPCMFormatFlagIsSignedInteger) ? " signed" : " unsigned") : "";
        const char *floatInt = isInt ? "integer" : "float";
        char packed[32];
        if (wordSize > 0 && PackednessIsSignificant()) {
            if (mFormatFlags & kLinearPCMFormatFlagIsPacked)
                snprintf(packed, sizeof(packed), "packed in %d bytes", wordSize);
            else
                snprintf(packed, sizeof(packed), "unpacked in %d bytes", wordSize);
        } else
            packed[0] = '\0';
        const char *align = (wordSize > 0 && AlignmentIsSignificant()) ?
                            ((mFormatFlags & kLinearPCMFormatFlagIsAlignedHigh) ? " high-aligned" : " low-aligned") : "";
        const char *deinter = (mFormatFlags & kAudioFormatFlagIsNonInterleaved) ? ", deinterleaved" : "";
        const char *commaSpace = (packed[0]!='\0') || (align[0]!='\0') ? ", " : "";
        char bitdepth[20];

        int fracbits = (mFormatFlags & kLinearPCMFormatFlagsSampleFractionMask) >> kLinearPCMFormatFlagsSampleFractionShift;
        if (fracbits > 0)
            snprintf(bitdepth, sizeof(bitdepth), "%d.%d", (int)mBitsPerChannel - fracbits, fracbits);
        else
            snprintf(bitdepth, sizeof(bitdepth), "%d", (int)mBitsPerChannel);

        /* nc =*/ snprintf(buf, bufsize, "%s-bit%s%s %s%s%s%s%s",
                           bitdepth, endian, sign, floatInt,
                           commaSpace, packed, align, deinter);
        // buf += nc; if ((bufsize -= nc) <= 0) goto exit;
    } else if (mFormatID == 'alac') {	//	kAudioFormatAppleLossless
void CAStreamBasicDescription::PrintFormat2(FILE *f, const char *indent, const char *name) const
{
	fprintf(f, "%s%s ", indent, name);
	char formatID[5];
	*(UInt32 *)formatID = CFSwapInt32HostToBig(mFormatID);
	formatID[4] = '\0';
	fprintf(f, "%2d ch, %6.0f Hz, '%-4.4s' (0x%08X) ",		
				(int)NumberChannels(), mSampleRate, formatID,
				(int)mFormatFlags);
	if (mFormatID == kAudioFormatLinearPCM) {
		bool isInt = !(mFormatFlags & kLinearPCMFormatFlagIsFloat);
		int wordSize = SampleWordSize();
		const char *endian = (wordSize > 1) ? 
			((mFormatFlags & kLinearPCMFormatFlagIsBigEndian) ? " big-endian" : " little-endian" ) : "";
		const char *sign = isInt ? 
			((mFormatFlags & kLinearPCMFormatFlagIsSignedInteger) ? " signed" : " unsigned") : "";
		const char *floatInt = isInt ? "integer" : "float";
		char packed[32];
		if (wordSize > 0 && PackednessIsSignificant()) {
			if (mFormatFlags & kLinearPCMFormatFlagIsPacked)
				sprintf(packed, "packed in %d bytes", wordSize);
			else
				sprintf(packed, "unpacked in %d bytes", wordSize);
		} else
			packed[0] = '\0';
		const char *align = (wordSize > 0 && AlignmentIsSignificant()) ?
			((mFormatFlags & kLinearPCMFormatFlagIsAlignedHigh) ? " high-aligned" : " low-aligned") : "";
		const char *deinter = (mFormatFlags & kAudioFormatFlagIsNonInterleaved) ? ", deinterleaved" : "";
		const char *commaSpace = (packed[0]!='\0') || (align[0]!='\0') ? ", " : "";
		
		fprintf(f, "%d-bit%s%s %s%s%s%s%s",
			(int)mBitsPerChannel, endian, sign, floatInt, 
			commaSpace, packed, align, deinter);
	} else if (mFormatID == 'alac') {	//	kAudioFormatAppleLossless
		int sourceBits = 0;
		switch (mFormatFlags)
		{
			case 1:	//	kAppleLosslessFormatFlag_16BitSourceData
				sourceBits = 16;
				break;
    		case 2:	//	kAppleLosslessFormatFlag_20BitSourceData
    			sourceBits = 20;
    			break;
    		case 3:	//	kAppleLosslessFormatFlag_24BitSourceData
    			sourceBits = 24;
    			break;
    		case 4:	//	kAppleLosslessFormatFlag_32BitSourceData
    			sourceBits = 32;
    			break;
		}
		if (sourceBits)
			fprintf(f, "from %d-bit source, ", sourceBits);
		else
			fprintf(f, "from UNKNOWN source bit depth, ");
			
		fprintf(f, "%d frames/packet", (int)mFramesPerPacket);
	}
	else
		fprintf(f, "%d bits/channel, %d bytes/packet, %d frames/packet, %d bytes/frame", 
			(int)mBitsPerChannel, (int)mBytesPerPacket, (int)mFramesPerPacket, (int)mBytesPerFrame);
}
char *CAStreamBasicDescription::AsString(char *buf, size_t _bufsize, bool brief /*=false*/) const
{
	int bufsize = (int)_bufsize;	// must be signed to protect against overflow
	char *theBuffer = buf;
	int nc;
	char formatID[24];
	CAStringForOSType(mFormatID, formatID, sizeof(formatID));
	if (brief) {
		CommonPCMFormat com;
		bool interleaved;
		if (IdentifyCommonPCMFormat(com, &interleaved) && com != kPCMFormatOther) {
			const char *desc;
			switch (com) {
			case kPCMFormatInt16:
				desc = "Int16";
				break;
			case kPCMFormatFixed824:
				desc = "Int8.24";
				break;
			case kPCMFormatFloat32:
				desc = "Float32";
				break;
			case kPCMFormatFloat64:
				desc = "Float64";
				break;
			default:
				desc = NULL;
				break;
			}
			if (desc) {
				const char *inter ="";
				if (mChannelsPerFrame > 1)
					inter = !interleaved ? ", non-inter" : ", inter";
				snprintf(buf, static_cast<size_t>(bufsize), "%2d ch, %6.0f Hz, %s%s", (int)mChannelsPerFrame, mSampleRate, desc, inter);
				return theBuffer;
			}
		}
		if (mChannelsPerFrame == 0 && mSampleRate == 0.0 && mFormatID == 0) {
			snprintf(buf, static_cast<size_t>(bufsize), "%2d ch, %6.0f Hz", (int)mChannelsPerFrame, mSampleRate);
			return theBuffer;
		}
	}
	
	nc = snprintf(buf, static_cast<size_t>(bufsize), "%2d ch, %6.0f Hz, %s (0x%08X) ", (int)NumberChannels(), mSampleRate, formatID, (int)mFormatFlags);
	buf += nc; if ((bufsize -= nc) <= 0) goto exit;
	if (mFormatID == kAudioFormatLinearPCM) {
		bool isInt = !(mFormatFlags & kLinearPCMFormatFlagIsFloat);
		int wordSize = static_cast<int>(SampleWordSize());
		const char *endian = (wordSize > 1) ? 
			((mFormatFlags & kLinearPCMFormatFlagIsBigEndian) ? " big-endian" : " little-endian" ) : "";
		const char *sign = isInt ? 
			((mFormatFlags & kLinearPCMFormatFlagIsSignedInteger) ? " signed" : " unsigned") : "";
		const char *floatInt = isInt ? "integer" : "float";
		char packed[32];
		if (wordSize > 0 && PackednessIsSignificant()) {
			if (mFormatFlags & kLinearPCMFormatFlagIsPacked)
				snprintf(packed, sizeof(packed), "packed in %d bytes", wordSize);
			else
				snprintf(packed, sizeof(packed), "unpacked in %d bytes", wordSize);
		} else
			packed[0] = '\0';
		const char *align = (wordSize > 0 && AlignmentIsSignificant()) ?
			((mFormatFlags & kLinearPCMFormatFlagIsAlignedHigh) ? " high-aligned" : " low-aligned") : "";
		const char *deinter = (mFormatFlags & kAudioFormatFlagIsNonInterleaved) ? ", deinterleaved" : "";
		const char *commaSpace = (packed[0]!='\0') || (align[0]!='\0') ? ", " : "";
		char bitdepth[20];

		int fracbits = (mFormatFlags & kLinearPCMFormatFlagsSampleFractionMask) >> kLinearPCMFormatFlagsSampleFractionShift;
		if (fracbits > 0)
			snprintf(bitdepth, sizeof(bitdepth), "%d.%d", (int)mBitsPerChannel - fracbits, fracbits);
		else
			snprintf(bitdepth, sizeof(bitdepth), "%d", (int)mBitsPerChannel);
		
		/*nc =*/ snprintf(buf, static_cast<size_t>(bufsize), "%s-bit%s%s %s%s%s%s%s",
			bitdepth, endian, sign, floatInt, 
			commaSpace, packed, align, deinter);
		// buf += nc; if ((bufsize -= nc) <= 0) goto exit;
	} else if (mFormatID == 'alac') {	//	kAudioFormatAppleLossless