波达方向估计DOA

本文聚焦于语音增强中的波达方向估计,特别是GCC算法的应用。作者使用双麦克风阵列(8cm间距)实现了C语言版本的GCC算法,尽管代码初级,但能稳定工作,角度误差约20°,旨在助力语音信号处理。
摘要由CSDN通过智能技术生成

最近一直致力于语音增强方面的工作,主要是增强目标位置发出的语音信号,削弱环境噪音。这里面最有效的方法就是波达方向估计和波束增强了。本篇主要介绍波达方向估计,其包含很多种算法:capon music  RSS GCC等。我这里主要是使用GCC算法,我的麦克阵列使用的是双麦克,8cm距离。以下是我写的C语言版本,由于是第一版,所以比较粗糙,不过性能还是稳定的,角度误差在20°左右,希望能帮到大家:

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include<string.h>
#include<fftw3.h>
#include<math.h>
#include"tool_spline.h"


#define PI 3.1416

typedef struct PCM PCM;
typedef struct Matrix Matrix;
typedef struct X X;
typedef struct conj_X conj_X;
typedef struct max_index max_index;
typedef struct doa_res doa_res;

// 读取文件后,文件内容和文件长度
struct PCM {
	int* data;
	int length;
};

// 把两个麦克的数据组成矩阵
struct Matrix {
	int * m[2];
	int length;
};
// fft变换后,二维的频率数据
struct X {
	fftw_complex* x[2];
};
// X数据的复数共轭
struct conj_X {
	fftw_complex* x[2];
};
// 求取最大值和最大值的索引
struct max_index {
	double data;
	int index;
};
// 最终角度的数据和长度
struct doa_res {
	double* data;
	int n_blocks;
};

// 读取文件
PCM readPCM(char* file_path) {
	FILE* file;
	const int  MAX_END = 2;
	const int  MAX_START = 0;

	file = fopen(file_path, "rb");
	if (file == NULL) {
		printf("open file failed. file_path is :%s\n", file_path);
		PCM cur_pcm = { NULL,0 };
		return cur_pcm;
	}

	fseek(file, 0L, MAX_END);
	int file_len = ftell(file);
	unsigned char* origin_data = (unsigned char*)malloc(file_len + 1);
	int* data = (int*)calloc(file_len / 2, sizeof(int));
	fseek(file, 0L, MAX_START);

	fread((char*)origin_data, 1, file_len, file);

	origin_data[file_len] = '\0'; // 空字符,表示字符串的结束
	int count = 0;
	for (int i = 0; i < file_len - 1; i += 2) {
		data[count++] = (int)((origin_data[i + 1] << 8) | origin_data[i]);
	}

	fclose(file);
	free(origin_data);
	origin_data = NULL;
	struct PCM cur_pcm = { data, file_len / 2 };
	return cur_pcm;
}


// 合成二维矩阵
Matrix getMatrix(char* file_path1, char* file_path2) {
	PCM data1 = readPCM(file_path1);
	PCM data2 = readPCM(file_path2);
	

	// 如果两个pcm文件长度不同,我们以短的作为标准
	if (data1.length > data2.length) {
		data1.length = data2.length;
	}
	else if (data1.length < data2.length) {
		data2.length = data1.length;
	}

	Matrix cur_m;
	for (int i = 0; i < 2; i++) {
		cur_m.m[i] = (int*)calloc(data1.length , sizeof(int));
	}

	memcpy(cur_m.m[0], data1.data, data1.length*sizeof(int));
	memcpy(cur_m.m[1], data2.data, data1.length*sizeof(int));
	cu
  • 2
    点赞
  • 56
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值