Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Answered my own question: I had to pass this problem to my colleague and he got it to work! I never had the chance to analyze my original problem but I thought, I'd post it here for the sake of completeness. The following method is called from within an NSThread. Parameters are set via the 'threadDictionary' and he created a custom delegate to transmit progress feedback (sorry, SO doesn't understand the formatting properly, the following is supposed to be one block of method implementation):</p> <pre><code>- (void)encodeToAAC { RXAudioEncoderStatusType encoderStatus; OSStatus result = noErr; BOOL success = NO; BOOL cancelled = NO; UInt32 size; ExtAudioFileRef sourceAudioFile,destAudioFile; AudioStreamBasicDescription sourceFormat,outputFormat, clientFormat; SInt64 totalFrames; unsigned long long encodedBytes, totalBytes; int bufferSizeInFrames, bufferSize; UInt8 * buffer; AudioBufferList bufferList; NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; NSFileManager * fileManager = [[[NSFileManager alloc] init] autorelease]; NSMutableDictionary * threadDict = [[NSThread currentThread] threadDictionary]; NSObject&lt;RXAudioEncodingDelegate&gt; * delegate = (NSObject&lt;RXAudioEncodingDelegate&gt; *)[threadDict objectForKey:@"Delegate"]; NSString *sourcePath = (NSString *)[threadDict objectForKey:@"SourcePath"]; NSString *destPath = (NSString *)[threadDict objectForKey:@"DestinationPath"]; NSURL * sourceURL = [NSURL fileURLWithPath:sourcePath]; NSURL * destURL = [NSURL fileURLWithPath:destPath]; // Open a source audio file. result = ExtAudioFileOpenURL( (CFURLRef)sourceURL, &amp;sourceAudioFile ); if( result != noErr ) { DLog( @"Error in ExtAudioFileOpenURL: %ld", result ); goto bailout; } // Get the source data format size = sizeof( sourceFormat ); result = ExtAudioFileGetProperty( sourceAudioFile, kExtAudioFileProperty_FileDataFormat, &amp;size, &amp;sourceFormat ); if( result != noErr ) { DLog( @"Error in ExtAudioFileGetProperty: %ld", result ); goto bailout; } // Define the output format (AAC). memset(&amp;outputFormat, 0, sizeof(outputFormat)); outputFormat.mFormatID = kAudioFormatMPEG4AAC; outputFormat.mSampleRate = 44100; outputFormat.mFormatFlags = kMPEG4Object_AAC_Main; outputFormat.mChannelsPerFrame = 2; outputFormat.mBitsPerChannel = 0; outputFormat.mBytesPerFrame = 0; outputFormat.mBytesPerPacket = 0; outputFormat.mFramesPerPacket = 1024; // Use AudioFormat API to fill out the rest of the description. //size = sizeof( outputFormat ); //AudioFormatGetProperty( kAudioFormatProperty_FormatInfo, 0, NULL, &amp;size, &amp;outputFormat); // Make a destination audio file with this output format. result = ExtAudioFileCreateWithURL( (CFURLRef)destURL, kAudioFileM4AType, &amp;outputFormat, NULL, kAudioFileFlags_EraseFile, &amp;destAudioFile ); if( result != noErr ) { DLog( @"Error creating destination file: %ld", result ); goto bailout; } // Create the canonical PCM client format. memset(&amp;clientFormat, 0, sizeof(clientFormat)); clientFormat.mSampleRate = sourceFormat.mSampleRate; clientFormat.mFormatID = kAudioFormatLinearPCM; clientFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked; //kAudioFormatFlagIsPacked | kAudioFormatFlagIsSignedInteger; clientFormat.mChannelsPerFrame = 2; clientFormat.mBitsPerChannel = 16; clientFormat.mBytesPerFrame = 4; clientFormat.mBytesPerPacket = 4; clientFormat.mFramesPerPacket = 1; // Set the client format in source and destination file. size = sizeof( clientFormat ); result = ExtAudioFileSetProperty( sourceAudioFile, kExtAudioFileProperty_ClientDataFormat, size, &amp;clientFormat ); if( result != noErr ) { DLog( @"Error while setting client format in source file: %ld", result ); goto bailout; } size = sizeof( clientFormat ); result = ExtAudioFileSetProperty( destAudioFile, kExtAudioFileProperty_ClientDataFormat, size, &amp;clientFormat ); if( result != noErr ) { DLog( @"Error while setting client format in destination file: %ld", result ); goto bailout; } // Make a buffer bufferSizeInFrames = 8000; bufferSize = ( bufferSizeInFrames * sourceFormat.mBytesPerFrame ); buffer = (UInt8 *)malloc( bufferSize ); bufferList.mNumberBuffers = 1; bufferList.mBuffers[0].mNumberChannels = clientFormat.mChannelsPerFrame; bufferList.mBuffers[0].mData = buffer; bufferList.mBuffers[0].mDataByteSize = ( bufferSize ); // Obtain total number of audio frames to encode size = sizeof( totalFrames ); result = ExtAudioFileGetProperty( sourceAudioFile, kExtAudioFileProperty_FileLengthFrames, &amp;size, &amp;totalFrames ); if( result != noErr ) { DLog( @"Error in ExtAudioFileGetProperty, could not get kExtAudioFileProperty_FileLengthFrames from sourceFile: %ld", result ); goto bailout; } encodedBytes = 0; totalBytes = totalFrames * sourceFormat.mBytesPerFrame; [threadDict setValue:[NSValue value:&amp;totalBytes withObjCType:@encode(unsigned long long)] forKey:@"TotalBytes"]; if (delegate != nil) [self performSelectorOnMainThread:@selector(didStartEncoding) withObject:nil waitUntilDone:NO]; while( TRUE ) { // Try to fill the buffer to capacity. UInt32 framesRead = bufferSizeInFrames; result = ExtAudioFileRead( sourceAudioFile, &amp;framesRead, &amp;bufferList ); if( result != noErr ) { DLog( @"Error in ExtAudioFileRead: %ld", result ); success = NO; break; } // 0 frames read means EOF. if( framesRead == 0 ) { success = YES; break; } // Write. result = ExtAudioFileWrite( destAudioFile, framesRead, &amp;bufferList ); if( result != noErr ) { DLog( @"Error in ExtAudioFileWrite: %ld", result ); success = NO; break; } encodedBytes += framesRead * sourceFormat.mBytesPerFrame; if (delegate != nil) [self performSelectorOnMainThread:@selector(didEncodeBytes:) withObject:[NSValue value:&amp;encodedBytes withObjCType:@encode(unsigned long long)] waitUntilDone:NO]; if ([[NSThread currentThread] isCancelled]) { cancelled = YES; DLog( @"Encoding was cancelled." ); success = NO; break; } } free( buffer ); // Close the files. ExtAudioFileDispose( sourceAudioFile ); ExtAudioFileDispose( destAudioFile ); bailout: encoderStatus.result = result; [threadDict setValue:[NSValue value:&amp;encoderStatus withObjCType:@encode(RXAudioEncoderStatusType)] forKey:@"EncodingError"]; // Report to the delegate if one exists if (delegate != nil) if (success) [self performSelectorOnMainThread:@selector(didEncodeFile) withObject:nil waitUntilDone:YES]; else if (cancelled) [self performSelectorOnMainThread:@selector(encodingCancelled) withObject:nil waitUntilDone:YES]; else [self performSelectorOnMainThread:@selector(failedToEncodeFile) withObject:nil waitUntilDone:YES]; // Clear the partially encoded file if encoding failed or is cancelled midway if ((cancelled || !success) &amp;&amp; [fileManager fileExistsAtPath:destPath]) [fileManager removeItemAtURL:destURL error:NULL]; [threadDict setValue:[NSNumber numberWithBool:NO] forKey:@"isEncoding"]; [pool release]; } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload