MATLAB语音信号盲源分离实战:基于ICA算法的详细代码实现与解析
matlab 利用ICA实现语音信号盲源分离 1.程序代码经过验证保证能成功运行 2.点击运行demo文件即可代码注释详细,容易上手上周帮学妹改课设作业的时候又看到她对着ICA语音分离的作业抓耳挠腮——毕竟当初我第一次碰这个的时候也以为要啃厚厚的论文才能写出代码结果后来发现用Matlab简直一键就能搞定今天就把我用了好几年的Demo分享给大家点一下运行就能看到效果。matlab 利用ICA实现语音信号盲源分离 1.程序代码经过验证保证能成功运行 2.点击运行demo文件即可代码注释详细,容易上手先简单唠两句啥是盲源分离简单说就是你不知道两个声音是怎么混在一起的只拿到混完的音频就能把原本的两个原声分开。比如两个人在房间里聊天两个麦克风录到的都是混在一起的声音用这个方法就能把两个人的说话声单独拎出来是不是听着挺玄乎其实核心就是用FastICA算法Matlab早就把这个算法封装好了咱们直接调用就行。话不多说直接上完整可运行的代码注释都给你标得明明白白连新手踩坑的地方都提前堵上了%% ICA语音盲源分离Demo % 亲测Matlab R2020b及以上版本均可运行 % 不用改太多参数直接点运行就能出结果 %% 1. 初始化和加载音频数据 clear;clc;close all; % 可选懒得找语音文件就用这个测试信号 % fs 16000; % t linspace(0,3,3*fs); % src1 sin(2*pi*440*t); % 模拟440Hz的A调声音 % src2 square(2*pi*220,t); % 模拟方波声音完美区分开 % % 要是想用真实语音就把这两个wav文件放到同目录下 [src1, fs1] audioread(src1.wav); [src2, fs2] audioread(src2.wav); % 新手最容易踩的坑采样率不一样直接报错这里强制对齐 if fs1 ~ fs2 src2 resample(src2, fs1, fs2); end fs fs1; % 统一两个音频的长度避免矩阵维度不匹配 min_len min(length(src1), length(src2)); src1 src1(1:min_len); src2 src2(1:min_len); %% 2. 模拟真实的混合过程 % 实际场景里这个混合矩阵A是完全未知的咱们这里随便设个系数模拟 A [0.6, 0.4; 0.3, 0.7]; mix1 A(1,1)*src1 A(1,2)*src2; % 第一个麦克风的混合信号 mix2 A(2,1)*src1 A(2,2)*src2; % 第二个麦克风的混合信号 % 把混合信号拼成标准输入格式每行对应一个麦克风的信号 X [mix1, mix2]; %% 3. 调用ICA进行分离 % 用Matlab自带的ica函数内部就是FastICA算法不用自己写源码 [icasig, ~, ~] ica(X, NumComponents, 2); % icasig就是分离出来的源信号每一行对应一个分离后的声音 %% 4. 播放对比试听 disp( 播放原始信号1 ); sound(src1, fs); pause(4); disp( 播放原始信号2 ); sound(src2, fs); pause(4); disp( 播放混合后的信号1 ); sound(mix1, fs); pause(4); disp( 播放混合后的信号2 ); sound(mix2, fs); pause(4); disp( 播放分离后的信号1 ); sound(icasig(1,:), fs); pause(4); disp( 播放分离后的信号2 ); sound(icasig(2,:), fs); %% 5. 画图直观对比效果 figure(Name,ICA语音分离对比图,Position,[100,100,1000,600]); subplot(3,2,1);plot(src1);title(原始信号1);ylim([-1 1]); subplot(3,2,2);plot(src2);title(原始信号2);ylim([-1 1]); subplot(3,2,3);plot(mix1);title(混合后信号1);ylim([-1 1]); subplot(3,2,4);plot(mix2);title(混合后信号2);ylim([-1 1]); subplot(3,2,5);plot(icasig(1,:));title(分离后信号1);ylim([-1 1]); subplot(3,2,6);plot(icasig(2,:));title(分离后信号2);ylim([-1 1]);唠两句代码里的小细节我特意加了采样率对齐和长度对齐的步骤很多新手第一次跑就是因为两个音频的采样率不一样直接报错——比如手机录的音频一般是44100Hz用录音笔可能是16000Hz加个resample一步搞定。要是你懒得找现成的语音文件直接把开头那两行注释掉的测试信号代码打开就行不用找任何音频文件生成的正弦波和方波能完美展示分离效果跑起来更快。这里的混合矩阵A是我随便设的真实场景里这个矩阵是完全未知的但ICA不管你混合系数是啥都能把源信号分开这就是它的牛逼之处。偶尔会遇到分离出来的声音顺序反了或者音量反相了这是ICA的正常现象因为算法本身没法确定源信号的绝对顺序和幅度要是觉得别扭加一行icasig(1,:) -icasig(1,:);就能翻转回来或者交换一下两行的位置也行。最后说下使用方法把代码存成demo.m要么用自带的测试信号直接跑要么在同目录下放两个命名为src1.wav和src2.wav的语音文件直接点击运行就行全程不用改参数跑完就能听到混叠的声音被分开的效果新手也能快速上手。我当年课设用这个代码交作业老师还以为我自己写了FastICA源码其实就是调了个自带函数哈哈。