Prachi Rajput Prachi Rajput - 5 months ago 26
iOS Question

Convert recorded audio file in to .wav format in iOS

I want to record a audio file and upload to server in .wav format, but recorder doesn't allow to me to record a file into wav format.

for recording i have used the code :
NSMutableDictionary *recordSetting = [[NSMutableDictionary alloc] init];

[recordSetting setValue:[NSNumber numberWithInt:kAudioFormatMPEG4AAC] forKey:AVFormatIDKey];
[recordSetting setValue:[NSNumber numberWithFloat:44100.0] forKey:AVSampleRateKey];
[recordSetting setValue:[NSNumber numberWithInt: 2] forKey:AVNumberOfChannelsKey];

// Initiate and prepare the recorder
recorder = [[AVAudioRecorder alloc] initWithURL:outputFileURL settings:recordSetting error:nil];
recorder.delegate = self;
recorder.meteringEnabled = YES;
[recorder prepareToRecord];


Another way i have found, convert file from caff to wav after recording but this also not working for me.

I have used the code for convert file from caff to wav:

-(BOOL)exportAssetAsWaveFormat:(NSURL*)filePath
{
NSError *error = nil ;

NSDictionary *audioSetting = [NSDictionary dictionaryWithObjectsAndKeys:
[ NSNumber numberWithFloat:44100.0], AVSampleRateKey,
[ NSNumber numberWithInt:2], AVNumberOfChannelsKey,
[ NSNumber numberWithInt:16], AVLinearPCMBitDepthKey,
[ NSNumber numberWithInt:kAudioFormatLinearPCM], AVFormatIDKey,
[ NSNumber numberWithBool:NO], AVLinearPCMIsFloatKey,
[ NSNumber numberWithBool:0], AVLinearPCMIsBigEndianKey,
[ NSNumber numberWithBool:NO], AVLinearPCMIsNonInterleaved,
[ NSData data], AVChannelLayoutKey, nil ];

// NSString *audioFilePath = filePath;
AVURLAsset * URLAsset = [[AVURLAsset alloc] initWithURL:recorder.url options:nil];

if (!URLAsset) return NO ;

AVAssetReader *assetReader = [AVAssetReader assetReaderWithAsset:URLAsset error:&error];
if (error) return NO;

NSArray *tracks = [URLAsset tracksWithMediaType:AVMediaTypeAudio];
if (![tracks count]) return NO;

AVAssetReaderAudioMixOutput *audioMixOutput = [AVAssetReaderAudioMixOutput
assetReaderAudioMixOutputWithAudioTracks:tracks
audioSettings :audioSetting];

if (![assetReader canAddOutput:audioMixOutput]) return NO ;

[assetReader addOutput :audioMixOutput];

if (![assetReader startReading]) return NO;



NSString *title = @"WavConverted";
NSArray *docDirs = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docDir = [docDirs objectAtIndex: 0];
NSString *outPath = [[docDir stringByAppendingPathComponent :title]
stringByAppendingPathExtension:@"wav" ];

NSURL *outURL = [NSURL fileURLWithPath:outPath];
AVAssetWriter *assetWriter = [AVAssetWriter assetWriterWithURL:outURL
fileType:AVFileTypeWAVE
error:&error];
if (error) return NO;

AVAssetWriterInput *assetWriterInput = [ AVAssetWriterInput assetWriterInputWithMediaType :AVMediaTypeAudio
outputSettings:audioSetting];
assetWriterInput. expectsMediaDataInRealTime = NO;

if (![assetWriter canAddInput:assetWriterInput]) return NO ;

[assetWriter addInput :assetWriterInput];

if (![assetWriter startWriting]) return NO;




[assetWriter startSessionAtSourceTime:kCMTimeZero ];

dispatch_queue_t queue = dispatch_queue_create( "assetWriterQueue", NULL );

[assetWriterInput requestMediaDataWhenReadyOnQueue:queue usingBlock:^{

NSLog(@"start");

while (1)
{
if ([assetWriterInput isReadyForMoreMediaData]) {

CMSampleBufferRef sampleBuffer = [audioMixOutput copyNextSampleBuffer];

if (sampleBuffer) {
[assetWriterInput appendSampleBuffer :sampleBuffer];
CFRelease(sampleBuffer);
} else {
[assetWriterInput markAsFinished];
break;
}
}
}

[assetWriter finishWriting];


NSLog(@"finish %@",assetWriter);
}];
return YES;
// dispatch_release(queue);
}


Thanks in advance.

Any help would be really appreciated.

Answer

You are uploading the file to a server, but I recommend you to not use the wav format because it's bigger in size than any other formats. Use caf, m4a, or any other formats instead.

You can record a wav file by setting AVFormatIDKey to kAudioFormatLinearPCM; no other encoding format will work.

NSURL *url = [NSURL fileURLWithPath: outPath];
NSError *err = nil;
audioRecorder = [[ AVAudioRecorder alloc] initWithURL:url 
                                             settings: audioSetting 
                                                error:&err];

//prepare to record
[audioRecorder setDelegate:self];
[audioRecorder prepareToRecord];
audioRecorder.meteringEnabled = YES;
[audioRecorder recordForDuration:(NSTimeInterval)10000000000];
[audioRecorder record];