2013年2月10日日曜日

iOS 音声録音(AVAudioRecorder)


・iOS, Mac でのオーディオ録音のためのObjective-C インタフェースを提供するAVAudioRecorderの使い方(Mac OS Xでも同じです)

※Mac OS Xの場合, 録音に利用するデバイスの選択はできません。(デフォルトになる)デバイスを選択する場合は, Audio Queue Service を利用します。iOSはマイク入力は1つです今のところ。

AVAudioRecorder を利用すると以下のようなことができるらしいです。


・録音
・長さ(duration)を決めて録音
・PauseとResume
・レベルで与えられた入力のオーディオレベルを取得する
・ファイルとして保存する

すこし調べてみて出来そうもなかったこと
録音の入力(マイクの入力)音量の変更(iOS)

※ちなみにMac OS Xならできます

・サンプル :  録音してファイルとして保存, 再生もできます

※ちなみに, Simulator でも動作します。私はMac Book Pro を使っていますが, マイクついています。さらに仕事で, Mac を使っていますが, こちらもマイクがついています。マイクが付いていれば録音のテストをSimulator 上でもできます。

- RecordViewController.h

#import "ViewController.h"
#import <AudioToolbox/AudioToolbox.h>

@interface RecordViewController : ViewController

@property (nonatomic)AVAudioRecorder *recorder;
@property (nonatomic)AVAudioSession *session;
@property (nonatomic)AVAudioPlayer *player;


@property (weak, nonatomic) IBOutlet UIButton *recordButton;
- (IBAction)recordClick:(id)sender;

@property (weak, nonatomic) IBOutlet UIButton *playButton;
- (IBAction)playClick:(id)sender;

@end



AudioSessionと AVAudioRecorder, AVAudioPlayerを宣言しています。
ARC用です。


//
//  RecordViewController.m
//  AudioSamples
//
//  Created by atmarkplant on 13/02/10.
//  Copyright (c) 2013 atmarkplant. All rights reserved.
//

#import "RecordViewController.h"

@interface RecordViewController ()

@end

- RecordViewController.m
@implementation RecordViewController

@synthesize session;
@synthesize recorder;
@synthesize player;


- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
// Do any additional setup after loading the view.
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

#pragma mark - Helpers
-(NSMutableDictionary *)setAudioRecorder
{
    NSMutableDictionary *settings = [[NSMutableDictionary alloc] init];
    [settings setValue:[NSNumber numberWithInt:kAudioFormatLinearPCM] forKey:AVFormatIDKey];
    [settings setValue:[NSNumber numberWithFloat:44100.0] forKey:AVSampleRateKey];
    [settings setValue:[NSNumber numberWithInt:2] forKey:AVNumberOfChannelsKey];
    [settings setValue:[NSNumber numberWithInt:16] forKey:AVLinearPCMBitDepthKey];
    [settings setValue:[NSNumber numberWithBool:NO] forKey:AVLinearPCMIsBigEndianKey];
    [settings setValue:[NSNumber numberWithBool:NO] forKey:AVLinearPCMIsFloatKey];
    
    return settings;
}

-(void)recordFile
{
    // Prepare recording(Audio session)
    NSError *error = nil;
    self.session = [AVAudioSession sharedInstance];
    
    if ( session.inputAvailable )   // for iOS6 [session inputIsAvailable]  iOS5
    {
        [session setCategory:AVAudioSessionCategoryPlayAndRecord error:&error];
    }
    
    if ( error != nil )
    {
        NSLog(@"Error when preparing audio session :%@", [error localizedDescription]);
        return;
    }
    [session setActive:YES error:&error];
    if ( error != nil )
    {
        NSLog(@"Error when enabling audio session :%@", [error localizedDescription]);
        return;
    }
    
    // File Path
    NSString *dir = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];
    NSString *filePath = [dir stringByAppendingPathComponent:@"test.caf"];
    NSURL *url = [NSURL fileURLWithPath:filePath];
    
   // recorder = [[AVAudioRecorder alloc] initWithURL:url settings:nil error:&error];
   recorder = [[AVAudioRecorder alloc] initWithURL:url settings:[self setAudioRecorder] error:&error];
   
    //recorder.meteringEnabled = YES;
    if ( error != nil )
    {
        NSLog(@"Error when preparing audio recorder :%@", [error localizedDescription]);
        return;
    }
    [recorder record];
}

-(void)stopRecord
{
    if ( self.recorder != nil && self.recorder.isRecording )
    {
        [recorder stop];
        self.recorder = nil;
    }
}

-(void)playRecord
{
    NSError *error = nil;
    
    // File Path
    NSString *dir = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];
    NSString *filePath = [dir stringByAppendingPathComponent:@"test.caf"];
    NSURL *url = [NSURL fileURLWithPath:filePath];
    
    if ( [[NSFileManager defaultManager] fileExistsAtPath:[url path]] )
    {
        self.player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
        
        if ( error != nil )
        {
            NSLog(@"Error %@", [error localizedDescription]);
        }
        [self.player prepareToPlay];
        [self.player play];
    }
}

- (IBAction)recordClick:(id)sender
{
    if ( self.recorder != nil && self.recorder.isRecording )
    {
        [self stopRecord];
        [self.recordButton setTitle:@"Record" forState:UIControlStateNormal];
    }
    else
    {
        [self recordFile];
        [self.recordButton setTitle:@"..." forState:UIControlStateNormal];
    }
}
- (IBAction)playClick:(id)sender
{
    [self playRecord];
}
@end



重要な部分は太字になっています。
-(NSMutableDictionary *)setAudioRecorder
では, 保存形式を入れています。 settingsの部分で入れていますが, nilにするとdefault の設定になります。 辞書式に設定を入れていきます。ここで保存形式などを細かく指定できます。

-(void)recordFile 
で, 実際の処理をしています。処理手順はこんな感じです。

1. AudioSession をつくる
2. マイク入力が可能かどうかの確認
3. ファイルパスの設定
4. AVAudioRecorder の作成
5. record 開始




※caf って何? ということですが, caf はApple のwrapper です。中身はこれだけではわかりません。PCMかもしれないですし, MP4かもしれません。動画いう.avi みたいなコーデックのラッパーみたいなものでしょうか。






0 件のコメント:

コメントを投稿