zoukankan      html  css  js  c++  java
  • hrtf 旋转音效matlab实现

    原理参考:

    http://www.mahong.me/archives/97

    将音频分段,各个段分别使用hrtf在Ls, L, R, Ls, Rrs, Lrs位置处的filter系数。是声音听起来来自Ls, L, R, Rs, Rrs, Lrs,就有旋转效果。

    hrtf = load("E:CIPIC_hrtf_databasestandard_hrir_databasesubject_21hrir_final.mat");

    Ls = [1 9];

    L = [8 9];

    R= [17 9];

    Rs = [25 9];

    Rrs = [17 41];

    Lrs = [8 41];

    %source from 5.1 to L ch

    h_l_l = squeeze(hrtf.hrir_l(L(1), L(2), :));

    h_r_l = squeeze(hrtf.hrir_l(R(1), R(2), :));

    h_ls_l = squeeze(hrtf.hrir_l(Ls(1), Ls(2), :));

    h_rs_l = squeeze(hrtf.hrir_l(Rs(1), Rs(2), :));

    h_lrs_l = squeeze(hrtf.hrir_l(Lrs(1), Lrs(2), :));

    h_rrs_l = squeeze(hrtf.hrir_l(Rrs(1), Rrs(2), :));

    %source from 5.1 to R ch

    h_l_r = squeeze(hrtf.hrir_r(L(1), L(2), :));

    h_r_r = squeeze(hrtf.hrir_r(R(1), R(2), :));

    h_ls_r = squeeze(hrtf.hrir_r(Ls(1), Ls(2), :));

    h_rs_r = squeeze(hrtf.hrir_r(Rs(1), Rs(2), :));

    h_lrs_r = squeeze(hrtf.hrir_r(Lrs(1), Lrs(2), :));

    h_rrs_r = squeeze(hrtf.hrir_r(Rrs(1), Rrs(2), :));

    [input, fs] = wavread('input.wav');

    h_l = zeros(length(h_l_l), 6);

    h_l(:, 1) = h_ls_l;

    h_l(:, 2) = h_l_l;

    h_l(:, 3) = h_r_l;

    h_l(:, 4) = h_rs_l;

    h_l(:, 5) = h_rrs_l;

    h_l(:, 6) = h_lrs_l;

    h_r = zeros(length(h_l_r), 6);

    h_r(:, 1) = h_ls_r;

    h_r(:, 2) = h_l_r;

    h_r(:, 3) = h_r_r;

    h_r(:, 4) = h_rs_r;

    h_r(:, 5) = h_rrs_r;

    h_r(:, 6) = h_lrs_r;

    idx = 0;

    %change to another direction every 2 second (every N samples)

    N = fs * 2;

    %divide audio to loop segment, each segment has N samples

    loop = int32(length(input(:, 1)) / N);

    fadeSize = 1024;

    win = hamming(fadeSize * 2, 'symmetric');

    fadeIn = win(1: fadeSize, 1);

    fadeOut = win(fadeSize + 1 : fadeSize * 2, 1);

    y = zeros(length(input(:, 1)), 2);

    fadeInData = zeros(fadeSize, loop-1, 2);

    fadeOutData = zeros(fadeSize, loop-1, 2);

    fadeOutStartIdx = N - fadeSize;

    outputStartIdx = 1;

    for i = 1:1:loop-1

      idx = mod(i, 6);

      if idx == 0

        idx = 6;  

      end

      %current segment is inputStartIdx ~inputEndIdx

      inputStartIdx = int32((i-1) * N + 1);

      inputEndIdx = int32(i * N);

      pInput = pOutput = zeros(N, 2);

      pInput(:, 1) = input(inputStartIdx : inputEndIdx, 1);

      pInput(:, 2) = input(inputStartIdx : inputEndIdx, 2);

      if i * N < length(input(:, 1))

        %current segment filter with HRTF, which make the sound comes from direction idx.

        pOutput(:, 1) = filter(h_l(:, idx), 1, pInput(:, 1));

        pOutput(:, 2) = filter(h_l(:, idx), 1, pInput(:, 2));

      end

      %fadeIn fadeOut at the begine & end of current segment to avoid pop noise

      fadeInData(: ,i, 1) = pOutput(1: fadeSize, 1) .* fadeIn;

      fadeInData(: ,i, 2) = pOutput(1: fadeSize, 2) .* fadeIn;

      fadeOutData(: ,i, 1) = pOutput(fadeOutStartIdx + 1: N, 1) .* fadeOut;

      fadeOutData(: ,i, 2) = pOutput(fadeOutStartIdx + 1: N, 2) .* fadeOut;

      if i > 1

        %add the cross fade data at the begin & end of segment

        y(outputStartIdx:outputStartIdx + fadeSize-1, 1) = fadeInData(:, i, 1) + fadeOutData(:, i-1, 1);

        y(outputStartIdx:outputStartIdx + fadeSize-1, 2) = fadeInData(:, i, 2) + fadeOutData(:, i-1, 2);

      else

        %the first segment

        y(outputStartIdx:outputStartIdx + fadeSize-1, 1) = fadeInData(:, i, 1) ;

        y(outputStartIdx:outputStartIdx + fadeSize-1, 2) = fadeInData(:, i, 2) ;

      end

      y(outputStartIdx + fadeSize + 1: outputStartIdx + fadeOutStartIdx , 1) = pOutput(fadeSize+1: fadeOutStartIdx, 1);

      y(outputStartIdx + fadeSize + 1: outputStartIdx + fadeOutStartIdx , 2) = pOutput(fadeSize+1: fadeOutStartIdx, 2);

      outputStartIdx = outputStartIdx + fadeOutStartIdx; 

    end

    % low pass filter to avoid pop noise at the begin & end of segment

    wn = 10000 / fs;

    [B, A] = butter(8, wn, 'low');

    y = filter[B, A, y]

    wavwrite(y, fs, 'output.wav');

  • 相关阅读:
    word-wrap与word-break为长单词换行
    background-origin与background-clip的“区别”
    box-shadow
    你不知道的border-radius
    当document.write 遇到外联script
    getAttribute()方法的第二个参数
    Backbone.js入门教程第二版笔记(3)
    Backbone.js入门教程第二版笔记(2)
    php中的字符串常用函数(二) substr() 截取字符串
    php中类和对象的操作
  • 原文地址:https://www.cnblogs.com/fellow1988/p/9846824.html
Copyright © 2011-2022 走看看