我有一个连接到ATmega微控制器的MP3板,它还连接到电位器。 MP3板直接通过板载扬声器播放MP3数据,因此我也可以设置输出音量。
因此,正如您可能猜到的那样,我从poti中读取值并将其转发给微控制器。不幸的是,微控制器不会以线性方式增加音量。因此,从0到128,您几乎听不到任何声音,从128到255(最大),音量会迅速增加。
我发现,以下功能可以解决这个问题:
vol = 1 - (1 - x)^4
但x必须介于0和1之间,结果也介于0和1之间。
由于我在微控制器上,我想
也许有些人有想法?太棒了!
uint8_t linearize_volume(uint8_t value) {
// ideas?
// please don't use bigger data types than uint16_t
}
答案 0 :(得分:3)
您可以为CPU周期“支付”内存。如果您有256字节的ROM可用,那么计算此类函数的最便宜的方法是构建查找表。
创建一个程序,打印256个8位数字的列表,其中包含非线性函数的值。程序的速度并不重要,因为你只运行一次。将程序打印的数字作为数组初始化程序复制到C程序中,然后执行查找而不是计算函数。
答案 1 :(得分:1)
你可以通过将值视为8.8定点并通过平方两次提高到4的幂来得到合理的估计。
uint8_t linearize_volume(uint8_t value) {
// Approximate 255 * (1 - (1 - x/255)^4)
uint16_t x = 0xff - value;
x = (x * x) >> 8;
x = (x * x) >> 8;
return 0xff - x;
}
答案 2 :(得分:0)
首先,请确保您使用的是线性锅,而不是音频锥形锅。
这是典型的音频输出。数据是正弦波,因此负值是必要的。您当然可以将负片转换为正片,仅用于访问其功率级别,但如果没有听到完全不同的声音,则无法更改样品。
根据输出设备的不同,较低的值可能无法提供足够的功率来为扬声器充电。
“MP3板”应包括控制音量的功能,而无需更改样品。
你说你读了锅并将它转发给微型。你不是在用micro的ADC读锅吗?