Objective C: OpenAL changing Pitch issue - objective-c

im having a hard time on OpenAL framework... i just want to change the pitch in playback action... what code is missing in my project.. im new in objective c,iOS development. hoping for your kind consideration, thanks in advance.. here is my code for the three button (RECORD,STOP,Play)..
-(void)startRecording:(UIButton *)sender
{ //for recording
recStopBtn.hidden = NO;
recStopBtn.enabled =YES;
playRecBtn.enabled = NO;
loading.hidden = NO;
[loading startAnimating];
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
NSError *err = nil;
[audioSession setCategory :AVAudioSessionCategoryPlayAndRecord error:&err];
if(err)
{
NSLog(#"audioSession: %# %d %#", [err domain], [err code], [[err userInfo] description]);
return;
}
[audioSession setActive:YES error:&err];
err = nil;
if(err)
{
NSLog(#"audioSession: %# %d %#", [err domain], [err code], [[err userInfo] description]);
return;
}
recordSetting = [[NSMutableDictionary alloc] init];
// We can use kAudioFormatAppleIMA4 (4:1 compression) or kAudioFormatLinearPCM for nocompression
[recordSetting setValue :[NSNumber numberWithInt:kAudioFormatAppleIMA4] forKey:AVFormatIDKey];
// We can use 44100, 32000, 24000, 16000 or 12000 depending on sound quality
[recordSetting setValue:[NSNumber numberWithFloat:16000.0] forKey:AVSampleRateKey];
// We can use 2(if using additional h/w) or 1 (iPhone only has one microphone)
[recordSetting setValue:[NSNumber numberWithInt: 1] forKey:AVNumberOfChannelsKey];
// These settings are used if we are using kAudioFormatLinearPCM format
//[recordSetting setValue :[NSNumber numberWithInt:16] forKey:AVLinearPCMBitDepthKey];
//[recordSetting setValue :[NSNumber numberWithBool:NO] forKey:AVLinearPCMIsBigEndianKey];
//[recordSetting setValue :[NSNumber numberWithBool:NO] forKey:AVLinearPCMIsFloatKey];
recorderFilePath = [NSString stringWithFormat:#"%#/MySound.caf", DOCUMENTS_FOLDER];
NSLog(#"recorderFilePath: %#",recorderFilePath);
NSURL *url = [NSURL fileURLWithPath:recorderFilePath];
err = nil;
NSData *audioData = [NSData dataWithContentsOfFile:[url path] options: 0 error:&err];
if(audioData)
{
NSFileManager *fm = [NSFileManager defaultManager];
[fm removeItemAtPath:[url path] error:&err];
}
err = nil;
recorder = [[ AVAudioRecorder alloc] initWithURL:url settings:recordSetting error:&err];
if(!recorder){
NSLog(#"recorder: %# %d %#", [err domain], [err code], [[err userInfo] description]);
UIAlertView *alert =
[[UIAlertView alloc] initWithTitle: #"Warning"
message: [err localizedDescription]
delegate: nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
return;
}
//prepare to record
[recorder setDelegate:self];
[recorder prepareToRecord];
recorder.meteringEnabled = YES;
BOOL audioHWAvailable = audioSession.inputIsAvailable;
if (! audioHWAvailable) {
UIAlertView *cantRecordAlert =
[[UIAlertView alloc] initWithTitle: #"Warning"
message: #"Audio input hardware not available"
delegate: nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[cantRecordAlert show];
return;
}
// start recording
[recorder record];
lblStatusMsg.text = #"Recording...";
//recIcon.image = [UIImage imageNamed:#"rec_icon.png"];
//progressView.progress = 0.0;
//timer = [NSTimer scheduledTimerWithTimeInterval:6.0 target:self selector:#selector(handleTimer) userInfo:nil repeats:YES];
}
-(void)stopRecord:(UIButton *)sender
{
loading.hidden = YES;
[loading stopAnimating];
recStartBtn.enabled = YES;
recStartBtn.hidden = NO;
playRecBtn.hidden = NO;
playRecBtn.enabled = YES;
recStopBtn.enabled = NO;
recStopBtn.hidden = YES;
[recorder stop];
[timer invalidate];
lblStatusMsg.text = #"Stopped";
// recIcon.image = [UIImage imageNamed:#"rec_icon2.png"];
}
-(void)playRecord:(UIButton *)sender
{
recorderFilePath = [NSString stringWithFormat:#"%#/MySound.caf", DOCUMENTS_FOLDER];
NSURL *urlRecord = [NSURL fileURLWithPath:recorderFilePath isDirectory:NO];
NSError *errorRecord;
soundRecord = [[AVAudioPlayer alloc] initWithContentsOfURL:urlRecord error:&errorRecord];
[soundRecord play];
}
-(void)changePitch:(UIButton *)sender
{
alSourcef(recorderFilePath, AL_PITCH, 1.2f);//this kinda troubles me,the source. =(
[soundRecord play];//this one also...
}

The first argument of the alSourcef method isn't an NSString file path, it's an ALuint representing an audio source.
See the example oalTouch (specifically the oalPlayback class) for how to set up an OpenAL source from a URL.

Related

can't able to save recorded audio iOS?

I Want to save the recorded audio in local documents directory
After that i want to play the Saved audio file
Audiofile is not created in documents directory?
I've tried with the following code What I am doing wrong??
NSString *temp1=[NSString stringWithFormat:#"%#.m4a",temp];
NSLog(#"=====>>%#",temp1);
NSArray *pathComponents=[NSArray arrayWithObjects:[NSSearchPathForDirectoriesInDomains(NSDocumentationDirectory, NSUserDomainMask, YES)lastObject],temp1, nil];
NSURL *outputFileURL=[NSURL fileURLWithPathComponents:pathComponents];
if (isRecording==NO) {
isRecording=YES;
NSLog(#"recording started");
session = [AVAudioSession sharedInstance];
[session setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
// Define the recorder setting
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:NULL];
recorder.delegate = self;
recorder.meteringEnabled = YES;
[recorder prepareToRecord];
[session setActive:YES error:nil];
// Start recording
[recorder record];
}
else
{
NSLog(#"recording stopped");
[recorder stop];
NSData *audioData=[NSData dataWithContentsOfURL:outputFileURL];
[audioData writeToURL:outputFileURL atomically:YES];
player = [[AVAudioPlayer alloc] initWithContentsOfURL:outputFileURL error:nil];
[player prepareToPlay];
[player play];
[player setVolume:1.0];
isRecording=NO;
}
Try this code
-(IBAction)btnS1AudioPressed:(id)sender
{
audioSession = [AVAudioSession sharedInstance];
NSError *err = nil;
[audioSession setCategory :AVAudioSessionCategoryPlayAndRecord error:&err];
if(err)
{
NSLog(#"audioSession: %# %d %#", [err domain], [err code], [[err userInfo] description]);
return;
}
[audioSession setActive:YES error:&err];
err = nil;
if(err)
{
NSLog(#"audioSession: %# %d %#", [err domain], [err code], [[err userInfo] description]);
return;
}
NSMutableDictionary *recordSetting = [[NSMutableDictionary alloc] init];
[recordSetting setValue :[NSNumber numberWithInt:kAudioFormatLinearPCM] forKey:AVFormatIDKey];
[recordSetting setValue:[NSNumber numberWithFloat:44100.0] forKey:AVSampleRateKey];
[recordSetting setValue:[NSNumber numberWithInt: 2] forKey:AVNumberOfChannelsKey];
[recordSetting setValue :[NSNumber numberWithInt:16] forKey:AVLinearPCMBitDepthKey];
[recordSetting setValue :[NSNumber numberWithBool:NO] forKey:AVLinearPCMIsBigEndianKey];
[recordSetting setValue :[NSNumber numberWithBool:NO] forKey:AVLinearPCMIsFloatKey];
NSString *AudioName=[NSString stringWithFormat:#"TestAudio.caf"];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
audioPath = [documentsDirectory stringByAppendingPathComponent:AudioName];
NSURL *url = [NSURL fileURLWithPath:audioPath];
err = nil;
NSData *audioData = [NSData dataWithContentsOfFile:[url path] options: 0 error:&err];
if(audioData)
{
NSFileManager *fm = [NSFileManager defaultManager];
[fm removeItemAtPath:[url path] error:&err];
}
recorder = [[ AVAudioRecorder alloc] initWithURL:url settings:recordSetting error:&err];
if(!recorder)
{
NSLog(#"recorder: %# %d %#", [err domain], [err code], [[err userInfo] description]);
UIAlertView *alert =
[[UIAlertView alloc] initWithTitle: #"Warning"
message: [err localizedDescription]
delegate: nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
return;
}
[recorder setDelegate:self];
[recorder prepareToRecord];
recorder.meteringEnabled = YES;
BOOL audioHWAvailable = audioSession.inputIsAvailable;
if (! audioHWAvailable)
{
UIAlertView *cantRecordAlert =
[[UIAlertView alloc] initWithTitle: #"Warning"
message: #"Audio input hardware not available"
delegate: nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[cantRecordAlert show];
return;
}
[recorder recordForDuration:(NSTimeInterval) 10000];
}
- (IBAction) stopRecording:(id)sender
{
[recorder stop];
}
I've found the mistake I made
NSArray *pathComponents=[NSArray arrayWithObjects:[NSSearchPathForDirectoriesInDomains(NSDocumentationDirectory, NSUserDomainMask, YES)lastObject],temp1, nil];
In the above code I used NSDocumentationDirectory instead of NSDocumentsDirectory

Parsing Json to handle and direct a user to view controller. Objective C

I have a Login screen and I POST username and password to a login page.
The webservice gives me 2 responses if the Login user details are correct I get a response of back from the request.
{"value":1}
and if the user details are wrong I get back from request.
{"value":0}
I have been able to parse that JSON Result to give me a log output of
value: 1 or value:0
I am battling to handle the parsed json e.g
//parse out the json data
NSDictionary* json = [NSJSONSerialization JSONObjectWithData:urlData //1
options:kNilOptions
error:&error];
NSArray* defineJsonData = [json objectForKey:#"value"]; //2
NSLog(#"value: %#", defineJsonData); //3
if ([[json objectForKey:#"value"] isEqualToNumber:[NSNumber numberWithInt:1]])
{
HUD.customView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"37x-Checkmark.png"]];
HUD.mode = MBProgressHUDModeCustomView;
[HUD hide:YES afterDelay:0];
[self performSegueWithIdentifier: #"introScreenView" sender:self];
}
else {
HUD.customView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"37x-Checkmark.png"]];
HUD.mode = MBProgressHUDModeCustomView;
[HUD hide:YES afterDelay:0];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Wrong Credentials" message:#"Please try to login again" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alert show];
}
Here is the rest of my code.
- (void)myTask {
if ([userNameTextField.text isEqualToString:#""] || [passwordTextField.text isEqualToString:#""]) {
HUD.customView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"37x-Checkmark.png"]];
HUD.mode = MBProgressHUDModeCustomView;
[HUD hide:YES afterDelay:0];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Feilds Missing" message:#"Please Fill all the field" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alert show];
return;
}
NSString *data = [NSString stringWithFormat:#"UserName=%#&Password=%#",userNameTextField.text, passwordTextField.text];
NSData *postData = [data dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:#"%d", [postData length]];
// preaparing URL request to send data.
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init] ;
NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:request delegate:self];
NSString *url = [NSString stringWithFormat:#"http://www.ddproam.co.za/Central/Account/LogOnIOS?"];
[request setURL:[NSURL URLWithString:url]];
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setHTTPBody:postData];
[request setTimeoutInterval:7.0];
NSURLResponse *response;
NSError *error;
NSData *urlData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
NSString *str=[[NSString alloc]initWithData:urlData encoding:NSUTF8StringEncoding];
NSLog(#"Login response:%#",str);
NSHTTPCookie *cookie;
NSLog(#"name: '%#'\n", [cookie name]);
for (NSHTTPCookie *cookie in [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies])
{
NSLog(#"name: '%#'\n", [cookie name]);
NSLog(#"value: '%#'\n", [cookie value]);
NSLog(#"domain: '%#'\n", [cookie domain]);
NSLog(#"path: '%#'\n", [cookie path]);
}
//parse out the json data
NSDictionary* json = [NSJSONSerialization JSONObjectWithData:urlData //1
options:kNilOptions
error:&error];
NSArray* defineJsonData = [json objectForKey:#"value"]; //2
NSLog(#"value: %#", defineJsonData); //3
if ([defineJsonData isEqual:0])
{
HUD.customView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"37x-Checkmark.png"]];
HUD.mode = MBProgressHUDModeCustomView;
[HUD hide:YES afterDelay:0];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Wrong Credentials" message:#"Please try to login again" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alert show];
}
else {
HUD.customView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"37x-Checkmark.png"]];
HUD.mode = MBProgressHUDModeCustomView;
[HUD hide:YES afterDelay:0];
[self performSegueWithIdentifier: #"introScreenView" sender:self];
}
if (theConnection) {
}
}
If response from the server is really just {"value":1}, then you correctly parse JSON to dictionary using NSJSONSerialization.
However under value key, there is an instance of NSNumber, not NSArray.
Your code to retrieve value and check it should look like this:
NSNumber *defineJsonData = [json objectForKey:#"value"];
NSLog(#"value: %#", defineJsonData);
if ([defineJsonData integerValue] == 0) {
NSLog(#"Wrong credentials");
}
else {
NSLog(#"Welcome :-)");
}

Sending record audio POST

I record audio with AVAudioRecorder:
audioRecorder = nil;
//Initialize audio session
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryRecord error:nil];
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
//Override record to mix with other app audio, background audio not silenced on record
OSStatus propertySetError = 0;
UInt32 allowMixing = true;
propertySetError = AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryMixWithOthers, sizeof(allowMixing), &allowMixing);
UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker;
AudioSessionSetProperty (kAudioSessionProperty_OverrideAudioRoute,sizeof (audioRouteOverride),&audioRouteOverride);
NSLog(#"Mixing: %lx", propertySetError); // This should be 0 or there was an issue somewhere
[[AVAudioSession sharedInstance] setActive:YES error:nil];
NSMutableDictionary *recordSetting = [[NSMutableDictionary alloc] initWithCapacity:0];
if (recordEncoding == ENC_PCM) {
[recordSetting setValue:[NSNumber numberWithInt:kAudioFormatLinearPCM] forKey:AVFormatIDKey];
[recordSetting setValue:[NSNumber numberWithFloat:44100.0] forKey:AVSampleRateKey];
[recordSetting setValue:[NSNumber numberWithInt:2] forKey:AVNumberOfChannelsKey];
[recordSetting setValue:[NSNumber numberWithInt:16] forKey:AVLinearPCMBitDepthKey];
[recordSetting setValue:[NSNumber numberWithBool:NO] forKey:AVLinearPCMIsBigEndianKey];
[recordSetting setValue:[NSNumber numberWithBool:NO] forKey:AVLinearPCMIsFloatKey];
} else {
NSNumber *formatObject;
switch (recordEncoding) {
case ENC_AAC:
formatObject = [NSNumber numberWithInt:kAudioFormatMPEG4AAC];
break;
case ENC_ALAC:
formatObject = [NSNumber numberWithInt:kAudioFormatAppleLossless];
break;
case ENC_IMA4:
formatObject = [NSNumber numberWithInt:kAudioFormatAppleIMA4];
break;
case ENC_ILBC:
formatObject = [NSNumber numberWithInt:kAudioFormatiLBC];
break;
case ENC_ULAW:
formatObject = [NSNumber numberWithInt:kAudioFormatULaw];
break;
default:
formatObject = [NSNumber numberWithInt:kAudioFormatAppleIMA4];
break;
}
[recordSetting setValue:formatObject forKey:AVFormatIDKey];
[recordSetting setValue:[NSNumber numberWithFloat:44100.0] forKey:AVSampleRateKey];
[recordSetting setValue:[NSNumber numberWithInt:2] forKey:AVNumberOfChannelsKey];
[recordSetting setValue:[NSNumber numberWithInt:12800] forKey:AVEncoderBitRateKey];
[recordSetting setValue:[NSNumber numberWithInt:16] forKey:AVLinearPCMBitDepthKey];
[recordSetting setValue:[NSNumber numberWithInt:AVAudioQualityHigh] forKey:AVEncoderAudioQualityKey];
}
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *recDir = [paths objectAtIndex:0];
NSURL *url = [NSURL fileURLWithPath:[NSString stringWithFormat:#"%#/recordTest.caf", recDir]];
NSError *error = nil;
audioRecorder = [[ AVAudioRecorder alloc] initWithURL:url settings:recordSetting error:&error];
if (!audioRecorder) {
NSLog(#"audioRecorder: %# %d %#", [error domain], [error code], [[error userInfo] description]);
return;
}
// audioRecorder.meteringEnabled = YES;
//
BOOL audioHWAvailable = audioSession.inputAvailable;
if (! audioHWAvailable) {
UIAlertView *cantRecordAlert =
[[UIAlertView alloc] initWithTitle: #"Warning"
message: #"Audio input hardware not available"
delegate: nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[cantRecordAlert show];
return;
}
if ([audioRecorder prepareToRecord]) {
[audioRecorder record];
NSLog(#"recording");
} else {
// int errorCode = CFSwapInt32HostToBig ([error code]);
// NSLog(#"Error: %# [%4.4s])" , [error localizedDescription], (char*)&errorCode);
NSLog(#"recorder: %# %d %#", [error domain], [error code], [[error userInfo] description]);
}
And I want to send it in POST header. How can i do it correctly? I'm guessing that i should have NSData and then convert it into NSString. Am i right? If true how can I convert AVAudioRecorder output to NSData?
Here is a sample application I done for understanding the audio file uploading.
You can use the following method to send the recorded audio using POST:
- (IBAction) pushLoader
{
NSURL *pathURL = urlOfAudioFile; //File Url of the recorded audio
NSData *voiceData = [[NSData alloc]initWithContentsOfURL:pathURL];
NSString *urlString = #"http://iroboticshowoff.com/img2/upload.php"; // You can give your url here for uploading
NSMutableURLRequest *request = [[[NSMutableURLRequest alloc]init]autorelease];
#try
{
[request setURL:[NSURL URLWithString:urlString]];
[request setHTTPMethod:#"POST"];
NSString *boundary = [NSString stringWithString:#"---------------------------14737809831466499882746641449"];
NSString *contentType = [NSString stringWithFormat:#"multipart/form-data; boundary=%#",boundary];
[request addValue:contentType forHTTPHeaderField:#"Content-Type"];
NSMutableData *body = [NSMutableData data];
[body appendData:[[NSString stringWithFormat:#"\r\n--%#\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithString:#"Content-Disposition: form-data; name=\"userfile\"; filename=\".caf\"\r\n"]dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithString:#"Content-Type: application/octet-stream\r\n\r\n"]dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[NSData dataWithData:voiceData]];
[body appendData:[[NSString stringWithFormat:#"\r\n--%#--\r\n",boundary]dataUsingEncoding:NSUTF8StringEncoding]];
[request setHTTPBody:body];
NSError *error = nil;
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:&error];
NSString *returnString = [[NSString alloc]initWithData:returnData encoding:NSUTF8StringEncoding];
UIAlertView *alert = nil;
if(error)
{
alert = [[UIAlertView alloc]initWithTitle:#"Message" message:#"Error in Uploading the File" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
}
else
{
NSLog(#"Success %#",returnString);
alert = [[UIAlertView alloc]initWithTitle:#"Message" message:#"File get uploaded" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
}
[alert show];
[alert release];
alert = nil;
[returnString release];
returnString = nil;
boundary = nil;
contentType = nil;
body = nil;
}
#catch (NSException * exception)
{
NSLog(#"pushLoader in ViewController :Caught %# : %#",[exception name],[exception reason]);
}
#finally
{
[voiceData release];
voiceData = nil;
pathURL = nil;
urlString = nil;
}
}

AVAssetReader/Writer only working on certain devices?

I was using this tutorial to get a song from the music library to my specified directory. It works fine for me, but other people are reporting that the song never gets there. At first I thought there were device limitations, but it seems like people with the same device as me are having the problem. It is sort of annoying because I can't recreate their problem.
Here is my code:
{
NSURL *assetURL = [song valueForProperty:MPMediaItemPropertyAssetURL];
AVURLAsset *songAsset = [AVURLAsset URLAssetWithURL:assetURL options:nil];
NSError *assetError = nil;
AVAssetReader *assetReader = [[AVAssetReader assetReaderWithAsset:songAsset
error:&assetError]
retain];
if (assetError) {
NSLog (#"error: %#", assetError);
return;
}
AVAssetReaderOutput *assetReaderOutput = [[AVAssetReaderAudioMixOutput
assetReaderAudioMixOutputWithAudioTracks:songAsset.tracks
audioSettings: nil]
retain];
if (! [assetReader canAddOutput: assetReaderOutput]) {
NSLog (#"can't add reader output... die!");
return;
}
[assetReader addOutput: assetReaderOutput];
NSString *exportPath = #"Library/PreferenceBundles/MyAlarmSettings.bundle/export.m4a";
if ([[NSFileManager defaultManager] fileExistsAtPath:exportPath]) {
[[NSFileManager defaultManager] removeItemAtPath:exportPath error:nil];
}
NSURL *exportURL = [NSURL fileURLWithPath:exportPath];
AVAssetWriter *assetWriter = [[AVAssetWriter assetWriterWithURL:exportURL
fileType:AVFileTypeAppleM4A
error:&assetError]
retain];
if (assetError) {
NSLog (#"error: %#", assetError);
return;
}
AudioChannelLayout channelLayout;
memset(&channelLayout, 0, sizeof(AudioChannelLayout));
channelLayout.mChannelLayoutTag = kAudioChannelLayoutTag_Stereo;
NSDictionary *outputSettings = [NSDictionary dictionaryWithObjectsAndKeys:
[ NSNumber numberWithInt: kAudioFormatMPEG4AAC], AVFormatIDKey,
[ NSNumber numberWithInt: 2 ], AVNumberOfChannelsKey,
[ NSNumber numberWithFloat: 44100.0 ], AVSampleRateKey,
[ NSData dataWithBytes:&channelLayout length: sizeof( AudioChannelLayout ) ], AVChannelLayoutKey,
[ NSNumber numberWithInt: 320000 ], AVEncoderBitRateKey,
nil];
AVAssetWriterInput *assetWriterInput = [[AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeAudio
outputSettings:outputSettings]
retain];
if ([assetWriter canAddInput:assetWriterInput]) {
[assetWriter addInput:assetWriterInput];
} else {
NSLog (#"can't add asset writer input... die!");
return;
}
assetWriterInput.expectsMediaDataInRealTime = NO;
[assetWriter startWriting];
[assetReader startReading];
AVAssetTrack *soundTrack = [songAsset.tracks objectAtIndex:0];
CMTime startTime = CMTimeMake (0, soundTrack.naturalTimeScale);
[assetWriter startSessionAtSourceTime: startTime];
__block UInt64 convertedByteCount = 0;
dispatch_queue_t mediaInputQueue = dispatch_queue_create("mediaInputQueue", NULL);
[assetWriterInput requestMediaDataWhenReadyOnQueue:mediaInputQueue
usingBlock: ^
{
// NSLog (#"top of block");
while (assetWriterInput.readyForMoreMediaData) {
CMSampleBufferRef nextBuffer = [assetReaderOutput copyNextSampleBuffer];
if (nextBuffer) {
// append buffer
[assetWriterInput appendSampleBuffer: nextBuffer];
// NSLog (#"appended a buffer (%d bytes)",
// CMSampleBufferGetTotalSampleSize (nextBuffer));
convertedByteCount += CMSampleBufferGetTotalSampleSize (nextBuffer);
// oops, no
// sizeLabel.text = [NSString stringWithFormat: #"%ld bytes converted", convertedByteCount];
NSNumber *convertedByteCountNumber = [NSNumber numberWithLong:convertedByteCount];
[self performSelectorOnMainThread:#selector(updateSizeLabel:)
withObject:convertedByteCountNumber
waitUntilDone:NO];
} else {
// done!
NSString *songtitle = [[NSString alloc]initWithFormat:#"Alarm sound set to '%#' \n \n Press OK to respring. ",[song valueForProperty:MPMediaItemPropertyTitle]];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Done!" message:songtitle delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
[alert release];
[assetWriterInput markAsFinished];
[assetWriter finishWriting];
[assetReader cancelReading];
NSDictionary *outputFileAttributes = [[NSFileManager defaultManager]
attributesOfItemAtPath:exportPath
error:nil];
NSLog (#"done. file size is %llu",
[outputFileAttributes fileSize]);
NSNumber *doneFileSize = [NSNumber numberWithLong:[outputFileAttributes fileSize]];
[self performSelectorOnMainThread:#selector(updateCompletedSizeLabel:)
withObject:doneFileSize
waitUntilDone:NO];
// release a lot of stuff
[assetReader release];
[assetReaderOutput release];
[assetWriter release];
[assetWriterInput release];
[exportPath release];
break;
}
}
}];
NSLog (#"bottom of convertTapped:");
}
If you are accessing mediaItems from the users iPod library they maybe in the cloud. Use
[self.mediaItem valueForProperty:MPMediaItemPropertyIsCloudItem]
as far as I know you can not access these assets or force them to stream

How to record voice with an iPad?

I need a good example or guidelines for recording voice on an iPad. Whatever I say, I want to be able to play back later. How can I do this?
Actually, there are no examples at all. Here is my working code. Recording is triggered by the user pressing a button on the navBar. The recording uses cd quality (44100 samples), stereo (2 channels) linear pcm. Beware: if you want to use a different format, especially an encoded one, make sure you fully understand how to set the AVAudioRecorder settings (read carefully the audio types documentation), otherwise you will never be able to initialize it correctly. One more thing. In the code, I am not showing how to handle metering data, but you can figure it out easily. Finally, note that the AVAudioRecorder method deleteRecording as of this writing crashes your application. This is why I am removing the recorded file through the File Manager. When recording is done, I save the recorded audio as NSData in the currently edited object using KVC.
#define DOCUMENTS_FOLDER [NSHomeDirectory() stringByAppendingPathComponent:#"Documents"]
- (void) startRecording{
UIBarButtonItem *stopButton = [[UIBarButtonItem alloc] initWithTitle:#"Stop" style:UIBarButtonItemStyleBordered target:self action:#selector(stopRecording)];
self.navigationItem.rightBarButtonItem = stopButton;
[stopButton release];
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
NSError *err = nil;
[audioSession setCategory :AVAudioSessionCategoryPlayAndRecord error:&err];
if(err){
NSLog(#"audioSession: %# %d %#", [err domain], [err code], [[err userInfo] description]);
return;
}
[audioSession setActive:YES error:&err];
err = nil;
if(err){
NSLog(#"audioSession: %# %d %#", [err domain], [err code], [[err userInfo] description]);
return;
}
recordSetting = [[NSMutableDictionary alloc] init];
[recordSetting setValue :[NSNumber numberWithInt:kAudioFormatLinearPCM] forKey:AVFormatIDKey];
[recordSetting setValue:[NSNumber numberWithFloat:44100.0] forKey:AVSampleRateKey];
[recordSetting setValue:[NSNumber numberWithInt: 2] forKey:AVNumberOfChannelsKey];
[recordSetting setValue :[NSNumber numberWithInt:16] forKey:AVLinearPCMBitDepthKey];
[recordSetting setValue :[NSNumber numberWithBool:NO] forKey:AVLinearPCMIsBigEndianKey];
[recordSetting setValue :[NSNumber numberWithBool:NO] forKey:AVLinearPCMIsFloatKey];
// Create a new dated file
NSDate *now = [NSDate dateWithTimeIntervalSinceNow:0];
NSString *caldate = [now description];
recorderFilePath = [[NSString stringWithFormat:#"%#/%#.caf", DOCUMENTS_FOLDER, caldate] retain];
NSURL *url = [NSURL fileURLWithPath:recorderFilePath];
err = nil;
recorder = [[ AVAudioRecorder alloc] initWithURL:url settings:recordSetting error:&err];
if(!recorder){
NSLog(#"recorder: %# %d %#", [err domain], [err code], [[err userInfo] description]);
UIAlertView *alert =
[[UIAlertView alloc] initWithTitle: #"Warning"
message: [err localizedDescription]
delegate: nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
[alert release];
return;
}
//prepare to record
[recorder setDelegate:self];
[recorder prepareToRecord];
recorder.meteringEnabled = YES;
BOOL audioHWAvailable = audioSession.inputIsAvailable;
if (! audioHWAvailable) {
UIAlertView *cantRecordAlert =
[[UIAlertView alloc] initWithTitle: #"Warning"
message: #"Audio input hardware not available"
delegate: nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[cantRecordAlert show];
[cantRecordAlert release];
return;
}
// start recording
[recorder recordForDuration:(NSTimeInterval) 10];
}
- (void) stopRecording{
[recorder stop];
NSURL *url = [NSURL fileURLWithPath: recorderFilePath];
NSError *err = nil;
NSData *audioData = [NSData dataWithContentsOfFile:[url path] options: 0 error:&err];
if(!audioData)
NSLog(#"audio data: %# %d %#", [err domain], [err code], [[err userInfo] description]);
[editedObject setValue:[NSData dataWithContentsOfURL:url] forKey:editedFieldKey];
//[recorder deleteRecording];
NSFileManager *fm = [NSFileManager defaultManager];
err = nil;
[fm removeItemAtPath:[url path] error:&err];
if(err)
NSLog(#"File Manager: %# %d %#", [err domain], [err code], [[err userInfo] description]);
UIBarButtonItem *startButton = [[UIBarButtonItem alloc] initWithTitle:#"Record" style:UIBarButtonItemStyleBordered target:self action:#selector(startRecording)];
self.navigationItem.rightBarButtonItem = startButton;
[startButton release];
}
- (void)audioRecorderDidFinishRecording:(AVAudioRecorder *) aRecorder successfully:(BOOL)flag
{
NSLog (#"audioRecorderDidFinishRecording:successfully:");
// your actions here
}
from this answer - How do I record audio on iPhone with AVAudioRecorder?