如何在卷积方程中定义参数?

时间:2017-03-21 00:09:39

标签: matlab audio mono signal-processing convolution

我正在尝试使用内置的conv函数计算声音信号的卷积,而不是,而是使用数组。 x是输入信号,h是脉冲响应。但是,当我运行其他主要功能来调用my_conv时,我收到了这些错误:

Undefined function or variable 'nx'.**

Error in my_conv (line 6)
ly=nx+nh-1;

Error in main_stereo (line 66)
leftchannel = my_conv(leftimp, mono); % convolution of left ear impulse response and mono

这是我的函数my_conv

function [y]=my_conv(x,h)
  x=x(:);
  h=h(:);
  lx=length(x);
  lh=length(h);
  ly=nx+nh-1; 
  Y=zeros(nh,ny);
  for i =1:nh
    Y((1:nx)+(i-1),i)=x;
  end
  y=Y*h; 

我应该做些什么更改来修复这些错误并让这段代码运行?

我正在尝试将函数实现到此代码中:

input_filename = 'speech.wav'; 
stereo_filename = 'stereo2.wav'; 
imp_filename = 'H0e090a.dat';
len_imp = 128; 
fp = fopen(imp_filename, 'r', 'ieee-be'); 
data = fread(fp, 2*len_imp, 'short');
fclose(fp); 
[mono,Fs] = audioread(input_filename); 
if (Fs~=44100)
end
len_mono = length(mono); 


leftimp  = data(1:2:2*len_imp); 
rightimp = data(2:2:2*len_imp); 
leftchannel  = my_conv(leftimp, mono); 
rightchannel = my_conv(rightimp, mono);

leftchannel  = reshape(leftchannel , length(leftchannel ), 1); 
rightchannel = reshape(rightchannel, length(rightchannel), 1); 
norml = max(abs([leftchannel; rightchannel]))*1.05; 
audiowrite(stereo_filename,  [leftchannel rightchannel]/norml, Fs);

1 个答案:

答案 0 :(得分:0)

正如@ SardarUsama在评论中指出的那样,错误

Undefined function or variable 'nx'.
Error in my_conv (line 6) ly=nx+nh-1;

告诉您,变量nx之前尚未在行ly=nx+nh-1上使用之前定义。鉴于变量的命名及其用法,看起来你打算做的是:

nx = length(x);
nh = length(h);
ny = nx+nh-1; 

进行这些修改并解决第一个错误后,您可能会收到另一个错误消息

error: my_conv: operator *: nonconformant arguments

此错误是由Y矩阵的指定大小的反转引起的。这可以通过使用Y初始化Y = zeros(ny, nh);来解决。生成的my_conv函数如下:

function [y]=my_conv(x,h)
  nx=length(x);
  nh=length(h);
  ny=nx+nh-1; 

  Y=zeros(ny,nh);
  for i =1:nh
    Y((1:nx)+(i-1),i)=x;
  end
  y=Y*h;

注意,在矩阵Y中存储一个输入向量的每个可能的移位以计算卷积作为矩阵乘法不是非常有效的存储器(需要O(NM)存储)。更高效的内存实现将直接计算输出向量的每个元素:

function [y]=my_conv(x,h)
  nx=length(x);
  nh=length(h);
  if (nx < nh)
    y = my_conv(h,x);
  else
    ny=nx+nh-1; 

    y = zeros(1,ny);
    for i =1:ny
      idh = [max(i-(ny-nh),1):min(i,nh)]
      idx = [min(i,nx):-1:max(nx-(ny-i),1)]
      y(i) = sum(x(idx).*h(idh));
    end
  end

对于大型数组而言,计算效率更高的替代实现可以使用convolution theorem并使用Fast Fourier Transform (FFT)

function [y]=my_conv2(x,h)
  nx=length(x);
  nh=length(h);
  ny=nx+nh-1; 

  if (size(x,1)>size(x,2))
    x = transpose(x);
  end
  if (size(h,1)>size(h,2))
    h = transpose(h);
  end
  Xf = fft([x zeros(size(x,1),ny-nx)]);
  Hf = fft([h zeros(size(h,1),ny-nh)]);

  y = ifft(Xf .* Hf);