南京网站seo服务,涡阳哪里有做网站的,网站备案把二级域名放在国外,网站内容建设策略视频参考:https://www.bilibili.com/video/BV1ouUPYAErK/
修改之前的方波数据#xff0c;改播放正弦波 下面主要讲关于浮点数
1. char#xff08;字符类型#xff09;
大小#xff1a;1 字节#xff08;8 位#xff09;表示方式#xff1a;char 存储的是一个字符的 A…视频参考:https://www.bilibili.com/video/BV1ouUPYAErK/
修改之前的方波数据改播放正弦波 下面主要讲关于浮点数
1. char字符类型
大小1 字节8 位表示方式char 存储的是一个字符的 ASCII 值。由于它是一个整数类型它在内存中是以 二进制 形式存储的。 有符号 char表示的值范围通常是 -128 到 127其符号位决定了值的正负。无符号 char范围从 0 到 255。
存储示例
char c A; 对应的 ASCII 值是 65其二进制表示为 01000001。
内存示意 字符 AASCII 65十六进制 0x41二进制 010000013. int整数类型
大小4 字节32 位表示方式int 存储的是一个整数采用 二进制补码 表示。 有符号 int范围通常为 -2,147,483,648 到 2,147,483,647最高位为符号位。无符号 int表示的范围从 0 到 4,294,967,295。
存储示例
int i -123456; 使用 32 位二进制补码表示 -123456 的二进制补码表示11111111 11111110 00011101 11000000。 123456 0b00000000 00000001 11100010 01000000 ~123456 0b11111111 11111110 00011101 10111111 取反 ~1234561 0b11111111 11111110 00011101 11000000 1 内存示意 int i -123456;二进制补码表示 11111111 11111110 00011101 11000000十六进制表示 0xFFFE1DC0负数补码表示按位取反1
5. float单精度浮点数
大小4 字节32 位表示方式float 按照 IEEE 754 标准表示为 32 位浮点数包括 符号位、指数部分 和 尾数有效数字 部分。表示方法如下 符号位1 位表示数字的正负。指数部分8 位表示数字的范围通过偏移量调整。尾数部分23 位表示数字的精度。
表示为 ( − 1 ) 符号 × 1. 尾数 × 2 指数 − 127 (-1)^{\text{符号}} \times 1.\text{尾数} \times 2^{\text{指数}-127} (−1)符号×1.尾数×2指数−127
存储示例
float f 3.14f; 的 IEEE 754 单精度表示 3.14 的二进制表示为0 10000000 10010001111010111000011。
#include cstring
#include iostreamvoid printBinary(float num) {// 将 float 转换为 int按字节复制int bits;std::memcpy(bits, num, sizeof(bits));// 打印二进制表示for (int i 31; i 0; --i) {std::cout ((bits i) 1); // 逐位打印if (i 31 || i 23)std::cout ; // 分隔符用于区分符号位、指数位、尾数位}std::cout std::endl;
}int main() {float num 3.14f;std::cout Binary representation of num is: ;printBinary(num);return 0;
}float 32 位
内存示意 float f 3.14f;符号位0指数部分10000000尾数部分10010001111010111000011十六进制表示 0x4048F5C36. double双精度浮点数 大小8 字节64 位表示方式double 也按照 IEEE 754 标准表示但它使用 64 位包括 符号位、指数部分 和 尾数部分。它的精度比 float 更高具体结构如下 符号位1 位指数部分11 位尾数部分52 位
表示为 ( − 1 ) 符号 × 1. 尾数 × 2 指数 − 1023 (-1)^{\text{符号}} \times 1.\text{尾数} \times 2^{\text{指数}-1023} (−1)符号×1.尾数×2指数−1023
存储示例
double d 3.141592653589793; 的 IEEE 754 双精度表示 3.141592653589793 的二进制表示为0 10000000000 1001001000011111101101010100010001000010110100011000。
内存示意 double d 3.141592653589793;符号位0指数部分10000000000尾数部分1001001000011111101101010100010001000010110100011000double类似只是表示的位数更多了
继续上面修改写入正弦数据 示例
假设采样率为 44100 Hz即每秒采样 44100 个样本频率为 440 Hz比如这是标准 A 音符的频率。
每秒钟你会采集 44100 个样本。每秒钟会有 440 个周期。
那么一个周期的持续时间即波周期就是 W a v e P e r i o d 44100 440 ≈ 100.23 毫秒 WavePeriod \frac{44100}{440} \approx 100.23 \text{ 毫秒} WavePeriod44044100≈100.23 毫秒
这意味着每一个周期即波的一个完整振荡需要约 100.23 毫秒的时间。
波周期WavePeriod 是波形完成一个周期所需的时间单位是秒s。采样率S 是每秒钟采样多少个点单位是 样本/秒Hz。频率f 是波形每秒钟振荡多少次单位是 赫兹Hz。
波周期 采样率 / 频率 表示了 一个周期占用的时间即波形完成一个振荡所需要的时间反映了波形的 频率与采样细节的关系。 优化一下代码把声音写缓存相关代码提出来 vs watch技巧 添加模拟手柄改变音频调试 模拟手柄软件
因为我没有手柄只能用模拟器进行调试 游戏手柄模拟器Gaming Keyboard Splitter 可以到这个完整下载对应的软件Gaming Keyboard Splitter https://softlookup.com/download.asp?id280311
我已经传到CSDN https://download.csdn.net/download/TM1695648164/89982708
软件第一次运行会安装驱动会重启电脑
debug运行程序打开模拟手柄软件Gaming Keyboard Splitter 上面测试会听到撕裂的声音切换时
“相位跳变”是指在切换频率时波形的相位发生了不连续的变化导致声音出现不自然的突变。为了理解这一点我们需要从正弦波的相位和频率切换时的平滑性角度来分析。
1. 什么是相位
在波形中相位指的是波形在某个时间点的状态通常用一个角度来表示。例如对于正弦波 sin(θ)其中 θ 表示相位θ 通常是通过时间、频率和波速来计算的。
对于音频信号波形的相位描述的是波形的位置比如峰值、零交点等以及波形如何在时间轴上前进。不同频率的正弦波具有不同的波长周期而相位描述的是这些波形的“开始位置”。
2. 什么是相位跳变
相位跳变是指在两个连续的波形之间相位发生了突然变化。当你在播放音频时切换频率时如果没有处理好相位就可能会导致新的波形与旧的波形在相位上的不对齐。 相位对齐指的是两个不同频率的波形在切换时其相位起始位置要相同或者在一个平滑的过渡过程中对齐。相位对齐确保了波形的过渡是平滑的没有断裂感。 相位跳变如果你在切换频率时新的波形从一个不对齐的相位开始比如原本的波形处于一个正半周期而新的波形从零交点开始那么这两个波形之间会出现不连续性。这种不连续性会导致音频信号的突变或毛刺声。
3. 为什么频率切换会导致相位跳变
在频率切换时如果频率的变化过于突兀那么相位可能会发生跳变。例如 假设你正在播放一个频率为 256Hz 的正弦波这意味着每秒钟播放 256 个完整的波形周期。如果你突然切换到 512Hz 的频率意味着每秒钟播放的周期数是原来的两倍。如果没有对相位进行平滑过渡新的频率波形的起始位置可能会不一致比如一个正弦波的峰值和下一个波形的零交点不对齐导致两个波形之间的过渡不连贯。 当波形的相位不一致时你就会听到一种不自然的“呲”声或毛刺声因为音频信号的突然变化让耳朵感受到强烈的突变。
4. 如何理解和避免相位跳变 平滑过渡为了避免相位跳变最常见的做法是在切换频率时确保新的频率从平滑过渡的相位开始。这意味着你可以在切换频率之前记录当前频率的相位并确保新的频率从当前的相位状态开始播放。 相位对齐如果频率变化较大比如从 256Hz 跳到 512Hz你可以通过计算当前的相位并将其对齐到新频率来避免跳变。这样新的波形从一个平滑的相位开始不会有突然的相位变化。 渐变过渡另一种方法是通过渐变的方式逐步调整频率而不是直接跳到新的频率。通过线性插值或其他平滑过渡方法可以在一段时间内平滑地过渡到目标频率从而避免突如其来的波形跳跃。
5. 示例
假设你有一个频率为 256Hz 的正弦波
y sin(2π * 256 * t)在某一时刻t 0 时sin(0) 0t 1/256 时sin(2π) 0等等。
如果你突然从 256Hz 切换到 512Hz
y sin(2π * 512 * t)这时相位的变化会更加快速。假如没有正确处理相位那么切换时新的频率可能从一个不连续的位置开始。例如之前的正弦波刚刚完成一个周期而新的频率波形从零交点开始从而导致两个波形之间的断裂感即“呲”声。
6. 避免相位跳变的方法 记录当前的相位在频率切换时记录下当前时刻的相位然后确保新的频率从该相位继续播放。例如如果你在 t 0.1s 时切换频率可以将当前的相位例如 2π * 256 * 0.1保存下来切换到新的频率时新的波形从相同的相位位置继续计算。 平滑过渡在频率变化的过程中使用渐变方式逐步过渡到目标频率这样可以避免相位的突变。例如可以在每个采样周期调整频率增量而不是直接跳到新频率。
通过这些方法可以避免频率切换时产生不自然的“呲”声或毛刺声。 为了解决这个问题
下面用模拟手柄 StickY 对 上面代码进行测试
基于 AButton 按钮的操作来改变音频频率ToneHz和音频波形的周期WavePeriod并可能结合了控制器的 Y 轴摇杆 (StickY) 来微调频率。
更新 ToneHz音频频率 // 获取摇杆的 X 和 Y 坐标值-32768 到 32767int16 StickX Pad-sThumbLX;int16 StickY Pad-sThumbLY;// 根据摇杆的 Y 坐标值调整音调和声音xOffset StickX 12;yOffset StickY 12;// 更新音调频率 (ToneHz)通过摇杆的 Y 值来调节// 这里是将 StickY 映射到频率范围内使得频率与摇杆的上下运动相关。// 512 是基准频率StickY 值影响音频频率的变化范围。SoundOutput.ToneHz 512 (int)(256.0f * ((real32)StickY / 30000.0f));// 计算波周期基于频率决定波形的周期SoundOutput.WavePeriod SoundOutput.SamplesPerSecond / SoundOutput.ToneHz;std::cout ToneHz SoundOutput.ToneHz sThumbLY StickY std::endl; // 输出音调频率和摇杆值SoundOutput.ToneHz 512 (int)(256.0f * ((real32)StickY / 30000.0f)); 这行代码根据摇杆的 Y 值 (StickY) 动态计算音频的频率 ToneHz。StickY 的值范围是 -32768 到 32767即摇杆的 Y 轴范围。将它除以 30000.0f 来归一化到[-1, 1]然后乘以 256.0f 来决定音频频率变化的幅度。512 是基准频率通过摇杆的上下动作来改变频率。 SoundOutput.WavePeriod SoundOutput.SamplesPerSecond / SoundOutput.ToneHz; 这行代码计算音频波的周期。波周期是根据音频的采样率 (SamplesPerSecond) 和音调频率 (ToneHz) 来决定的。波周期越短频率越高声音听起来越尖锐。 上面的测试中会出现延时的现象键盘按下到音频改变有延时