- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在尝试使用 C 中的相位累加器实现带反馈的 FM 合成运算符。在 Tomisawa 的 original patent 中,进入加法器的相位累加器对负索引和正索引进行计数,从 -pi 正弦波相位的 -2^(n-1} 到 pi 相位的 2^(n-1)。为简单起见,我想使用一个仅对正值计数的相位累加器,使用未经过运算的 32 位整数的最高字节作为正弦表查找的索引。
我已经对此进行了试验,不幸的是,我似乎无法让算法在使用反馈时产生预期的结果。将正弦波输出添加到相位累加器应该会产生类似锯齿波的波形,但我无法弄清楚如何将输出正弦波(这是一个 16 位有符号整数)正确添加到无符号相位累加器来产生这个。如有任何建议,我们将不胜感激。
编辑:
一些澄清可能是有序的。以下是 Tomisawa 的原始专利中的一些图表:
当相位累加器和正弦波输出都带符号时,该算法很容易实现。相位累加器从 -1 开始运行到 1,正弦波输出也在 -1 和 1 之间。在 Python 中,生成 1000 个样本的算法看起来有点像这样:
table = []
feedback = 0.25
accumulator = -1
for i in xrange(1000):
output = math.sin(math.pi*(accumulator + feedback*output)
table[i] = output
accumulator += 0.005
if accumulator > 1:
accumulator = -1
产生如下所示的输出:
我正在尝试使此算法适应 C。在 C 中,为了提高计算效率,我希望相位累加器是 32 位无符号整数而不是有符号整数。这样,我可以将累加器高字节的前两位用作象限索引,将第二个高字节用作 256 个 16 位正弦值数组的索引,用于 1024 值正弦表。喜欢:
XXXXXXQQ.IIIIIIII.XXXXXXXX.XXXXXXXX
^^ ^^^^^^^^
quadrant index
我的问题是我很难将给定的 FM 算法应用于无符号相位累加器。如果相位累加器是一个无符号的 32 位整数,而正弦波表输出是一个(有符号或无符号的)16 位整数,我如何调整专利中所示的算法和上面的 Python 代码以使用这种格式,并产生相同的输出?
最佳答案
首先我们可以尝试用 C 语言编写 pyton 代码
#include <stdio.h>
#include <math.h>
void main() {
double table[1000];
double feedback = 0.25;
double accumulator = -1;
int i;
for (i=0;i<1000;i++) {
double output = sin(M_PI*(accumulator + feedback*output));
table[i]=output;
accumulator += 0.005;
if (accumulator > 1)
accumulator = -1;
printf("%f\n",output);
}
}
下一步 - 使用 sin 的计算值
#include <stdio.h>
#include <math.h>
void main() {
double table[1000];
double feedback = 0.25;
double accumulator = 1;
int i;
double sinvalue[1024];
for (i=0;i<1024;i++) {
sinvalue[i]=sin(M_PI*i/512);
}
for (i=0;i<1000;i++) {
double output = sinvalue[(int)(512*(accumulator + feedback*output))%1024];
printf("%0.6f %0.6f %0.6f\t",accumulator,feedback,output);
table[i]=output;
accumulator += 0.005;
if (accumulator > 2)
accumulator = 0;
printf("%f\n",output);
}
}
下一步 - 使用 16 位 sin 值和输出。在此“输出”中的版本值如 XXXXXXQQ.IIIIIIIII.XXXXXXXX.XXXXXXXX此外,我们失去了一些准确性。
#include <stdio.h>
#include <math.h>
#define ONE ((int)(2*256*256*256/M_PI))
void main() {
double table[1000];
double feedback = 0.25;
double accumulator = 1;
double accumulatorDelta = 0.005;
unsigned int feedback_i = ONE*feedback/32768;
unsigned int accumulator_i = ONE*accumulator;
unsigned int accumulatorDelta_i = ONE*accumulatorDelta;
int i;
double sinvalue[1025];
short int sinvalue_i[1025];
for (i=0;i<1025;i++) {
sinvalue[i]=sin(M_PI*i/512);
sinvalue_i[i]=32786*sinvalue[i];
if (sinvalue[i]*32768>32768) sinvalue_i[i]=32768;
if (sinvalue[i]*32768<-32767) sinvalue_i[i]=-32767;
}
for (i=0;i<1000;i++) {
double output = sin(M_PI*(accumulator + feedback*output));
short int output_i = sinvalue_i[ ((unsigned int) ((accumulator_i + feedback_i*output_i)*M_PI)>>16)%1024 ];
table[i]=output;
accumulator += 0.005;
if (accumulator > 2)
accumulator = 0;
accumulator_i += accumulatorDelta_i;
if (accumulator_i > 2*ONE)
accumulator_i = 0;
printf("%f %f %04X\n",output,(float)output_i/32768,(unsigned short int)output_i);
}
}
但是我们浪费了一些时间来转换 int->double->int如果我们改变一个常量,我们将失去快速进入象限的机会,但会摆脱转换
#include <stdio.h>
#include <math.h>
#define ONE ((int)(2*256*256*256))
void main() {
short int table[1000];
unsigned int feedback_i = ONE*0.25/32768;
unsigned int accumulator_i = ONE*1;
unsigned int accumulatorDelta_i = ONE*0.005;
int i;
short int sinvalue_i[1025];
for (i=0;i<1025;i++) {
double sinvalue=sin(M_PI*i/512);
sinvalue_i[i]=32786*sinvalue;
if (sinvalue*32768>32768) sinvalue_i[i]=32768;
if (sinvalue*32768<-32767) sinvalue_i[i]=-32767;
}
for (i=0;i<1000;i++) {
short int output_i = sinvalue_i[ ( (accumulator_i + feedback_i*output_i)>>16)%1024 ];
table[i]=output_i;
accumulator_i += accumulatorDelta_i;
if (accumulator_i > 2*ONE)
accumulator_i = 0;
printf("%f %04X\n",(float)output_i/32768,(unsigned short int)output_i);
}
}
关于c - 使用相位累加器的 FM 合成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16889426/
我正在从last.fm 获取有关我正在收听的轨道的信息。但是,我无法获取有关我正在录制的内容的信息,就像您在last.fm 页面上看到的那样:“现在从spotify scrobbling” 有谁知道这
我需要获取歌曲的发行日期。 在 last.fm API 中,如文档中所述,足以向服务器发出 HTTP 请求,它将使用包含字段“”的 XML(或 JSON)进行回复(如示例响应中所示在网站上)。 问题是
我正在尝试对音频信号进行频率调制。我可以使用以下方程式y = cos(Fc + sin(Fm))与另一个正弦波(载波)成功调频一个正弦波(载波),但是我不确定如何调频音频信号因为显然我不能使用上述公式
FMDatabase *database = [FMDatabase databaseWithPath:databasePath]; [数据库打开]; FMResultSet *results = n
我有以下一段代码。 REPORT ZZY. CLASS lcl_main DEFINITION FINAL CREATE PRIVATE. PUBLIC SECTION. CLASS-ME
我正在使用 FUNCTION_CREATE 创建 FM 并且一切正常,我正在传递一堆参数并且 FM 已按预期创建。但问题是FM的源代码部分。是否可以使用 FUNCTION_CREATE 创建它,我应该
我找到了这段代码: FUNCTION /FOO/BAR. *"---------------------------------------------------------------------
我已经为音频信号的频率调制编写了以下代码。音频本身为1秒长,以8000 Hz采样。我想通过使用频率为50 Hz(表示为采样频率的一部分)的正弦波将FM应用于此音频信号。调制信号的调制指数为0.25,以
布隆过滤器和哈希草图(也称为 FM 草图)之间有什么区别以及它们的用途是什么? 最佳答案 哈希草图/Flajolet-Martin 草图 Flajolet, P./Martin, G. (1985):
我正在尝试构建用于在线收听调频广播的移动应用程序。任何人都可以帮助我在哪里可以获得有关此类 FM 的流媒体 url 的信息,以便我可以根据我的位置或位置字符串进行搜索。 简单地说我想在特定位置找到所有
我正在尝试在 FM 中使用 findwindow api 调用,我可以在 VCL 应用程序中使用它查找,但不能在 FM 中使用。 这是我的代码 function WindowExists(ti
我想为安卓手机开发一个定制的 FM radio 应用程序,里面有 FM 接收芯片。 通过研究,我发现 FM 接收器通常由 BroadComm 开发。 主要的安卓手机制造商——三星、HTC、索尼爱立信是
我正在尝试录制 FM 广播音频流。我可以使用一个音频源进行录制,即摩托罗拉的 9。 但是当我尝试使用不同的手机时它不起作用。所以我想知道如何动态获取这个音频源。 我是这样记录的 //RX_SRC i
我正在尝试从 Last.fm 获取艺术家图像并将其应用到 ImageView,但没有返回任何图像。我不确定我在这里做错了什么。 private void setLastFmArtistImage()
我有一个音频信号,上面有一种 FM 编码信号。编码信号使用 this Biphase mark coding technique maximuPossibleIndex) break;
我正在尝试使用 C 中的相位累加器实现带反馈的 FM 合成运算符。在 Tomisawa 的 original patent 中,进入加法器的相位累加器对负索引和正索引进行计数,从 -pi 正弦波相位的
我正在尝试使用 Audiolet(合成库,http://en.wikipedia.org/wiki/YM3812)在 JavaScript 中实现 Yamaha YM3812 声音芯片(又名 OPL2
我正在使用 Last.fm API 学习 API。我如何知道此示例代码中指定的日期是什么(chart from="1108296002")? ... 我在这里得到了例子:http:
我是 SAP SD 模块专家,我经常需要调试代码。有时我需要知道哪些节目/FM 地址特定表。我在 SE11 中将 Where used 用于表,它会找到处理该表的类方法。但是当我将 Where use
我正在使用 last.fm JavaScript API ( https://github.com/fxb/javascript-last.fm-api ) 来获取相似的轨道 (track.getSi
我是一名优秀的程序员,十分优秀!