2009-08-20 5 views

Répondre

5

Voici un extrait de code de ce que j'utilise en temps réel le code de production en direct pour convertir des fichiers audio:

- (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; 
} 
+2

Pouvez-vous s'il vous plaît fournir un code de travail .. – Saurabh

+1

D'où je peux obtenir la bibliothèque avec quelques classes comme SoundDocumentCore? – jfalexvijay

+0

hey whats "SoundDocumentCore" dans ce code ci-dessus? – Saurabh

0

vous définissez la "qualité" et "bitrate" en utilisant la même valeur de propriété de kAudioConverterEncodeBitRate - ceci est incorrect car la qualité du codec est définie en utilisant kAudioConverterCodecQuality. Vous ne remarquerez pas si cela a retourné une erreur parce que vous ne la vérifiez pas, alors vous écrasez la valeur err.

Je suggère de regarder l'exemple de ConvertFile Apple qui montre comment faire ceci correctement et prend soin des formats AAC superposés et des informations d'amorçage.

http://developer.apple.com/library/mac/#samplecode/ConvertFile/

+0

Stackoverflow n'est pas un forum basé sur des threads. C'est axé sur la Q & A. Cela signifie que si vous voulez commenter une interview, vous devez le faire dans un commentaire, pas dans une réponse séparée. Des parties de votre réponse sont un commentaire sur une réponse précédente, il devrait donc entrer dans un commentaire. Parce que vous avez été vu pour la dernière fois sur SO 3 ans, je vais copier votre réponse dans un commentaire. –

0

Il est un exemple de code fourni avec le temps libre DiracLE bibliothèque d'étirement à http://dirac.dspdimension.com. J'utilise leur classe EAFWrite dans mon code tout le temps car elle enveloppe bien l'ensemble de l'API AudioFile/ExtAudioFile.

Questions connexes