读书笔记---音频设备访问

开发音频应用,主要有两个框架AVFoundation和CoreAudio.

CoreAudio内容比较多使用起来也比较麻烦,他有4个主要的音频处理引擎API:System Sound,Audio Unit,Audio Queue和Open AL


System Sound 它是基于C的音频API,可以播放系统声音,它播放短的声音,不超过30s.

Audio Unit 他是最底层的声音生成器,他生成原始音频样本并且将音频值放到输出缓冲区中.Audio Unit也可以实现混合多种声音.

Audio Queue 可以提供对音频的录制,播放,暂停,循环和同步处理.

OpenAL 是一个基于位置变化的3D声音的工业化标准API,他的API接口与OpenGL非常相似.主要应用于游戏音效处理.

Audio File 服务 这个服务简化了处理各种不同的音频容器格式的任务.可以读写各种支持音频流,而不用考虑他们的差异

Audio File Stream 服务 读写网络音频流数据,当从一个流读取数据时,使用该服务解析这个流并确定其格式,最终把音频数据包传递给一个音频队列或自行处理.

Audio Converter 服务 实现音频数据格式的转换

Audio Session服务 协调使用音频资源与系统之间的关系


在AVFoundation框架中,AVAudioPlayer类可以实现一般音频播放,用于播放超过5s的声音,只能播放本地声音,不能播放网络媒体文件.


<span style="font-size:18px;">- (IBAction)play:(id)sender {
    
    NSLog(@"player %i",player.isPlaying);
    
    NSError *error = nil;
    if (player == nil) {
        player = [[AVAudioPlayer alloc]initWithContentsOfURL:[NSURL URLWithString:[[NSBundle mainBundle] pathForResource:@"1" ofType:@"mp3"]] error:&error];
        player.delegate = self;
    }
    
    if (error) {
        NSLog(@"%@",[error description]);
    }else {
        [player play];
    }
}

- (IBAction)pause:(id)sender {
    
    if (player&&player.isPlaying) {
        [player pause];
    }
    
}

- (IBAction)stop:(id)sender {

    if (player) {
        [player stop];
        player.delegate = nil;
        player = nil;
    }
    
}

#pragma delegate

- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag{
    NSLog(@"播放完成");
}

- (void)audioPlayerDecodeErrorDidOccur:(AVAudioPlayer *)player error:(NSError *)error{
    NSLog(@"error : %@",[error localizedDescription]);
}

- (void)audioPlayerEndInterruption:(AVAudioPlayer *)player withOptions:(NSUInteger)flags{
    NSLog(@"中断返回");
}

- (void)audioPlayerBeginInterruption:(AVAudioPlayer *)player{
    NSLog(@"播放中断");
}

</span>

录音


- (NSString *)doc{
//    NSArray *arr = NSSearchPathForDirectoriesInDomains(NSDocumentationDirectory, NSUserDomainMask, YES);
//    return [arr objectAtIndex:0];
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
                                                         NSUserDomainMask, YES);
    return [paths objectAtIndex:0];
}

- (IBAction)record:(id)sender {
    
    if (recoeder == nil) {
        //配置存放路径
        NSString *filePath = [NSString stringWithFormat:@"%@/rec_audio.caf",[self doc]];
        NSURL *fileUrl = [NSURL fileURLWithPath:filePath];
        
        NSError *error = nil;
        
        
        [[AVAudioSession sharedInstance]setCategory:AVAudioSessionCategoryRecord error:&error];
        [[AVAudioSession sharedInstance] setActive:YES error:&error];
        
        NSMutableDictionary *settings = [NSMutableDictionary dictionary];
        [settings setValue:[NSNumber numberWithInt:kAudioFormatLinearPCM] forKey:AVFormatIDKey];//设置录制音频编码格式
        [settings setValue:[NSNumber numberWithFloat:44100.0] forKey:AVSampleRateKey];//设置音频采样率
        [settings setValue:[NSNumber numberWithInt:1] forKey:AVNumberOfChannelsKey];//设置声道数量
        [settings setValue:[NSNumber numberWithInt:16] forKey:AVLinearPCMBitDepthKey];//设置采样位数
        [settings setValue:[NSNumber numberWithBool:NO] forKey:AVLinearPCMIsBigEndianKey];//设置音频解码是大字节序还是小字节序
        [settings setValue:[NSNumber numberWithBool:NO] forKey:AVLinearPCMIsFloatKey];//设置音频解码是否为浮点数
        
        recoeder = [[AVAudioRecorder alloc]initWithURL:fileUrl settings:settings error:&error];
        recoeder.delegate = self;
        
    }
    
    if (recoeder.isRecording) {
        return;
    }
    
    if (player && player.isPlaying) {
        [player stop];
    }

    [recoeder record];
    
    self.label.text = @"录制中...";
}

- (IBAction)stop:(id)sender {

    self.label.text = @"停止...";

    if (recoeder.isRecording) {
        [recoeder stop];
        recoeder.delegate = nil;
        recoeder = nil;
    }
    
    if (player.isPlaying) {
        [player stop];
    }
}

- (IBAction)play:(id)sender {

    if (recoeder.isRecording) {
        [recoeder stop];
        recoeder.delegate = nil;
        recoeder = nil;
    }

    if (player.isPlaying) {
        [player stop];
    }
    
    NSString *filePath =
    [NSString stringWithFormat:@"%@/rec_audio.caf", [self doc]];
    NSURL *fileUrl = [NSURL fileURLWithPath:filePath];
    
    NSError *error = nil;
    
    //AVAudioSession类提供了 AVAudio Session 服务,用来指定应用与音频系统如何交互.AVAudioSession 是通过指定一个音频类别实现的,音频类别描述了应用使用音频的方式
    [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:&error];
    
    //设置是否活跃,这回把后台的任何系统声音关闭
    [[AVAudioSession sharedInstance] setActive:YES error:&error];
    player = [[AVAudioPlayer alloc] initWithContentsOfURL:fileUrl error:&error];
    
    if(error) {
        NSLog(@"%@",[error description]);
    } else {
        [player play];
        _label.text = @"播放...";
    }

}

#pragma delegate

- (void)audioRecorderDidFinishRecording:(AVAudioRecorder *)recorder successfully:(BOOL)flag{
    NSLog(@"录制完成");
}

- (void)audioRecorderEncodeErrorDidOccur:(AVAudioRecorder *)recorder error:(NSError *)error{
    NSLog(@"录制发送错误 %@",[error localizedDescription]);
}

- (void)audioRecorderBeginInterruption:(AVAudioRecorder *)recorder{
    NSLog(@"中断播放");
}

- (void)audioRecorderEndInterruption:(AVAudioRecorder *)recorder withOptions:(NSUInteger)flags{
    NSLog(@"中断返回");
}



更多干货,请支持原作:http://item.jd.com/11436547.html


你可能感兴趣的:(ios,audio,音频,AVFoundation,CoreAudio)