【发布时间】:2013-11-09 08:34:34
【问题描述】:
我有以下设置https://sketchfab.com/show/7e2912f5f8794a7b96ef3ac5930e090a(这是一个 3d 查看器,使用鼠标查看所有角度)
盒子有两个非定向驻极体麦克风(黑点)。在地面上,有一些元素像水或类似物(以球体表示)一样落下并产生噪音。最上面,有人在包厢里说话。距离大致准确,所以嘴巴很近。
盒子里面有两个不同的放大器(但相同的驻极体麦克风),有两个不同的放大电路(通常嘴巴的声音更大,并且集成了一些归一化电路。长话短说,我可以把它录制成原始的44100Hz、16Bit、Stereo的音频文件,左声道为上,右声道为下麦克风放大器输出。
目标是 - 即使驻极体麦克风没有定向并且即使有不同的放大器 - 从上部麦克风(面向扬声器)中减去下部麦克风(面向地面)以消除噪音。
我试过(以 Datei 为原始文件名)。这包括一个高通或低通滤波器和一个将最终结果放回原始单声道文件 (%s.neu.raw) 的例程
问题是 - 嗯 - 无法定义的失真。我能听到我的声音,但根本无法忍受。如果您需要样本,我可以上传一个。
编辑:新代码。
static void *substractf( char *Datei)
{
char ergebnis[80];
sprintf(ergebnis,"%s.neu.raw",Datei);
FILE* ausgabe = fopen(ergebnis, "wb");
FILE* f = fopen(Datei, "rb");
if (f == NULL)
return;
double g = 0.1;
double RC = 1.0/(1215*2*3.14);
double dt = 1.0/44100;
double alpha = dt/(RC+dt);
double noise_gain = 18.0;
double voice_gain = 1.0;
struct {
uint8_t noise_lsb;
int8_t noise_msb;
uint8_t voice_lsb;
int8_t voice_msb;
} sample;
while (fread(&sample, sizeof sample, 1, f) == 1)
{
int16_t noise_source = sample.noise_msb * 256 + sample.noise_lsb;
int16_t voice_source = sample.voice_msb * 256 + sample.voice_lsb;
double signal, difference_voice_noise;
difference_voice_noise = voice_gain*voice_source - noise_gain*noise_source;
signal = (1.0 - alpha)*signal + alpha*difference_voice_noise;
putc((char) ( (signed)signal & 0xff),ausgabe);
putc((char) (((signed)signal >> 8) & 0xff),ausgabe);
}
fclose(f);
fclose(ausgabe);
char output[300];
sprintf(output,"rm -frv \"%s\"",Datei);
system(output);
}
【问题讨论】:
-
while(wo !=EOF) { wo = getc(f);是一个小问题。wo需要在getc()之后立即进行 EOF 测试。事先进行测试,让我们wo等于 EOF 进行 1 个循环。 -
@chux 我不明白。它应该是什么样子?
-
while ((c = getc(f)) != EOF) { -
2 个想法:1) 使用
double而不是float。 A/D 转换的声音的保真度约为 20-22 位(浮点数为 23),但有时会注意到各种数学噪声。 2)不是减法,而是加法。有时麦克风的线交叉,您需要在软件中撤消它。 -
另外 2 个想法:1)使用
r-g*l-r(或r+g*l)而不是r - fileter_l。 (做过滤后减法)使用struct { int16_t l,r; } sample; while (fread(sample, sizeof sample, f) > 0) {来简化你正在做的所有字节拼接。
标签: c audio cancellation noise-reduction