Пример #1
0
void	ACFLACCodec::GetProperty(AudioCodecPropertyID inPropertyID, UInt32& ioPropertyDataSize, void* outPropertyData)
{	
	// kAudioCodecPropertyMaximumPacketByteSize is handled in the Encoder or Decoder
	
	switch(inPropertyID)
	{
		case kAudioCodecPropertyFormatCFString:
		{
			if (ioPropertyDataSize != sizeof(CFStringRef))
			{
				CODEC_THROW(kAudioCodecBadPropertySizeError);
			}
			
			CABundleLocker lock;
			CFStringRef name = CFCopyLocalizedStringFromTableInBundle(CFSTR("FLAC"), CFSTR("CodecNames"), GetCodecBundle(), CFSTR(""));
			*(CFStringRef*)outPropertyData = name;
			break; 
		}

       case kAudioCodecPropertyRequiresPacketDescription:
  			if(ioPropertyDataSize == sizeof(UInt32))
			{
                *reinterpret_cast<UInt32*>(outPropertyData) = 1; 
            }
			else
			{
				CODEC_THROW(kAudioCodecBadPropertySizeError);
			}
            break;
			
        case kAudioCodecPropertyHasVariablePacketByteSizes:
  			if(ioPropertyDataSize == sizeof(UInt32))
			{
                *reinterpret_cast<UInt32*>(outPropertyData) = 1; // We are variable bitrate
            }
			else
			{
				CODEC_THROW(kAudioCodecBadPropertySizeError);
			}
            break;
			
		case kAudioCodecPropertyPacketFrameSize:
			if(ioPropertyDataSize == sizeof(UInt32))
			{
                *reinterpret_cast<UInt32*>(outPropertyData) = kFramesPerPacket;
            }
			else
			{
				CODEC_THROW(kAudioCodecBadPropertySizeError);
			}
			break;
			
		case kAudioCodecPropertyMagicCookie:
			if(ioPropertyDataSize >= GetMagicCookieByteSize())
			{
				GetMagicCookie(outPropertyData, ioPropertyDataSize);
				mMagicCookieLength = ioPropertyDataSize;
			}
			else
			{
				CODEC_THROW(kAudioCodecIllegalOperationError);
			}
			break;
			
        case kAudioCodecPropertyCurrentInputSampleRate:
  			if(ioPropertyDataSize == sizeof(Float64))
			{
                *reinterpret_cast<Float64*>(outPropertyData) = (Float64)(mInputFormat.mSampleRate);
			}
			else
			{
				CODEC_THROW(kAudioCodecBadPropertySizeError);
			}
            break;
			
		case kAudioCodecPropertyCurrentOutputSampleRate:
  			if(ioPropertyDataSize == sizeof(Float64))
			{
				*reinterpret_cast<Float64*>(outPropertyData) = (Float64)(mOutputFormat.mSampleRate);
			}
			else
			{
				CODEC_THROW(kAudioCodecBadPropertySizeError);
			}
			break;
			
		case kAudioCodecPropertyInputChannelLayout:
		case kAudioCodecPropertyOutputChannelLayout:
			AudioChannelLayout temp1AudioChannelLayout;
			memset(&temp1AudioChannelLayout, 0, sizeof(AudioChannelLayout));
  			if(ioPropertyDataSize == sizeof(AudioChannelLayout))
			{
				temp1AudioChannelLayout.mChannelLayoutTag = sChannelLayoutTags[mInputFormat.mChannelsPerFrame - 1];
				memcpy(outPropertyData, &temp1AudioChannelLayout, ioPropertyDataSize);
			}
			else
			{
				CODEC_THROW(kAudioCodecBadPropertySizeError);
			}
			break;
			
		case kAudioCodecPropertyAvailableInputChannelLayouts:
		case kAudioCodecPropertyAvailableOutputChannelLayouts:
  			if(ioPropertyDataSize == kMaxChannels * sizeof(AudioChannelLayoutTag))
			{
				if(mIsInitialized)
				{
					AudioChannelLayoutTag temp2AudioChannelLayout[1];
					temp2AudioChannelLayout[0] = sChannelLayoutTags[mInputFormat.mChannelsPerFrame - 1];
					ioPropertyDataSize = sizeof(AudioChannelLayoutTag);
					memcpy(reinterpret_cast<AudioChannelLayoutTag*>(outPropertyData), temp2AudioChannelLayout, ioPropertyDataSize);
				}
				else
				{
					AudioChannelLayoutTag tempAudioChannelLayout[kMaxChannels];
					tempAudioChannelLayout[0] = kAudioChannelLayoutTag_Mono;
					tempAudioChannelLayout[1] = kAudioChannelLayoutTag_Stereo;
					tempAudioChannelLayout[2] = kAudioChannelLayoutTag_MPEG_3_0_B;
					tempAudioChannelLayout[3] = kAudioChannelLayoutTag_MPEG_4_0_B;
					tempAudioChannelLayout[4] = kAudioChannelLayoutTag_MPEG_5_0_D;
					tempAudioChannelLayout[5] = kAudioChannelLayoutTag_MPEG_5_1_D;
					tempAudioChannelLayout[6] = kAudioChannelLayoutTag_AAC_6_1;
					tempAudioChannelLayout[7] = kAudioChannelLayoutTag_MPEG_7_1_B;
					memcpy(reinterpret_cast<AudioChannelLayoutTag*>(outPropertyData), tempAudioChannelLayout, ioPropertyDataSize);
				}
			}
			else
			{
				CODEC_THROW(kAudioCodecBadPropertySizeError);
			}
			break;
			
		case kAudioCodecPropertyFormatInfo:
			if(ioPropertyDataSize == sizeof(AudioFormatInfo))
			{
				AudioFormatInfo& formatInfo = *(AudioFormatInfo*)outPropertyData;
				
				// Check for cookie existence
				if((NULL != formatInfo.mMagicCookie) && (formatInfo.mMagicCookieSize > 0))
				{
					UInt32 theByteSize = formatInfo.mMagicCookieSize;
					
					FLAC__StreamMetadata_StreamInfo theConfig;
					memset (&theConfig, 0, sizeof(FLAC__StreamMetadata_StreamInfo));
					ParseMagicCookie(formatInfo.mMagicCookie, theByteSize, &theConfig);
					formatInfo.mASBD.mSampleRate = (Float64)theConfig.sample_rate;
					formatInfo.mASBD.mChannelsPerFrame = theConfig.channels;
					formatInfo.mASBD.mFramesPerPacket = theConfig.max_blocksize;
					formatInfo.mASBD.mBytesPerPacket = 0; // it's never CBR
					switch (theConfig.bits_per_sample)
					{
						case 16:
							formatInfo.mASBD.mFormatFlags = kFLACFormatFlag_16BitSourceData;
							break;
						case 20:
							formatInfo.mASBD.mFormatFlags = kFLACFormatFlag_20BitSourceData;
							break;
						case 24:
							formatInfo.mASBD.mFormatFlags = kFLACFormatFlag_24BitSourceData;
							break;
						case 32:
							formatInfo.mASBD.mFormatFlags = kFLACFormatFlag_32BitSourceData;
							break;
						default: // we don't support this
							formatInfo.mASBD.mFormatFlags = 0;
							break;						
					}
				}
				else
				{
					// We don't have a cookie, we have to check the ASBD 
					// according to the input formats
					UInt32 i;
					for(i = 0; i < GetNumberSupportedInputFormats(); ++i)
					{
						if(mInputFormatList[i].IsEqual(formatInfo.mASBD))
						{
							// IsEqual will treat 0 values as wildcards -- we can't have that with the format flags
							UInt32 tempFormatFlags = formatInfo.mASBD.mFormatFlags;
							// Fill out missing entries
							CAStreamBasicDescription::FillOutFormat(formatInfo.mASBD, mInputFormatList[i]);
							if (tempFormatFlags == 0)
							{
								formatInfo.mASBD.mFormatFlags = 0; // anything assigned here would be bad.
							}
							break;
						}
					}
					if(i == GetNumberSupportedInputFormats())
					{
						// No suitable settings found
						CODEC_THROW(kAudioCodecUnsupportedFormatError);						
					}
				}
			}
			else
			{
				CODEC_THROW(kAudioCodecBadPropertySizeError);
			}
			break;
			
		default:
			ACBaseCodec::GetProperty(inPropertyID, ioPropertyDataSize, outPropertyData);
	}
}
Пример #2
0
void	ACBaseCodec::GetPropertyInfo(AudioCodecPropertyID inPropertyID, UInt32& outPropertyDataSize, Boolean& outWritable)
{
	switch(inPropertyID)
	{
		case kAudioCodecPropertyNameCFString:
			outPropertyDataSize = SizeOf32(CFStringRef);
			outWritable = false;
			break;
			
		case kAudioCodecPropertyManufacturerCFString:
			outPropertyDataSize = SizeOf32(CFStringRef);
			outWritable = false;
			break;
			
		case kAudioCodecPropertyFormatCFString:
			outPropertyDataSize = SizeOf32(CFStringRef);
			outWritable = false;
			break;
		case kAudioCodecPropertyRequiresPacketDescription:
			outPropertyDataSize = SizeOf32(UInt32);
			outWritable = false;
			break;
			
		case kAudioCodecPropertyMinimumNumberInputPackets :
			outPropertyDataSize = SizeOf32(UInt32);
			outWritable = false;
			break;
			
		case kAudioCodecPropertyMinimumNumberOutputPackets :
			outPropertyDataSize = SizeOf32(UInt32);
			outWritable = false;
			break;

		case kAudioCodecPropertyCurrentInputFormat:
			outPropertyDataSize = SizeOf32(AudioStreamBasicDescription);
			outWritable = true;
			break;
			
		case kAudioCodecPropertySupportedInputFormats:
		case kAudioCodecPropertyInputFormatsForOutputFormat:
			outPropertyDataSize = GetNumberSupportedInputFormats() * SizeOf32(AudioStreamBasicDescription);
			outWritable = false;
			break;
			
		case kAudioCodecPropertyCurrentOutputFormat:
			outPropertyDataSize = SizeOf32(AudioStreamBasicDescription);
			outWritable = true;
			break;
			
		case kAudioCodecPropertySupportedOutputFormats:
		case kAudioCodecPropertyOutputFormatsForInputFormat:
			outPropertyDataSize = GetNumberSupportedOutputFormats() * SizeOf32(AudioStreamBasicDescription);
			outWritable = false;
			break;
			
		case kAudioCodecPropertyMagicCookie:
			outPropertyDataSize = GetMagicCookieByteSize();
			outWritable = true;
			break;
			
		case kAudioCodecPropertyInputBufferSize:
			outPropertyDataSize = SizeOf32(UInt32);
			outWritable = false;
			break;
			
		case kAudioCodecPropertyUsedInputBufferSize:
			outPropertyDataSize = SizeOf32(UInt32);
			outWritable = false;
			break;
		
		case kAudioCodecPropertyIsInitialized:
			outPropertyDataSize = SizeOf32(UInt32);
			outWritable = false;
			break;

		case kAudioCodecPropertyAvailableNumberChannels:
			outPropertyDataSize = SizeOf32(UInt32) * 2; // Mono, stereo
			outWritable = false;
			break;
			
 		case kAudioCodecPropertyPrimeMethod:
			outPropertyDataSize = SizeOf32(UInt32);
			outWritable = false;
			break;

 		case kAudioCodecPropertyPrimeInfo:
			outPropertyDataSize = SizeOf32(AudioCodecPrimeInfo);
			outWritable = false;
			break;

 		case kAudioCodecPropertyDoesSampleRateConversion:
			outPropertyDataSize = SizeOf32(UInt32);
			outWritable = false;
			break;

		default:
			CODEC_THROW(kAudioCodecUnknownPropertyError);
			break;
			
	};
}