20160825音频开发之AVAudioRecoder
来源:互联网 发布:osiris数据库 编辑:程序博客网 时间:2024/06/01 10:13
上一篇博文介绍了一下AVAudioPlayer,本文分享一下我学习AVAudioRecoder录制音频的相关内容。
打开你的iPhone,自带一个录音功能的应用---语音备忘录,界面简洁,功能很给力。即时通信软件,发送语音消息应该是常用的功能,目前一些K歌App也有录音这个功能,所以在开发中AVAudioRecorder也是比较重要的,高效灵活的使用还是很有必要的。
我下载过几款很棒的音频应用,比如全民K歌,弹琴吧,我可以用弹琴吧调试我的吉他,这个功能很强大,我再也不用我的调音器了。还有全民K歌,这款软件最强大功能是评分,其中有个细节引起我的注意。根据我的声音的强度的高低绘制不同的曲线,我在思考这个功能是如何实现的。今天找到了答案,通过 Metering(声音计量),可以通过这个技术将声音信号转化,以可视化的形式呈现。
AVAudioRecorder 有两个方法返回声音的分贝值。
- (float)peakPowerForChannel:(NSUInteger)channelNumber; /* returns peak power in decibels for a given channel */- (float)averagePowerForChannel:(NSUInteger)channelNumber; /* returns average power in decibels for a given channel */
分贝值有个计算公式应该是 db = 10lgM (M表示声音强度吧),目前我们通过上面的两个函数得到db,平均分贝,峰值分贝。
我们希望将前面得到的分贝值的结果转化我线性的0到1形式,这需要一个转化的方式,如果我们把一次计算的结果记录下来,那么下次的计算就不需要了,因此提供下面的一个方法
#define MIN_DB -60.0f#define TABLE_SIZE 300@implementation THMeterTable { float _scaleFactor; NSMutableArray *_meterTable;}- (id)init { self = [super init]; if (self) { float dbResolution = MIN_DB / (TABLE_SIZE - 1); _meterTable = [NSMutableArray arrayWithCapacity:TABLE_SIZE]; _scaleFactor = 1.0f / dbResolution; float minAmp = dbToAmp(MIN_DB); float ampRange = 1.0 - minAmp; float invAmpRange = 1.0 / ampRange; for (int i = 0; i < TABLE_SIZE; i++) { float decibels = i * dbResolution; float amp = dbToAmp(decibels); float adjAmp = (amp - minAmp) * invAmpRange; _meterTable[i] = @(adjAmp); } } return self;}float dbToAmp(float dB) { return powf(10.0f, 0.05f * dB);}- (float)valueForPower:(float)power { if (power < MIN_DB) { return 0.0f; } else if (power >= 0.0f) { return 1.0f; } else { int index = (int) (power * _scaleFactor); return [_meterTable[index] floatValue]; }}@end
该类的主要的功能是:
//It creates an internal table storing the precomputed db -> linear
// values.
其中关键是_meterTable 保存一个列表
-(float)valueForPower:(float)power
这个接口提供查询。
接着是界面上的转化,重新绘制,或许要用到定时器,进行轮询。可以考虑用这个CADisplayLink作为解决方案。参考下面这段代码
self.levelTimer = [CADisplayLink displayLinkWithTarget:self selector:@selector(updateMeter)]; self.levelTimer.frameInterval = 5; [self.levelTimer addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
/* Defines how many display frames must pass between each time the
* display link fires. Default value is one, which means the display
* link will fire for every display frame. Setting the interval to two
* will cause the display link to fire every other display frame, and
* so on. The behavior when using values less than one is undefined. *
我的理解:如果是默认,定时器的刷新率是屏幕的刷新同步,应该是每秒60次,如果设置frameInterval = 5,则刷新率应该是 60 / 5 = 12。
本文
完!
- 20160825音频开发之AVAudioRecoder
- AvAudioRecoder
- iOS开发之音频
- QT开发之音频
- Android音频开发之尝试音频混合
- iPhone开发之音频知识
- IOS 开发之音频播放
- Iphone开发之音频学习
- iOS开发之 音频总结
- Android开发之播放音频
- iOS 音频开发之CoreAudio
- iOS开发实用技术之音频开发
- Iphone开发之音频 (二) : 程序实现播放音频
- iPhone音频开发之:程序实现播放音频
- Android开发之初探音频的播放
- iPhone应用开发之AVAudioPlayer音频播放
- iPhone应用开发之AudioServicesPlayerSystemSound音频播放
- iOS开发之AVAudioPlayer 音频播放
- Android之时间戳转今天、明天、后天、周几
- WIFI的状态判断
- 观察者模式(Observer Pattern)
- Android数据存储五种方式总结
- C语言基础及指针⑩预编译及jni.h分析
- 20160825音频开发之AVAudioRecoder
- gradle关于依赖module编译问题
- ArcGIS runtime SDK for android的学习笔记(序:写在开始之前的话)
- postgres简易安装
- 【C++】STL常用容器总结之十一:容器小结
- 开发相关的一些网站
- Spark2.0机器学习系列之2:Logistic回归及Binary分类(二分问题)结果评估
- 诠释 Linux 中“一切都是文件”概念和相应的文件类型
- 测试