コード例 #1
0
ファイル: HLAudioFile.cpp プロジェクト: fruitsamples/HAL
HLFileSystemObject*	HLAudioFileFactory::Create(const FSRef& inParentFSRef, CFStringRef inName, const void* inData, UInt32 inDataSize)
{
	HLFile* theFile = NULL;
	
	//	the data for an HLAudioFile is a stream descption
	ThrowIf(inDataSize != sizeof(AudioStreamBasicDescription), CAException(paramErr), "HLAudioFileFactory::Create: the data is supposed to be an AudioStreamBasicDescription");

	const AudioStreamBasicDescription* theFormat = reinterpret_cast<const AudioStreamBasicDescription*>(inData);

	//	create the file on disk
	FSRef theFSRef;
	AudioFileID theAudioFileID = 0;
	OSStatus theError = AudioFileCreate(&inParentFSRef, inName, mObjectType, theFormat, 0, &theFSRef, &theAudioFileID);
	if(theError == 0)
	{
		AudioFileClose(theAudioFileID);
		
		//	make the object
		theFile = CreateObject(theFSRef);
		theFile->Prepare();
	}
	else
	{
		ThrowIfError(theError, CAException(theError), "HLAudioFileFactory::Create: AudioFileCreate failed");
	}
	
	return theFile;
}
コード例 #2
0
OSStatus OutputFile (const char 							*inputFilename, 
						UInt32								inFileType,
						OSType 								subType, 
						bool								overwrite,
						const AudioStreamBasicDescription 	&desc, 
						AudioFileID 						&outFile)
{
	int len = strlen (inputFilename);
	char* copyStr = (char*)malloc (len);
	strcpy (copyStr, inputFilename);
	int i = len;
	FSRef parentDir;
	char filename[512];
	memset (filename, 0, 512);
	OSStatus result = fnfErr;
	CFStringRef cfstr = NULL;
	
	while (--i >= 0) {
		if (copyStr[i] == '/') {// find the delimiter for the directory
			copyStr[i] = 0;
			require_noerr (result = FSPathMakeRef ((const UInt8*)copyStr, &parentDir, 0), home);
			int j = len;
			while (--j > i) { //find the ext
				if (inputFilename[j] == '.')
					break;
			}
				// copy the name itself first
			memcpy (filename, inputFilename + i + 1, (len - i - (len - j + 1)));
				// append the -subType suffix before the .ext
			char* temp = filename + strlen(filename);
			temp += sprintf (temp, "-%4.4s", (char*)&subType);
				// append the file type .ext
			memcpy (temp, inputFilename + j, (len - j));
			
			printf ("Output File: Dir:%s, FileName:%s\n", copyStr, filename);
			
			cfstr = CFStringCreateWithCString (NULL, filename, kCFStringEncodingASCII);
			
			FSRef outRef;
			result = AudioFileCreate (&parentDir, cfstr, inFileType, &desc, 0/*flags*/, &outRef, &outFile);
			
			if (result == dupFNErr) { // file already exits - initialie it?
				if (overwrite) {
					len += 5;
					char* name = (char*)malloc (len);
					strcpy (name, copyStr);
					strcat (name, "/");
					strcat (name, filename);
	
					require_noerr (result = FSPathMakeRef ((const UInt8*)name, &outRef, 0), home);
					
					require_noerr (result = AudioFileInitialize (&outRef, inFileType,
														&desc, 0, &outFile), home);
					free (name);
				} else {
					printf ("Output File exists - specify overwrite\n");
				}
			}
			break;
		}
	}
home:
	if (cfstr)
		CFRelease (cfstr);
	free (copyStr);
	return result;
}
コード例 #3
0
ファイル: CAAudioFile.cpp プロジェクト: gesius/AudioComplete
// _______________________________________________________________________________________
//
// called to create the file -- or update its format/channel layout/properties based on an encoder
// setting change
void	CAAudioFile::FileFormatChanged(const FSRef *parentDir, CFStringRef filename, AudioFileTypeID filetype)
{
	LOG_FUNCTION("CAAudioFile::FileFormatChanged", "%p", this);
	XThrowIf(mMode != kPreparingToCreate && mMode != kPreparingToWrite, kExtAudioFileError_InvalidOperationOrder, "new file not prepared");

	UInt32 propertySize;
	OSStatus err;
	AudioStreamBasicDescription saveFileDataFormat = mFileDataFormat;

#if VERBOSE_CONVERTER
	mFileDataFormat.PrintFormat(stdout, "", "Specified file data format");
#endif

	// Find out the actual format the converter will produce. This is necessary in
	// case the bitrate has forced a lower sample rate, which needs to be set correctly
	// in the stream description passed to AudioFileCreate.
	if (mConverter != NULL) {
		propertySize = sizeof(AudioStreamBasicDescription);
		Float64 origSampleRate = mFileDataFormat.mSampleRate;
		XThrowIfError(AudioConverterGetProperty(mConverter, kAudioConverterCurrentOutputStreamDescription, &propertySize, &mFileDataFormat), "get audio converter's output stream description");
		// do the same for the channel layout being output by the converter
#if VERBOSE_CONVERTER
		mFileDataFormat.PrintFormat(stdout, "", "Converter output");
#endif
		if (fiszero(mFileDataFormat.mSampleRate))
			mFileDataFormat.mSampleRate = origSampleRate;
		err = AudioConverterGetPropertyInfo(mConverter, kAudioConverterOutputChannelLayout, &propertySize, NULL);
		if (err == noErr && propertySize > 0) {
			AudioChannelLayout *layout = static_cast<AudioChannelLayout *>(malloc(propertySize));
			err = AudioConverterGetProperty(mConverter, kAudioConverterOutputChannelLayout, &propertySize, layout);
			if (err) {
				free(layout);
				XThrow(err, "couldn't get audio converter's output channel layout");
			}
			mFileChannelLayout = layout;
#if VERBOSE_CHANNELMAP
			printf("got new file's channel layout from converter: %s\n", CAChannelLayouts::ConstantToString(mFileChannelLayout.Tag()));
#endif
			free(layout);
		}
	}

	// create the output file
	if (mMode == kPreparingToCreate) {
		CAStreamBasicDescription newFileDataFormat = mFileDataFormat;
		if (fiszero(newFileDataFormat.mSampleRate))
			newFileDataFormat.mSampleRate = 44100;	// just make something up for now
#if VERBOSE_CONVERTER
		newFileDataFormat.PrintFormat(stdout, "", "Applied to new file");
#endif
		XThrowIfError(AudioFileCreate(parentDir, filename, filetype, &newFileDataFormat, 0, &mFSRef, &mAudioFile), "create audio file");
		mMode = kPreparingToWrite;
		mOwnOpenFile = true;
	} else if (saveFileDataFormat != mFileDataFormat || fnotequal(saveFileDataFormat.mSampleRate, mFileDataFormat.mSampleRate)) {
		// second check must be explicit since operator== on ASBD treats SR of zero as "don't care"
		if (fiszero(mFileDataFormat.mSampleRate))
			mFileDataFormat.mSampleRate = mClientDataFormat.mSampleRate;
#if VERBOSE_CONVERTER
		mFileDataFormat.PrintFormat(stdout, "", "Applied to new file");
#endif
		XThrowIf(fiszero(mFileDataFormat.mSampleRate), kExtAudioFileError_InvalidDataFormat, "file's sample rate is 0");
		XThrowIfError(AudioFileSetProperty(mAudioFile, kAudioFilePropertyDataFormat, sizeof(AudioStreamBasicDescription), &mFileDataFormat), "couldn't update file's data format");
	}

	UInt32 deferSizeUpdates = 1;
	err = AudioFileSetProperty(mAudioFile, kAudioFilePropertyDeferSizeUpdates, sizeof(UInt32), &deferSizeUpdates);

	if (mConverter != NULL) {
		// encoder
		// get the magic cookie, if any, from the converter
		delete[] mMagicCookie;	mMagicCookie = NULL;
		mMagicCookieSize = 0;

		err = AudioConverterGetPropertyInfo(mConverter, kAudioConverterCompressionMagicCookie, &propertySize, NULL);

		// we can get a noErr result and also a propertySize == 0
		// -- if the file format does support magic cookies, but this file doesn't have one.
		if (err == noErr && propertySize > 0) {
			mMagicCookie = new Byte[propertySize];
			XThrowIfError(AudioConverterGetProperty(mConverter, kAudioConverterCompressionMagicCookie, &propertySize, mMagicCookie), "get audio converter's magic cookie");
			mMagicCookieSize = propertySize;	// the converter lies and tell us the wrong size
			// now set the magic cookie on the output file
			UInt32 willEatTheCookie = false;
			// the converter wants to give us one; will the file take it?
			err = AudioFileGetPropertyInfo(mAudioFile, kAudioFilePropertyMagicCookieData,
					NULL, &willEatTheCookie);
			if (err == noErr && willEatTheCookie) {
#if VERBOSE_CONVERTER
				printf("Setting cookie on encoded file\n");
#endif
				XThrowIfError(AudioFileSetProperty(mAudioFile, kAudioFilePropertyMagicCookieData, mMagicCookieSize, mMagicCookie), "set audio file's magic cookie");
			}
		}

		// get maximum packet size
		propertySize = sizeof(UInt32);
		XThrowIfError(AudioConverterGetProperty(mConverter, kAudioConverterPropertyMaximumOutputPacketSize, &propertySize, &mFileMaxPacketSize), "get audio converter's maximum output packet size");

		AllocateBuffers(true /* okToFail */);
	} else {
		InitFileMaxPacketSize();
	}

	if (mFileChannelLayout.IsValid() && mFileChannelLayout.NumberChannels() > 2) {
		// don't bother tagging mono/stereo files
		UInt32 isWritable;
		err = AudioFileGetPropertyInfo(mAudioFile, kAudioFilePropertyChannelLayout, NULL, &isWritable);
		if (!err && isWritable) {
#if VERBOSE_CHANNELMAP
			printf("writing file's channel layout: %s\n", CAChannelLayouts::ConstantToString(mFileChannelLayout.Tag()));
#endif
			err = AudioFileSetProperty(mAudioFile, kAudioFilePropertyChannelLayout,
				mFileChannelLayout.Size(), &mFileChannelLayout.Layout());
			if (err)
				CAXException::Warning("could not set the file's channel layout", err);
		} else {
#if VERBOSE_CHANNELMAP
			printf("file won't accept a channel layout (write)\n");
#endif
		}
	}

	UpdateClientMaxPacketSize();	// also sets mFrame0Offset
	mPacketMark = 0;
	mFrameMark = 0;
}