1

I wanted to remove last 5 second audio data and save it to different location as new audio.I'm trying to get it done by following code using ExtAudioFile service but here my audio output size is increasing from 2.5 MB to 26.5 MB..where am i wrong.

UInt32 size;                                                                                                                                                                                           NSString *docsDir;
NSArray *dirPaths;
dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
docsDir = [dirPaths objectAtIndex:0];
NSString *destinationURL = [docsDir
                            stringByAppendingPathComponent:@"Audio3.m4a"];
NSURL * soundFilePath = [NSURL fileURLWithPath:[[NSBundle mainBundle]
                                                pathForResource:@"Audio1"
                                                ofType:@"m4a"]];
ExtAudioFileRef inputFile= NULL;
ExtAudioFileRef outputFile= NULL;
ExtAudioFileOpenURL((CFURLRef)soundFilePath, &inputFile);

AudioStreamBasicDescription destFormat;

destFormat.mFormatID = kAudioFormatMPEG4AAC;
destFormat.mFormatFlags = kAudioFormatFlagsCanonical;
destFormat.mSampleRate = 441000;
destFormat.mBytesPerPacket = 2;
destFormat.mFramesPerPacket = 1;
destFormat.mBytesPerFrame = 2;
destFormat.mChannelsPerFrame = 2;
destFormat.mBitsPerChannel = 16;    
destFormat.mReserved = 0;

OSStatus createStatus =ExtAudioFileCreateWithURL((CFURLRef)[NSURL fileURLWithPath:destinationURL],kAudioFileM4AType,&destFormat,NULL,kAudioFileFlags_EraseFile,&outputFile);
//ExtAudioFileDispose(outputFile);
NSLog(@"createStatus: %i", createStatus);
//this is not needed as file url is already opened. 


ExtAudioFileOpenURL((CFURLRef)soundFilePath, &inputFile);
//ExtAudioFileOpenURL((CFURLRef)[NSURL fileURLWithPath:destinationURL], &outputFile);   
//find out how many frames long this file is 

SInt64 length = 0;
UInt32 dataSize2 = (UInt32)sizeof(length);
ExtAudioFileGetProperty(inputFile, kExtAudioFileProperty_FileLengthFrames, &dataSize2, &length);

AudioStreamBasicDescription clientFormat;
clientFormat.mFormatID = kAudioFormatMPEG4AAC;
clientFormat.mSampleRate = 441000;
clientFormat.mFormatFlags = kAudioFormatFlagsCanonical;
clientFormat.mBitsPerChannel = 16;
clientFormat.mChannelsPerFrame = 2;
clientFormat.mFramesPerPacket = 1;
clientFormat.mBytesPerPacket = 2;
clientFormat.mBytesPerFrame = 2;
destFormat.mReserved = 0;

size = sizeof(clientFormat);

//set the intermediate format to canonical on the source file for conversion (?) 
ExtAudioFileSetProperty(inputFile, kExtAudioFileProperty_ClientDataFormat, size, &clientFormat);
ExtAudioFileSetProperty(outputFile, kExtAudioFileProperty_ClientDataFormat, size, &clientFormat);

OSStatus seekStatus = ExtAudioFileSeek(outputFile, 0);  
NSLog(@"seekstatus %i", seekStatus);

SInt64 newLength = length - (5); //shorten by 5 seconds worth of frames 

NSLog(@"length: %i frames", length);

UInt8 *buffer = malloc(64*1024); //64K 

UInt32 totalFramecount = 0;
while(true) {
    AudioBufferList bufferList;
    bufferList.mNumberBuffers = 1;
    bufferList.mBuffers[0].mNumberChannels = 2;
    bufferList.mBuffers[0].mData = buffer; //pointer to buffer of audio data 
    bufferList.mBuffers[0].mDataByteSize =64*1024; //number of bytes in the buffer 

    UInt32 frameCount = 64*1024 / 2; //2 bytes per frame        
    // Read a chunk of input 
    SInt64              outFrameOffset;
    ExtAudioFileTell(inputFile, &outFrameOffset)    ;
    NSLog(@"head status %i", outFrameOffset);
    OSStatus status = ExtAudioFileRead(inputFile, &frameCount, &bufferList);
    totalFramecount += frameCount;

    NSLog(@"read status %i", status);
    NSLog(@"loaded %i frames and stopping at %i", totalFramecount, newLength);

    if (!frameCount ||(totalFramecount >= newLength)) {
        //termination condition 
        break;
    }   
    OSStatus writeStatus = ExtAudioFileWrite(outputFile, frameCount, &bufferList);
    NSLog(@"ws: %i", writeStatus);
}   
free(buffer);

ExtAudioFileDispose(inputFile);
ExtAudioFileDispose(outputFile);
Katrawat
  • 41
  • 8

1 Answers1

3

You are taking compressed audio (M4A) and uncompressing it, which is what you need to do to trim down the audio content. If you want to get back to the 2.5 MB range, you will need to recompress your audio when done.

Keep in mind that repeated lossy uncompress-edit-recompress cycles will degrade the quality of your audio. If you are going to be performing a lot of audio edit operations, you should transform your audio from compressed to uncompressed, then run your transforms, and finally recompress at the end.

ObscureRobot
  • 7,306
  • 2
  • 27
  • 36
  • Thanks for your answer but now i am not able to play this newly saved audio file and also duration & bit rate are not shown in its info. how can i fix it? – Katrawat Oct 24 '11 at 09:43
  • 1
    Up-voting a useful answer as a show of thanks would probably increase the chance of getting a follow-up – P i Dec 10 '11 at 13:43
  • Give [Audacity](http://audacity.sourceforge.net/) a try for diving deeper into the audio files your code creates. Even though version 1.3 is in Beta, it is very stable and is significantly better than 1.2. – ObscureRobot Dec 24 '11 at 06:16
  • I couldn't find any answer for how to delete from an audio file, for example if I want to delete from second 3 till 10. can u check this question please: https://stackoverflow.com/questions/53928988/swift-how-to-delete-part-of-audio – mahdi Dec 26 '18 at 11:07