我很努力地將記錄的pcm/caf文件(通過AudioQueue錄製)轉換爲m4a文件。我應該可以通過「AudioConverter.h」以某種方式實現,但看起來並不容易。尋找一些示例代碼音頻轉換用iPhone caf => m4a
如果你看過一個例子或者有一個代碼片段,它會很棒,如果你可以發佈它。
感謝您的幫助
湯姆
我很努力地將記錄的pcm/caf文件(通過AudioQueue錄製)轉換爲m4a文件。我應該可以通過「AudioConverter.h」以某種方式實現,但看起來並不容易。尋找一些示例代碼音頻轉換用iPhone caf => m4a
如果你看過一個例子或者有一個代碼片段,它會很棒,如果你可以發佈它。
感謝您的幫助
湯姆
這裏從我在現實生活的生產代碼用於轉換音頻文件的代碼片段:
- (BOOL)convertWithDocument:(SoundDocumentCore*)document selection: (SoundSelection*)selection saveTo:(NSString*)path fileType:(UInt32)fileType progress:(ProgressSheet*)progress
{
OSStatus err;
ExtAudioFileRef eafRef;
UInt32 n;
UInt32 dataFormat = [self dataFormat];
SInt32 bitRate = [self bitRate];
// -- Data Source --
// Calculate offsets from selection, if any
UInt64 offset = 0, length = [document numFrames];
SInt32 trackOffset = 0, numTracks = [document numTracks];
if (selection != nil) {
trackOffset = [selection firstTrack];
numTracks = [selection numTracks];
offset = round ([selection startTime] * [document sampleRate]);
length = round ([selection duration] * [document sampleRate]);
}
// -- Extended Audio File --
NSString *parentPath = [path stringByDeletingLastPathComponent];
NSString *fileName = [self flipColonsAndSlashes:[path lastPathComponent]];
FSRef parentDir;
AudioStreamBasicDescription inputFormat, outputFormat;
// Create FSRef from path
err = FSPathMakeRef ((const UInt8*)[parentPath fileSystemRepresentation], &parentDir, nil);
if (err != noErr) {if (mVerbose) NSLog(@"-[AudioFile convertWithDocument:] FSPathMakeRef() error %d", err); return NO;}
// Delete the existing file
[[NSFileManager defaultManager] removeFileAtPath: path handler:nil];
// Set up the input and output data formats
inputFormat.mSampleRate = [document sampleRate];
inputFormat.mFormatID = kAudioFormatLinearPCM;
inputFormat.mFormatFlags = kLinearPCMFormatFlagIsFloat | kAudioFormatFlagsNativeEndian;
inputFormat.mBytesPerFrame = sizeof(float) * numTracks;
inputFormat.mFramesPerPacket = 1;
inputFormat.mBytesPerPacket = inputFormat.mBytesPerFrame * inputFormat.mFramesPerPacket;
inputFormat.mChannelsPerFrame = numTracks;
inputFormat.mBitsPerChannel = 32;
inputFormat.mReserved = 0;
[self getFileDataFormat: &outputFormat];
// Create an audio file and then wrap it with ExtAudioFile
AudioFileID audioFileID;
FSRef audioFileRef;
err = AudioFileCreate(&parentDir, (CFStringRef) fileName, fileType, &outputFormat, nil, &audioFileRef, &audioFileID);
if (err != noErr) {if (mVerbose) NSLog(@"-[AudioFile convertWithDocument:] AudioFileCreate() error %d", err); return NO;}
// Add user data
[self addUserDataToAudioFile:audioFileID];
// Wrap it in ExtAudioFile
err = ExtAudioFileWrapAudioFileID(audioFileID, YES, &eafRef);
if (err != noErr) {if (mVerbose) NSLog(@"-[AudioFile convertWithDocument:] ExtAudioFileWrapAudioFileID() error %d", err); return NO;}
//err = ExtAudioFileCreateNew (&parentDir, (CFStringRef) fileName, fileType, &outputFormat, nil, &eafRef);
//if (err != noErr) {if (mVerbose) NSLog(@"-[AudioFile convertWithDocument:] ExtAudioFileCreateNew() error %d", err); return NO;}
// Set the client data format
err = ExtAudioFileSetProperty (eafRef, kExtAudioFileProperty_ClientDataFormat, sizeof (AudioStreamBasicDescription), &inputFormat);
if (err != noErr) {if (mVerbose) NSLog(@"-[AudioFile convertWithDocument:] ExtAudioFileSetProperty() error %d", err); return NO;}
// -- AudioConverter Setup --
AudioConverterRef converter;
n = sizeof (converter);
err = ExtAudioFileGetProperty (eafRef, kExtAudioFileProperty_AudioConverter, &n, &converter);
if (err != noErr) {if (mVerbose) NSLog(@"-[AudioFile convertWithDocument:] ExtAudioFileGetProperty() error %d", err); return NO;}
// Set quality
UInt32 quality = kAudioCodecQuality_Max;
err = AudioConverterSetProperty(converter, kAudioConverterEncodeBitRate, sizeof (quality), &quality);
// Set bit rate
if ((bitRate != 0) && (dataFormat == kAudioFormatMPEG4AAC)) {
err = AudioConverterSetProperty(converter, kAudioConverterEncodeBitRate, sizeof (bitRate), &bitRate);
if (err != noErr) {if (mVerbose) NSLog(@"-[AudioFile convertWithDocument:] AudioConverterSetProperty() error %d", err);}
}
// Resynchronize ExtAudioFile with AudioConverter
n = 0;
err = ExtAudioFileSetProperty (eafRef, kExtAudioFileProperty_ConverterConfig, sizeof (n), &n);
if (err != noErr) {if (mVerbose) NSLog(@"-[AudioFile convertWithDocument:] ExtAudioFileSetProperty() error %d", err);}
// -- Write Data --
const UInt32 maxBufferSize = 256 * 1024L;
SInt64 remain = length;
UInt32 frameSize = inputFormat.mBytesPerFrame;
UInt32 maxNumFrames = maxBufferSize/frameSize;
NSMutableData *bufferListData = [NSMutableData dataWithLength: 16];
AudioBufferList *bufferList = [bufferListData mutableBytes];
NSData *bufferData;
NSAutoreleasePool *pool;
BOOL success = YES;
// Loop
while ((remain > 0) && (success == YES)) {
pool = [[NSAutoreleasePool alloc] init];
// Calculate number of frames to write
n = (remain < maxNumFrames)? remain : maxNumFrames;
// Get sample data from document
bufferData = [document interleavedDataAtOffset: offset numFrames: n firstTrack: trackOffset numTracks: numTracks];
// Set up audio buffer list
bufferList->mNumberBuffers = 1;
bufferList->mBuffers[0].mNumberChannels = numTracks;
bufferList->mBuffers[0].mDataByteSize = [bufferData length];
bufferList->mBuffers[0].mData = (void*) [bufferData bytes];
// Write data to disk
err = ExtAudioFileWrite (eafRef, n, bufferList);
if (err != noErr) {if (mVerbose) NSLog(@"-[AudioFile convertWithDocument:] ExtAudioFileWrite() error %d", err);}
[pool release];
// Update counters
offset += n;
remain -= n;
// Update progress window
[progress setMarkValue: [progress markValue] + n];
if ([progress isCancelled]) success = NO;
}
// -- Clean Up --
err = ExtAudioFileDispose (eafRef);
if (err != noErr) {if (mVerbose) NSLog(@"-[AudioFile convertWithDocument:] ExtAudioFileDispose() error %d", err);}
err = AudioFileClose (audioFileID);
if (err != noErr) {if (mVerbose) NSLog(@"-[AudioFile convertWithDocument:] AudioFileClose() error %d", err);}
return success;
}
你設置的「質量」和使用kAudioConverterEncodeBitRate的相同屬性值的「比特率」 - 這是不正確的,因爲編解碼器質量是使用kAudioConverterCodecQuality設置的。你不會注意到,如果這個返回錯誤是因爲你沒有檢查它,那麼你覆蓋了錯誤值。
我建議看一下ConvertFile蘋果示例,演示如何正確執行此操作並處理分層的AAC格式和啓動信息。
http://developer.apple.com/library/mac/#samplecode/ConvertFile/
Stackoverflow不是一個基於線程的論壇。這是以問答爲重點。這意味着如果你想對anser發表評論,你必須在評論中這樣做,而不是單獨回答。你的答案部分是對以前答案的評論,所以應該發表評論。因爲3年前您最後一次看到您,所以我會將您的答案複製到評論中。 – 2014-02-24 12:00:39
有附帶自由DiracLE時間http://dirac.dspdimension.com拉伸庫的示例代碼。我一直在我的代碼中使用他們的EAFWrite類,因爲它很好地包裝了整個AudioFile/ExtAudioFile API業務。
你能否提供一些工作代碼.. – Saurabh 2010-08-26 12:09:32
從哪裏我可以得到像SoundDocumentCore幾個類庫? – jfalexvijay 2011-01-26 05:14:58
嘿什麼「SoundDocumentCore」在上面的代碼? – Saurabh 2011-05-12 13:11:39