gpt4 book ai didi

c - 在 2ch PCM 上添加 440HZ 音调(合并 PCM,噪声叠加)

转载 作者:行者123 更新时间:2023-12-04 05:02:03 25 4
gpt4 key购买 nike

我想添加一些噪音

44100 Hz
2 channel
16 bit
interleaved PCM

我正在生成 1 秒的 440Hz 噪声并将其存储在噪声缓冲区中:
#define SAMPLING_RATE 44100
int *noise_buffer;

void generate_440(int *buffer) {
int pos; // sample number we're on
float volume = 0.1; // 0 to 1.0, one being the loudest

for (pos = 0; pos < SAMPLING_RATE; pos++) {
float a = (2 * 3.14159) * pos / (SAMPLING_RATE / 440.0);
float v = sin(a) * volume;

// convert from [-1.0,1.0] to [-32768,32767]:
buffer[pos] = remap_level_to_signed_16_bit(v);
}
}
..
noise_buffer = (int *) malloc(SAMPLING_RATE * sizeof(int));
generate_440(noise_buffer);

并以这种方式将其添加到我的 PCM 流中:
int count = read(file_fd, buffer, len);
int bytesPerSample = 4;
int samples = count / bytesPerSample, c, currentSample;
for (currentSample = 0; currentSample < samples; currentSample++) {
samplesWritten++;
memcpy(buffer+(currentSample * bytesPerSample), noise_buffer+((samplesWritten%SAMPLING_RATE)), bytesPerSample);
}

这有效,但它取代了 buffer 中的原始 PCM带有(响亮的)440Hz 音调。

然后尝试将原始 PCM 与噪声“合并”,这样就可以以这种方式(而不是 memcpy)听到带有噪声覆盖的原始音频:
for (c = 0; c < bytesPerSample; c++) {
*(buffer+(currentSample * bytesPerSample) + c)=(*(buffer+(currentSample * bytesPerSample) + c)+*(noise_buffer+((samplesWritten%SAMPLING_RATE)) + c)) / 2;
}

但它会产生一种奇怪的声音。我认为问题与 2 个 channel 有关?遗憾的是,我还不熟悉音频数据。

有人可以帮助我或将我推向正确的方向吗?

最佳答案

这是我添加两个信号的方法:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <limits.h>

#define SAMPLING_RATE 44100

int remap_level_to_signed_16_bit(float v)
{
if (v >= 1)
return 32767;

if (v <= -1)
return -32767;

return v * 32767;
}

void generate_freq(int *buffer, size_t count, float volume, float freq)
{
size_t pos; // sample number we're on

for (pos = 0; pos < count; pos++) {
float a = 2 * 3.14159f * freq * pos / SAMPLING_RATE;
float v = sin(a) * volume;
// convert from [-1.0,1.0] to [-32767,32767]:
buffer[pos] = remap_level_to_signed_16_bit(v);
}
}

void generate_noise(int *buffer, size_t count, float volume)
{
size_t pos; // sample number we're on

for (pos = 0; pos < count; pos++) {
// random number [-1.0,1.0]
float v = (rand() - RAND_MAX / 2.0f) * 2 / RAND_MAX * volume;
// convert from [-1.0,1.0] to [-32767,32767]:
buffer[pos] = remap_level_to_signed_16_bit(v);
}
}

int add_two_16_bit_samples(int a, int b)
{
int sum;

// add a and b avoiding overflow
if (a >= 0 && b >= 0) {
if (a > INT_MAX - b) // mathematically equivalent to if (a + b > INT_MAX)
sum = INT_MAX; // limit sum at INT_MAX if overflow
else
sum = a + b;
} else if (a < 0 && b < 0) {
if (a < INT_MIN - b) // mathematically equivalent to if (a + b < INT_MIN)
sum = INT_MIN; // limit sum at INT_MIN if overflow
else
sum = a + b;
} else {
sum = a + b;
}

// limit sum to [-32767,32767]
if (sum > 32767)
sum = 32767;

if (sum < -32767)
sum = -32767;

return sum;
}

void add_16_bit_samples(int *destination, const int* source, size_t count)
{
for (; count--; destination++, source++) {
*destination = add_two_16_bit_samples(*destination, *source);
}
}

int save_16_bit_samples(const char* name, int* buf, size_t count, int stereo)
{
FILE* f = fopen(name, "wb");
int res = -1; // failure by default

if (f != NULL) {

while (count) {
// convert sample to 2's complement unsigned representation
unsigned v = *buf++;

// separate it into 8-bit parts
unsigned char c[2];
c[0] = v & 0xFF; // LSB
c[1] = (v >> 8) & 0xFF; // MSB

// save it as little endian
if (fwrite(c, 1, 2, f) != 2)
break;

// do once more if stereo
if (stereo)
if (fwrite(c, 1, 2, f) != 2)
break;

count--;
}

if (count == 0)
res = 0; // success if all samples written out

fclose(f);
}

return res;
}

int main(void)
{
int* buf_440 = malloc(SAMPLING_RATE * sizeof(int));
int* buf_noise = malloc(SAMPLING_RATE * sizeof(int));

if (buf_440 == NULL || buf_noise == NULL) {
printf("failed to allocate memory for samples\n");
return EXIT_FAILURE;
}

generate_freq(buf_440, SAMPLING_RATE, 0.1f/*volume*/, 440.0f/*freq*/);
generate_noise(buf_noise, SAMPLING_RATE, 0.01f/*volume*/);

add_16_bit_samples(buf_440, buf_noise, SAMPLING_RATE);

if (save_16_bit_samples("440noise.pcm", buf_440, SAMPLING_RATE, 1/*stereo*/)) {
printf("failed to save samples to file\n");
return EXIT_FAILURE;
}

return EXIT_SUCCESS;
}

关于c - 在 2ch PCM 上添加 440HZ 音调(合并 PCM,噪声叠加),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16033718/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com