- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我一直在使用数学方程式为 android 做一些基本的综合。公式保持并变得越来越复杂的问题。所以我开始使用波表合成。
到目前为止,我可以根据字节数组和预定频率播放单个音符。然而,当寻找公式来重新采样样本并改变波表的音高时......我只是找不到一个简单的解决方案。有整个图书馆可以做到这一点。但感觉应该是一个简单的公式,通过下采样或过采样来改变采样频率。
有没有一种简单的方法可以做到这一点?
例如:输入是 [0,0.5,1,0.5,0...]
让我们假装它是C4
要使其成为 C3,预期输出应为 [0,0.25,0.5,0.75,1,0.75,0.5,0.25,0...]
基本上它是和android的audiopool“速率”属性,但只是重新采样字节的公式,我在任何地方都没有找到
编辑:
感谢 Phil Freihofner 指导我找到答案。然而,他提供的原始公式并没有在过度采样的情况下平滑结束。但这是一个非常好的开始,我只需要顺利结束。我将附上我的结束代码,以防有人想要一个简单的函数来“拉伸(stretch)”一个浮点数组。
public static void main(String[] args) {
float[] sample = {0f, 0.5f, 1f, 0.5f, 0f, 0.5f, 1f, 0.5f, 0};
System.out.println(Arrays.toString(resample(sample, 2f)));
//[0.0, 0.25, 0.5, 0.75, 1.0, 0.75, 0.5, 0.25, 0.0, 0.25, 0.5, 0.75, 1.0, 0.75, 0.5, 0.25, 0.125, 0.0]
System.out.println(Arrays.toString(resample(sample, 3f)));
//[0.0, 0.16666667, 0.33333334, 0.5, 0.6666667, 0.8333333, 1.0, 0.8333334, 0.6666666, 0.5, 0.33333337, 0.16666663, 0.0, 0.16666675, 0.33333325, 0.5, 0.66666675, 0.83333325, 1.0, 0.83333325, 0.66666675, 0.5, 0.33333325, 0.16666675, 0.111111164, 0.055555582, 0.0]
System.out.println(Arrays.toString(resample(sample, 0.5f)));
//[0.0, 1.0, 0.0, 1.0, 0.0]
System.out.println(Arrays.toString(resample(sample, 1f)));
//[0.0, 0.5, 1.0, 0.5, 0.0, 0.5, 1.0, 0.5, 0.0]
System.out.println(Arrays.toString(resample(sample, 4.3f)));
//[0.0, 0.116279066, 0.23255813, 0.3488372, 0.46511626, 0.5813953, 0.6976744, 0.81395346, 0.9302325, 0.95348847, 0.83720934, 0.72093034, 0.6046512, 0.4883722, 0.37209308, 0.25581408, 0.13953495, 0.023255944, 0.09302306, 0.20930219, 0.3255813, 0.44186044, 0.5581393, 0.67441845, 0.7906976, 0.9069767, 0.9767444, 0.8604653, 0.74418616, 0.62790704, 0.51162815, 0.39534903, 0.2790699, 0.16279078, 0.04651189, 0.034883916, 0.023255944, 0.011627972, 0.0]
}
public static float[] resample(float[] sample, float rate) {
if (rate == 1) {
return sample;
}
int newLength = Math.round(sample.length * rate);
int rateUnit = (int) Math.round(rate);
float[] result = new float[newLength];
for (int i = 0; i < newLength - rateUnit; i++) {
float val = (i / rate);
int o = (int) val;
result[i] = sample[o + 1] * (val - o)
+ sample[o] * ((o + 1) - val);
}
int startIndex = newLength - rateUnit;
for (int u = 0; u < newLength - startIndex; u++) {
result[startIndex + u] = result[startIndex - 1] + (u + 1) *
(sample[sample.length - 1] - result[startIndex - 1]) / rateUnit;
}
return result;
}
最佳答案
假设您有一个 float 波表。
然后你可以做的是创建一个“光标”来遍历表。此游标不必是整数,它可以是浮点数。当您的光标落在波表的两个元素之间的值上时,您可以使用线性插值来计算“足够好”的值以返回。
考虑第一个波表。当您使用增量为 1 的游标时,它会播放 C4。如果您将增量设为 0.5 并使用线性插值,那么您将返回的值将与您的表中的内容相同,但要低一个 Octave 。
但是您可以选择任何增量值,甚至可以随时间更改它(以获得滑音)。
光标增量的确切大小将取决于波表的大小和采样率以及所需的音高。
我正在为我编码的 FM 合成器使用波表。正弦波表有 1024 个增量,用于单个波、浮点分辨率。它似乎运作良好。声音非常清晰——与我的旧 Yamaha DX7 或第二代 DX7S 相比,量化噪音肯定要少。
这是我目前使用线性插值返回给定光标值的波表值的代码:
public static float get(float i)
{
final int idx = (int)i;
return data[idx + 1] * (i - idx)
+ data[idx] * ((idx + 1) - i);
}
数据表为
float[]
长度为 1025,而周期为 1024 步。我有
data[0] == data[1024]
以便上述算法适用于
0 <= cursor < 1024
范围内的任何游标值.当光标等于或超过 1024 时,我减去 1024。这样,可以无限增加光标,创建任何持续时间的音调。
关于java - 更改波表音高(重新采样),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64417603/
这是我的问题 1)我有动态y数组数据,使用该数组如何连续绘制波浪。 如果Y数组数据完整,则使用相同的y数组数据继续。 2)声音自动播放在该数组值是143.if我停止不停止。 这是我的代码:
网络上有太多使用 WiFi 或蓝牙传输数据的对讲机应用程序(至少我见过的所有应用程序),但没有一个使用内置天线通过 radio 波传输数据真正的对讲机设备。 是否有任何安全原因?还是限制作为发送器/接
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 想改进这个问题?更新问题,使其成为 on-topic对于堆栈溢出。 4年前关闭。 Improve this
我正在尝试着手研究 boost wave,但到目前为止,我的运气并不好。 我尝试了网站上的示例代码。如下: #include #include #include #include #inclu
我正在尝试使用 svg 编写一个 javascript 加载器。想法是,它是一个从下到上两侧均匀填充的圆圈,加载器的顶线是一个从左到右不断移动的正弦波。 我能够根据百分比为加载程序创建弧线,如下所示:
这个问题在这里已经有了答案: Is there a one-line function that generates a triangle wave? (8 个答案) 关闭 9 年前。 我试图用 A
当我在论坛中搜索时,我了解到要定位 GPS,我必须通过互联网连接或短信发送坐标。但据我所知,我们可以通过 radio 波进行通信,发送语音、图片、数据。我可以用它来获取数据吗? GPS 设备?因为业余
我是一名优秀的程序员,十分优秀!