Пример #1
0
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
Пример #3
0
OSStatus PrintBuses (FILE* file, const char* str, AudioUnit au, AudioUnitScope inScope)
{
	OSStatus result;
	UInt32 busCount;
	UInt32 theSize = sizeof(busCount);

	ca_require_noerr (result = AudioUnitGetProperty (au, kAudioUnitProperty_ElementCount,	
							inScope, 0, &busCount, &theSize), home);
		
	fprintf (file, "\t%s Elements:\n\t\t", str);
	for (UInt32 i = 0; i < busCount; ++i) {
		Float32 val;
		ca_require_noerr (result = AudioUnitGetParameter (au, kMatrixMixerParam_Enable, inScope, i, &val), home);
		UInt32 numChans;
		ca_require_noerr (result = NumberChannels (au, inScope, i, numChans), home);
		char frameCharStart = (val != 0 ? '[' : '{');
		char frameCharEnd = (val != 0 ? ']' : '}');
		fprintf (file, "%d:%c%d, %c%c  ", (int)i, frameCharStart, (int)numChans, (val != 0 ? 'T' : 'F'), frameCharEnd);
	}
	fprintf (file, "\n");
home:
	return result;
}
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
Пример #6
0
bool		CAAudioUnit::CanDo (const CAAUChanHelper		&inputs,
								const CAAUChanHelper		&outputs) const

{
// first check our state
		// huh!
	if (inputs.mNumEls == 0 && outputs.mNumEls == 0) return false;

	UInt32 elCount;
	if (GetElementCount (kAudioUnitScope_Input, elCount)) { return false; }
	if (elCount != inputs.mNumEls) return false;

	if (GetElementCount (kAudioUnitScope_Output, elCount)) { return false; }
	if (elCount != outputs.mNumEls) return false;

// (1) special cases (effects and sources (generators and instruments) only)
	UInt32	dataSize = 0;
	if (GetPropertyInfo (kAudioUnitProperty_SupportedNumChannels,
									kAudioUnitScope_Global, 0, &dataSize, NULL) != noErr)
	{
		if (Comp().Desc().IsEffect() || Comp().Desc().IsOffline()) {
			UInt32 numChan = outputs.mNumEls > 0 ? outputs.mChans[0] : inputs.mChans[0];
			for (unsigned int in = 0; in < inputs.mNumEls; ++in)
				if (numChan != inputs.mChans[in]) return false;
			for (unsigned int out = 0; out < outputs.mNumEls; ++out)
				if (numChan != outputs.mChans[out]) return false;
			return true;
		}

			// in this case, all the channels have to match the current config
		if (Comp().Desc().IsGenerator() || Comp().Desc().IsMusicDevice()) {
			for (unsigned int in = 0; in < inputs.mNumEls; ++in) {
				UInt32 chan;
				if (NumberChannels (kAudioUnitScope_Input, in, chan)) return false;
				if (chan != UInt32(inputs.mChans[in])) return false;
			}
			for (unsigned int out = 0; out < outputs.mNumEls; ++out) {
				UInt32 chan;
				if (NumberChannels (kAudioUnitScope_Output, out, chan)) return false;
				if (chan != UInt32(outputs.mChans[out])) return false;
			}
			return true;
		}

			// if we get here we can't determine anything about channel capabilities
		return false;
	}

	StackAUChannelInfo info (dataSize);

	if (GetProperty (kAudioUnitProperty_SupportedNumChannels,
							kAudioUnitScope_Global, 0,
							info.mChanInfo, &dataSize) != noErr)
	{
		return false;
	}

	int numInfo = dataSize / sizeof(AUChannelInfo);

// (2) Test for dynamic capability (or no elements on that scope)
	SInt32 dynInChans = 0;
	if (ValidateDynamicScope (kAudioUnitScope_Input, dynInChans, info.mChanInfo, numInfo)) {
		if (CheckDynCount (dynInChans, inputs) == false) return false;
	}

	SInt32 dynOutChans = 0;
	if (ValidateDynamicScope (kAudioUnitScope_Output, dynOutChans, info.mChanInfo, numInfo)) {
		if (CheckDynCount (dynOutChans, outputs) == false) return false;
	}

	if (dynOutChans && dynInChans) { return true; }

// (3)	Just need to test one side
	if (dynInChans || (inputs.mNumEls == 0)) {
		return CheckOneSide (outputs, true, info.mChanInfo, numInfo);
	}

	if (dynOutChans || (outputs.mNumEls == 0)) {
		return CheckOneSide (inputs, false, info.mChanInfo, numInfo);
	}

// (4) - not a dynamic AU, has ins and outs, and has channel constraints so we test every possible pairing
	for (unsigned int in = 0; in < inputs.mNumEls; ++in)
	{
		bool testInAlready = false;
		for (unsigned int i = 0; i < in; ++i) {
			if (inputs.mChans[i] == inputs.mChans[in]) {
				testInAlready = true;
				break;
			}
		}
		if (!testInAlready) {
			for (unsigned int out = 0; out < outputs.mNumEls; ++out) {
					// try to save a little bit and not test the same pairing multiple times...
				bool testOutAlready = false;
				for (unsigned int i = 0; i < out; ++i) {
					if (outputs.mChans[i] == outputs.mChans[out]) {
						testOutAlready = true;
						break;
					}
				}
				if (!testOutAlready) {
					if (!ValidateChannelPair (inputs.mChans[in], outputs.mChans[out],info.mChanInfo, numInfo)) {
						return false;
					}
				}
			}
		}
	}

	return true;
}
Пример #7
0
int    CAAudioUnit::GetChannelInfo (AUChannelInfo** chaninfo, UInt32& cnt)
{
	// this is the default assumption of an audio effect unit
	Boolean* isWritable = 0;
	UInt32	dataSize = 0;
		// lets see if the unit has any channel restrictions
	OSStatus result = AudioUnitGetPropertyInfo (AU(),
						    kAudioUnitProperty_SupportedNumChannels,
						    kAudioUnitScope_Global, 0,
						    &dataSize, isWritable); //don't care if this is writable

	// if this property is NOT implemented an FX unit
	// is expected to deal with same channel valance in and out

	if (result)
	{
		if (Comp().Desc().IsEffect())
		{
			return 1;
		}
		else if (Comp().Desc().IsGenerator() || Comp().Desc().IsMusicDevice()) {
			// directly query Bus Formats
			// Note that that these may refer to different subBusses
			// (eg. Kick, Snare,.. on a Drummachine)
			// eventually the Bus-Name for each configuration should be exposed
			// for the User to select..

			UInt32 elCountIn, elCountOut;

			if (GetElementCount (kAudioUnitScope_Input, elCountIn)) return -1;
			if (GetElementCount (kAudioUnitScope_Output, elCountOut)) return -1;

			cnt = std::max(elCountIn, elCountOut);

			*chaninfo = (AUChannelInfo*) malloc (sizeof (AUChannelInfo) * cnt);

			for (unsigned int i = 0; i < elCountIn; ++i) {
				UInt32 numChans;
				if (NumberChannels (kAudioUnitScope_Input, i, numChans)) return -1;
				(*chaninfo)[i].inChannels = numChans;
			}
			for (unsigned int i = elCountIn; i < cnt; ++i) {
				(*chaninfo)[i].inChannels = 0;
			}

			for (unsigned int i = 0; i < elCountOut; ++i) {
				UInt32 numChans;
				if (NumberChannels (kAudioUnitScope_Output, i, numChans)) return -1;
				(*chaninfo)[i].outChannels = numChans;
			}
			for (unsigned int i = elCountOut; i < cnt; ++i) {
				(*chaninfo)[i].outChannels = 0;
			}
			return 0;
		}
		else
		{
			// the au should either really tell us about this
			// or we will assume the worst
			return -1;
		}
	}

	*chaninfo = (AUChannelInfo*) malloc (dataSize);
	cnt = dataSize / sizeof (AUChannelInfo);

	result = GetProperty (kAudioUnitProperty_SupportedNumChannels,
			      kAudioUnitScope_Global, 0,
			      *chaninfo, &dataSize);

	if (result) { return -1; }
	return 0;
}