最近准备做一个关于录音和播放的项目!查了一些资料,很简单的做了一个,下面我就分享一下iPhone的录音和播放的使用心得。
iPhone的录音和播放使用到了media层的内容,media层处于cocoa层之下,用到的很大一部分都是c语言的结构。
1、引入框架。
#import <AVFoundation/AVFoundation.h>
2、创建录音项。
- (void) prepareToRecord

{

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;

}

}


以上这个方法就是创建了录音项,其中包括录音的路径和一些音频属性,但只是准备录音还没有录,如果要录的话还要加入以下的方法:
-(void)startrecorder

{

[recorder record];

}

这样就在我们创建的路径下开始了录音。完成录音很简单:

- (void) stopRecording{

 

[recorder stop];

 

 

}

 

这里顺便提一下录音的代理方法:

 

- (void)audioRecorderDidFinishRecording:(AVAudioRecorder *) aRecorder successfully:(BOOL)flag

{

NSLog(@"recorder successfully");

UIAlertView *recorderSuccessful = [[UIAlertView alloc] initWithTitle:@"" message:@"录音成功"delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];

[recorderSuccessful show];

[recorderSuccessful release];

}

- (void)audioRecorderEncodeErrorDidOccur:(AVAudioRecorder *)arecorder error:(NSError *)error

{

btnRecorder.enabled = NO;

UIAlertView *recorderFailed = [[UIAlertView alloc] initWithTitle:@"" message:@"发生错误"delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];

[recorderFailed show];

[recorderFailed release];

}

以上两个代理方法分别指定了录音的成功或失败。

录音中有一个的录音对象有一个averagePowerForChannel和peakPowerForChannel的属性分别为声音的最高振幅和平均振幅,有了他们就可以做一个动态的振幅的录音效果。

- (void) updateAudioDisplay {

if (isStart == NO) {

currentTimeLabel.text = @"--:--";

} else {

double currentTime = recorder.currentTime;

currentTimeLabel.text = [NSString stringWithFormat: @"d:d",

(int) currentTime/60,

(int) currentTime%60];

//START:code.RecordViewController.setlevelmeters

[recorder updateMeters];

[leftLevelMeter setPower: [recorder averagePowerForChannel:0]

peak: [recorder peakPowerForChannel: 0]];

if (! rightLevelMeter.hidden) {

[rightLevelMeter setPower: [recorder averagePowerForChannel:1]

peak: [recorder peakPowerForChannel: 1]];

}

//END:code.RecordViewController.setlevelmeters

}

}

以上就是录音相关的内容。

 

下面说一下播放的方法:

 

void SystemSoundsDemoCompletionProc (

SystemSoundID  soundID,

void           *clientData)

{

AudioServicesDisposeSystemSoundID (soundID);

((AudioRecorderPlayerAppDelegate*)clientData).statusLabel.text = @"Stopped";

};

 

-(void)playAudio

{

//START:code.SystemSoundsDemo.SystemSoundsDemoViewController.createsystemsound

// create a system sound id for the selected row

SystemSoundID soundID;

 

OSStatus err = kAudioServicesNoError;

 

// special case: vibrate//震动

//soundID = kSystemSoundID_Vibrate; //<label id="code.SystemSoundsDemo.SystemSoundsDemoViewController.createsystemsound.vibratesystemsound"/>

// find corresponding CAF file

//NSString *cafName = [NSString stringWithFormat: @"%@",recorderFilePath]; //<label id="code.SystemSoundsDemo.SystemSoundsDemoViewController.createsystemsound.rowtonumberstring"/>

NSURL *url = [NSURL fileURLWithPath:recorderFilePath];

 

//NSString *cafPath = 

//[[NSBundle mainBundle] pathForResource:cafName ofType:@"caf"]; //<label id="code.SystemSoundsDemo.SystemSoundsDemoViewController.createsystemsound.findcafinbundle"/>

//NSURL *cafURL = [NSURL fileURLWithPath:url]; //<label id="code.SystemSoundsDemo.SystemSoundsDemoViewController.createsystemsound.fileurlwithpath"/>

err = AudioServicesCreateSystemSoundID((CFURLRef) url, &soundID); //<label id="code.SystemSoundsDemo.SystemSoundsDemoViewController.createsystemsound.createsystemsound"/>

//END:code.SystemSoundsDemo.SystemSoundsDemoViewController.createsystemsound

//START:code.SystemSoundsDemo.SystemSoundsDemoViewController.registercompletionprocandplaysound

if (err == kAudioServicesNoError) {

// set up callback for sound completion

err = AudioServicesAddSystemSoundCompletion //<label id="code.SystemSoundsDemo.SystemSoundsDemoViewController.createsystemsound.addcompletionproc"/>

(soundID,// sound to monitor

NULL,// run loop (NULL==main)

NULL,// run loop mode (NULL==default)

SystemSoundsDemoCompletionProc, // callback function //<label id="code.SystemSoundsDemo.SystemSoundsDemoViewController.createsystemsound.completionprocroutine"/>

self // data to provide on callback

); //<label id="code.SystemSoundsDemo.SystemSoundsDemoViewController.createsystemsound.addcompletionprocend"/>

statusLabel.text = @"Playing"; //<label id="code.SystemSoundsDemo.SystemSoundsDemoViewController.createsystemsound.setlabel"/>

AudioServicesPlaySystemSound (soundID); //<label id="code.SystemSoundsDemo.SystemSoundsDemoViewController.createsystemsound.playsound"/>

}

if (err != kAudioServicesNoError) { //<label id="code.SystemSoundsDemo.SystemSoundsDemoViewController.createsystemsound.errorblockstart"/>

CFErrorRef error = CFErrorCreate(NULL, kCFErrorDomainOSStatus, err, NULL); //<label id="code.SystemSoundsDemo.SystemSoundsDemoViewController.createsystemsound.createcferror"/>

NSString *errorDesc = (NSString*) CFErrorCopyDescription (error); //<label id="code.SystemSoundsDemo.SystemSoundsDemoViewController.createsystemsound.copycferrordescription"/>

UIAlertView *cantPlayAlert =

[[UIAlertView alloc] initWithTitle:@"Cannot Play:"

  message: errorDesc

  delegate:nil

cancelButtonTitle:@"OK"

otherButtonTitles:nil];

[cantPlayAlert show];

[cantPlayAlert release]; 

[errorDesc release]; //<label id="code.SystemSoundsDemo.SystemSoundsDemoViewController.createsystemsound.releaseerrordescription"/>

CFRelease (error); //<label id="code.SystemSoundsDemo.SystemSoundsDemoViewController.createsystemsound.releaseerror"/>

} //<label id="code.SystemSoundsDemo.SystemSoundsDemoViewController.createsystemsound.errorblockend"/>

//END:code.SystemSoundsDemo.SystemSoundsDemoViewController.registercompletionprocandplaysound

}

 


通过以上的方法就应该能够实现播放,播放的时候也是可以加入振幅过程的,大家可以试试!这样一个iPhone录音机就做好了!哈哈
posted on 2011-05-20 12:27  一个人的天空@  阅读(1733)  评论(0编辑  收藏  举报