前言
最近在开发多媒体音视频相关业务,期间遇到的问题这里全做记录下来,下面是同事提供的一个例子我整理出来,以备后续开发遇到此类问题有个备案.
开篇
最近开发音频涉及到左右声道调节,基于左右声道的音量实现 声音环绕效果. 下面是 UI 演示.
这里其实修改的类似 AVAudioPlayer
里面的pan
值修改
我在以前的文章也有一篇提到过这个pan 值
可能大家不理解为啥 这个 API 起名叫pan
在声学领域这个东西有专门的名字叫 声像
.
这篇文章介绍了一些我们对声学知识的简单介绍,虽然不知道作者是谁,但是作者应该是非常专业的声学开发者.
其实按照我们平常的理解应该是这样去实现这个 pan 值的修改
左声道音量给右声道声音的补偿 或者右侧声道给左侧声道的补偿,通过滑块的 value 来决定两边谁加多少减多少,但是大家的思路是对的,但是做法是不正确的,因为 两边的音量放在中间必须是1.0,也就是说 range 在 -1 ~ 1
之间. 如果按照这个滑动方式回导致滑动过大.
带着这个问题我的同事找到了一个公式 来计算 这个值
pan
就是我们的滑块的value
Vl
代表左侧音量Vr
代表右侧音量
根据这个公式我们有如下 代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#import <math.h>
typedef NS_ENUM(NSUInteger, KSYMCChannelType) {
KSYMCChannelTypeLeft = 0,
KSYMCChannelTypeRight = 1
};
@interface KSYMultiCanvasHelper : NSObject
+ (CGFloat)calculateVolume:(KSYMCChannelType)type
panValue:(CGFloat)pan
volume:(CGFloat)volume;
@end
@implementation KSYMultiCanvasHelper
+ (CGFloat)calculateVolume:(KSYMCChannelType)type
panValue:(CGFloat)pan
volume:(CGFloat)volume{
if (type == KSYMCChannelTypeLeft) {
CGFloat leftVolumn = sqrt(2) * cos((1 + pan)*M_PI_4) *volume;
return leftVolumn;
} else if (type == KSYMCChannelTypeRight) {
CGFloat rightVolumn = sqrt(2) * sin((1 + pan)*M_PI_4) *volume;
return rightVolumn;
}
return 0;
}
@end
这里的计算还是比较准确的.
经过测试 左侧 音量 为 0 时 右侧音量应该是 1.41左右
总结
经过上述测试音频的 pan 值修改 如果自行开发还是比较好搞得,只是鄙人对音频的知识积累的太少了.这篇文章看起来虽然没什么技术含量,全当知识的点滴积累吧. 至于为啥 是 M_PI_4
还请专研一下文章的扩展链接,因为要把一个线性的操作转换成一个圆型方便数学的计算,以及 声像和声向的区别.
全文完