ExtAudioFileDispose not releasing certain files
ExtAudioFileDispose not releasing certain files
- Subject: ExtAudioFileDispose not releasing certain files
- From: Citizen <email@hidden>
- Date: Fri, 11 May 2007 10:14:52 +0100
Hi all,
I'm ripping files from audio CDs with code based on the ConvertFile
ExtAudioFile example:
/Developer/Examples/CoreAudio/SimpleSDK/ConvertFile/
As I'm ripping the files I'm converting them into 'ALAC' MPEG-4 files.
Everything works fine for most CDs.
But when I use a specific CD, ExtAudioFileDispose(infile), does not
seem to release the file. Which means that the CD can't be ejected
until the application is closed down.
The CD that causes the problem has a forward slash "/" character in
its display name.
If I close down iTunes and temporarily rename the "~/Library/
Preferences/CD Info.cidb" file and re-insert the CD and try again:
everything works as it should.
So this suggests that there is a problem with closing audio files
with the Core Audio framework where the path contains a "/" in a
folder's (or file's?) display name.
Can anyone suggest a workaround/solution?
So far I have tried:
1) replacing ExtAudioFileOpen(&inputFSRef, &infile) with
ExtAudioFileWrapAudioFileID(infileId, false, &infile) so I can use...
ExtAudioFileDispose(outfile);
ExtAudioFileDispose(infile);
AudioFileClose(infileId);
...to close.
This made no difference.
2) Using various APIs and system calls to (force) eject the CD. All
to no avail.
3) Unmounting and mounting the CD. Didn't work.
4) Attempting to force the NSThread that the code runs in, to exit.
Nada.
How can I give control of the CD back to the system? If the list
thinks this requires a non Core Audio solution I'll repost to cocoadev.
But thanks in advance for taking a look.
Cheers,
Dave
------
David Kennedy (http://www.zenopolis.com)
------
P.S. (The code I'm using is included below, just in case)
- (BOOL) copyAndCompressAIFF:(NSString *)source toAppleLossless:
(NSString *)destination delegate:(id)delegate
{
BOOL returnValue = NO;
NSString * fname = [destination lastPathComponent];
NSString * dirPath = [destination stringByDeletingLastPathComponent];
OSType format = kAudioFormatAppleLossless; // 'alac'
OSType fileType = kAudioFileM4AType; // 'm4af'
FSRef inputFSRef;
OSStatus err = FSPathMakeRef((const UInt8 *)[source
fileSystemRepresentation], &inputFSRef, NULL);
if(err != noErr) { return returnValue;}
FSRef dirFSRef;
err = FSPathMakeRef((const UInt8 *)[dirPath
fileSystemRepresentation], &dirFSRef, NULL);
if(err != noErr) { return returnValue; }
// open the input file
AudioFileID infileId;
err = AudioFileOpen(&inputFSRef, fsRdPerm, 0, &infileId);
if (err != noErr) { return returnValue; }
ExtAudioFileRef infile;
err = ExtAudioFileWrapAudioFileID(infileId, false, &infile);
if(err != noErr) { return returnValue; }
// ExtAudioFileRef infile;
// err = ExtAudioFileOpen(&inputFSRef, &infile);
// if(err != noErr) {
// //NSLog(@"ExtAudioFileOpen error %i", err);
// return returnValue;
// }
// get the input file format
AudioStreamBasicDescription inputFormat;
UInt32 size = sizeof(inputFormat);
err = ExtAudioFileGetProperty(infile,
kExtAudioFileProperty_FileDataFormat, &size, &inputFormat);
if(err != noErr) { return returnValue; }
char inputFormatID[5];
*(UInt32 *)inputFormatID = CFSwapInt32HostToBig(inputFormat.mFormatID);
inputFormatID[4] = '\0';
// create the output format
AudioStreamBasicDescription outputFormat;
outputFormat.mFormatID = format;
outputFormat.mSampleRate = inputFormat.mSampleRate;
outputFormat.mChannelsPerFrame = inputFormat.mChannelsPerFrame;
outputFormat.mFormatFlags = (UInt32)1;
outputFormat.mBytesPerPacket = 0;
outputFormat.mFramesPerPacket = (UInt32)4096;
outputFormat.mBytesPerFrame = 0;
outputFormat.mBitsPerChannel = 16;
outputFormat.mReserved =0;
char outputFormatID[5];
*(UInt32 *)outputFormatID = CFSwapInt32HostToBig
(outputFormat.mFormatID);
outputFormatID[4] = '\0';
// create the output file
ExtAudioFileRef outfile;
err = ExtAudioFileCreateNew(&dirFSRef, (CFStringRef)fname, fileType,
&outputFormat, NULL, &outfile);
if(err != noErr) { return returnValue; }
// get and set the client format to lpcm
AudioStreamBasicDescription clientFormat;
clientFormat = inputFormat;
clientFormat.mFormatFlags = kLinearPCMFormatFlagIsBigEndian |
kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked;
clientFormat.mBitsPerChannel = 16;
char clientFormatID[5];
*(UInt32 *)clientFormatID = CFSwapInt32HostToBig
(clientFormat.mFormatID);
clientFormatID[4] = '\0';
size = sizeof(clientFormat);
err = ExtAudioFileSetProperty(infile,
kExtAudioFileProperty_ClientDataFormat, size, &clientFormat);
if(err != noErr) { return returnValue; }
size = sizeof(clientFormat);
err = ExtAudioFileSetProperty(outfile,
kExtAudioFileProperty_ClientDataFormat, size, &clientFormat);
if(err != noErr) { return returnValue; }
// set up buffers
UInt32 kSrcBufSize = 32768;
char srcBuffer[kSrcBufSize];
unsigned long long bytes;
// read, convert and write
while (YES) {
AudioBufferList fillBufList;
fillBufList.mNumberBuffers = 1;
fillBufList.mBuffers[0].mNumberChannels =
inputFormat.mChannelsPerFrame;
fillBufList.mBuffers[0].mDataByteSize = kSrcBufSize;
fillBufList.mBuffers[0].mData = srcBuffer;
UInt32 numFrames = (kSrcBufSize / inputFormat.mBytesPerPacket) *
inputFormat.mFramesPerPacket; // normally 1
err = ExtAudioFileRead(infile, &numFrames, &fillBufList);
if (err || !numFrames) { break; }
err = ExtAudioFileWrite(outfile, numFrames, &fillBufList);
if(err != noErr) {
NSDictionary * errorDict = [NSDictionary
dictionaryWithObjectsAndKeys:
@"Couldn't create", @"Error",
destination, @"Path",
nil];
[delegate performSelector:@selector
(fileManager:shouldProceedAfterError:) withObject:self
withObject:errorDict];
ExtAudioFileDispose(outfile);
ExtAudioFileDispose(infile);
AudioFileClose(infileId);
return returnValue;
}
// deligate should return YES to continue or NO to quit
bytes = sizeof(srcBuffer);
if (![delegate performSelector:@selector(copiedBytes:toPath:)
withObject:[NSNumber numberWithUnsignedLongLong:bytes]
withObject:destination]) {
break;
}
}
// close
ExtAudioFileDispose(outfile);
ExtAudioFileDispose(infile);
AudioFileClose(infileId);
returnValue = YES;
return returnValue;
}
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Coreaudio-api mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden