TAG: rnnoise
最近看了一个关于rnn语音增强算法的项目,想到机器人听觉可能会需要语音降噪方面的算法,于是一时兴起搞了一下。除噪效果还是很明显的。 采用的是 GRU/LSTM 模型。项目地址为:rnnoise 我们可以考虑采用用作者训练的模型来构建数据集,也可以自己根据上面项目工程的地址按照步骤自己训练模型供自己调用,具体的请自己开发。 但是目前作者提供的只是一个仅支持48K采样率的音频数据。 不过测了一下16k的,可以用但是效果可能没有48k性能好。 下面给出封装成ros节点的rnnoise的算法,其实这种方法我并不推荐的,我感觉要把降噪放在最前端的位置,就是麦克风拾音那个位置上,把该项目可以封装成一个共享库,供自己调用。这个要看每个人开发的习惯而言。 由于只是尝试一下该算法的调用,故给出在ros中的调用示例如下: void Callback(const jack_msgs::JackAudio::ConstPtr& msg) { // int16_t* outputS16 = (int16_t*)malloc(sizeof(int16_t) * msg->size); int data_length = msg->size; int16_t* outputS16 = (int16_t*)malloc(sizeof(int16_t) * data_length); int k=0; printf("%d\n",data_length); short in_shorts[data_length]; short in_shorts1[data_length]; // DenoiseState* st = rnnoise_create(); float flag = 0; float processFrame[data_length]; char outFile[256] = "rnnoise.wav"; DenoiseState* st = rnnoise_create(); printf("***********"); for(int i=0; i<data_length; i++){ processFrame[i] = (msg->data[i] * 65535); } flag = rnnoise_process_frame(st, processFrame, processFrame); for (size_t i = 0; i < data_length; i++) { in_shorts[i] = (short)processFrame[i]; } rnnoise_destroy(st); } int main(int argc, char **argv) { ros::init(argc, argv, "rnnoise"); ros::NodeHandle n; printf("aaaaaaaaaaaa"); // DenoiseState* st = rnnoise_create(); ros::Subscriber Sub = n.subscribe("/jackaudio", 1000, Callback); std_msgs::String msg; signal( SIGINT, sig_handler ); ros::spin(); } 可以看出还是挺简单的,但是实际操作中并不会使用48k采样率的音频输入,因此下面给出冲采样的过程,添加上以后会实现所有采样率都支持的情况,根据需要添加。 void resampleData(const int16_t *sourceData, int32_t sampleRate, uint32_t srcSize, int16_t *destinationData, int32_t newSampleRate) { if (sampleRate == newSampleRate) { memcpy(destinationData, sourceData, srcSize * sizeof(int16_t)); return; } uint32_t last_pos = srcSize - 1; uint32_t dstSize = (uint32_t) (srcSize * ((float) newSampleRate / sampleRate)); for (uint32_t idx = 0; idx < dstSize; idx++) { float index = ((float) idx * sampleRate) / (newSampleRate); uint32_t p1 = (uint32_t) index; float coef = index - p1; uint32_t p2 = (p1 == last_pos) ? last_pos : p1 + 1; destinationData[idx] = (int16_t) ((1.0f - coef) * sourceData[p1] + coef * sourceData[p2]); } } 可以在除噪算法中添加上面的函数,具体请参考以下: resampleData(data_in, in_sampleRate, (uint32_t) in_size, data_out, out_sampleRate); resampleData(data_out, out_sampleRate, (uint32_t) out_size, data_in, in_sampleRate); (qq_37082966) |