Ejemplo n.º 1
0
static void ASBD_NtoB(const AudioStreamBasicDescription *infmt, AudioStreamBasicDescription *outfmt)
{
	*(UInt64 *)&outfmt->mSampleRate = EndianU64_NtoB(*(UInt64 *)&infmt->mSampleRate);
	outfmt->mFormatID = EndianU32_NtoB(infmt->mFormatID);
	outfmt->mFormatFlags = EndianU32_NtoB(infmt->mFormatFlags);
	outfmt->mBytesPerPacket = EndianU32_NtoB(infmt->mBytesPerPacket);
	outfmt->mFramesPerPacket = EndianU32_NtoB(infmt->mFramesPerPacket);
	outfmt->mBytesPerFrame = EndianU32_NtoB(infmt->mBytesPerFrame);
	outfmt->mChannelsPerFrame = EndianU32_NtoB(infmt->mChannelsPerFrame);
	outfmt->mBitsPerChannel = EndianU32_NtoB(infmt->mBitsPerChannel);
}
Ejemplo n.º 2
0
//FLAC__StreamMetadata_StreamInfo
void ACFLACCodec::GetMagicCookie(void* outMagicCookieData, UInt32& ioMagicCookieDataByteSize) const
{

	Byte *						buffer;
	Byte *						currPtr;
	AudioFormatAtom * frmaAtom;
	FullAtomHeader * flacAtom;
	AudioTerminatorAtom * termAtom;
	SInt32						atomSize;
	UInt32						flacSize;
	UInt32						chanSize;
	UInt32						frmaSize;
	UInt32						termSize;
	FLAC__StreamMetadata_StreamInfo *		config;
	OSStatus					status;
	UInt32						tempMaxFrameBytes;
	
	//RequireAction( sampleDesc != nil, return paramErr; );

	config		= nil;
	
	frmaSize = sizeof(AudioFormatAtom);
	flacSize		= sizeof(FullAtomHeader) + sizeof(FLAC__StreamMetadata_StreamInfo);
	chanSize		= 0;
	termSize = sizeof(AudioTerminatorAtom);

	// if we're encoding more than two channels, add an AudioChannelLayout atom to describe the layout
	if ( mOutputFormat.mChannelsPerFrame > 2 )
	{
		chanSize = sizeof(FullAtomHeader) + offsetof(AudioChannelLayout, mChannelDescriptions);
	}

	// create buffer of the required size
	atomSize = frmaSize + flacSize + chanSize + termSize;
	
	// Someone might have a stereo/mono cookie while we're trying to do surround.
	if ((UInt32)atomSize > ioMagicCookieDataByteSize)
	{
		CODEC_THROW(kAudioCodecBadPropertySizeError);
	}
	
	tempMaxFrameBytes = kInputBufferPackets * mOutputFormat.mChannelsPerFrame * ((10 + kMaxSampleSize) / 8) + 1;

	buffer = (Byte *)calloc( atomSize, 1 );
	currPtr = buffer;

	// fill in the atom stuff
	frmaAtom = (AudioFormatAtom *) currPtr;
	frmaAtom->size			= EndianU32_NtoB( frmaSize );
	frmaAtom->atomType		= EndianU32_NtoB( kAudioFormatAtomType );
	frmaAtom->format	= EndianU32_NtoB( 'flac' );
	currPtr += frmaSize;

	// fill in the FLAC config
	flacAtom = (FullAtomHeader *) currPtr;
	flacAtom->size				= EndianU32_NtoB( flacSize );
	flacAtom->type				= EndianU32_NtoB( 'flac' );
	flacAtom->versionFlags		= 0;
	currPtr += sizeof(FullAtomHeader);

/*
	unsigned min_blocksize, max_blocksize;
	unsigned min_framesize, max_framesize;
	unsigned sample_rate;
	unsigned channels;
	unsigned bits_per_sample;
	FLAC__uint64 total_samples;
	FLAC__byte md5sum[16];
*/
	config = (FLAC__StreamMetadata_StreamInfo *) currPtr;
	if (mCookieDefined)
	{
		config->min_blocksize	= EndianU32_NtoB( mStreamInfo.min_blocksize );
		config->max_blocksize	= EndianU32_NtoB( mStreamInfo.max_blocksize );
		config->min_framesize	= EndianU32_NtoB( mStreamInfo.min_framesize );
		config->max_framesize	= EndianU32_NtoB( mStreamInfo.max_framesize );
		config->sample_rate		= EndianU32_NtoB( mStreamInfo.sample_rate );
		config->channels		= EndianU32_NtoB( mStreamInfo.channels );
		config->bits_per_sample	= EndianU32_NtoB( mStreamInfo.bits_per_sample );
		config->total_samples	= EndianU64_NtoB( mStreamInfo.total_samples );
		config->md5sum[0]		= mStreamInfo.md5sum[0];
		config->md5sum[1]		= mStreamInfo.md5sum[1];
		config->md5sum[2]		= mStreamInfo.md5sum[2];
		config->md5sum[3]		= mStreamInfo.md5sum[3];
		config->md5sum[4]		= mStreamInfo.md5sum[4];
		config->md5sum[5]		= mStreamInfo.md5sum[5];
		config->md5sum[6]		= mStreamInfo.md5sum[6];
		config->md5sum[7]		= mStreamInfo.md5sum[7];
		config->md5sum[8]		= mStreamInfo.md5sum[8];
		config->md5sum[9]		= mStreamInfo.md5sum[9];
		config->md5sum[10]		= mStreamInfo.md5sum[10];
		config->md5sum[11]		= mStreamInfo.md5sum[11];
		config->md5sum[12]		= mStreamInfo.md5sum[12];
		config->md5sum[13]		= mStreamInfo.md5sum[13];
		config->md5sum[14]		= mStreamInfo.md5sum[14];
		config->md5sum[15]		= mStreamInfo.md5sum[15];
	}
	else
	{
		config->min_blocksize	= EndianU32_NtoB( kFLACDefaultFrameSize );
		config->max_blocksize	= EndianU32_NtoB( kFLACDefaultFrameSize );
		config->min_framesize	= EndianU32_NtoB( 0 );
		config->max_framesize	= EndianU32_NtoB( 0 );
		config->sample_rate		= EndianU32_NtoB( (UInt32)(mOutputFormat.mSampleRate) );
		config->channels		= EndianU32_NtoB(mOutputFormat.mChannelsPerFrame);
		config->bits_per_sample	= EndianU32_NtoB(mBitDepth);
		config->total_samples	= 0;
		config->md5sum[0]		= 0;
		config->md5sum[1]		= 0;
		config->md5sum[2]		= 0;
		config->md5sum[3]		= 0;
		config->md5sum[4]		= 0;
		config->md5sum[5]		= 0;
		config->md5sum[6]		= 0;
		config->md5sum[7]		= 0;
		config->md5sum[8]		= 0;
		config->md5sum[9]		= 0;
		config->md5sum[10]		= 0;
		config->md5sum[11]		= 0;
		config->md5sum[12]		= 0;
		config->md5sum[13]		= 0;
		config->md5sum[14]		= 0;
		config->md5sum[15]		= 0;
	}

	currPtr += sizeof(FLAC__StreamMetadata_StreamInfo);

	// if we're encoding more than two channels, add an AudioChannelLayout atom to describe the layout
	// Unfortunately there is no way to avoid dealing with an atom here
	if ( mOutputFormat.mChannelsPerFrame > 2 )
	{
		AudioChannelLayoutTag		tag;
		FullAtomHeader *			chan;
		AudioChannelLayout *		layout;
		
		chan = (FullAtomHeader *) currPtr;
		chan->size = EndianU32_NtoB( chanSize );
		chan->type = EndianU32_NtoB( AudioChannelLayoutAID );
		// version flags == 0
		currPtr += sizeof(FullAtomHeader);
		
		// we use a predefined set of layout tags so we don't need to write any channel descriptions
		layout = (AudioChannelLayout *) currPtr;
		tag = sChannelLayoutTags[mOutputFormat.mChannelsPerFrame - 1];
		layout->mChannelLayoutTag			= EndianU32_NtoB( tag );
		layout->mChannelBitmap				= 0;
		layout->mNumberChannelDescriptions	= 0;
		currPtr += offsetof(AudioChannelLayout, mChannelDescriptions);
	}
	
	// fill in Terminator atom header
	termAtom = (AudioTerminatorAtom *) currPtr;
	termAtom->size = EndianU32_NtoB( termSize );
	termAtom->atomType = EndianU32_NtoB( kAudioTerminatorAtomType );

	// all good, return the new description
	memcpy (outMagicCookieData, (const void *)(buffer), atomSize);
	ioMagicCookieDataByteSize = atomSize;
	status = noErr;
	
	// delete any memory we allocated
	if ( buffer != NULL )
	{
		delete buffer;
		buffer = NULL;
	}

}