annotate toolboxes/MIRtoolbox1.3.2/AuditoryToolbox/SeneffEar.m @ 0:cc4b1211e677 tip

initial commit to HG from Changeset: 646 (e263d8a21543) added further path and more save "camirversion.m"
author Daniel Wolff
date Fri, 19 Aug 2016 13:07:06 +0200
parents
children
rev   line source
Daniel@0 1 function y = SeneffEar(x, fs, plotChannel)
Daniel@0 2
Daniel@0 3 % Compute the response of Stephanie Seneff's Auditory Model. The
Daniel@0 4 % input waveform x (with sampling rate fs) is converted into fourty
Daniel@0 5 % channels of auditory firing probabilities.
Daniel@0 6 %
Daniel@0 7 % This m-function is based on data from the following paper:
Daniel@0 8 % Benjamin D. Bryant and John D. Gowdy, "Simulation of Stages
Daniel@0 9 % I and II of Seneff's Auditory Model (SAM) Using Matlab", and
Daniel@0 10 % published in the Proceedings of the 1993 Matlab User's Group
Daniel@0 11 % Conference.
Daniel@0 12 % Thanks to Benjamin Bryant for supplying us with his filter
Daniel@0 13 % coefficients and the initial organization of this implementation.
Daniel@0 14
Daniel@0 15 % (c) 1998 Interval Research Corporation
Daniel@0 16
Daniel@0 17 global SeneffFS SeneffPreemphasis SeneffFilterBank
Daniel@0 18 global SeneffForward SeneffBackward
Daniel@0 19
Daniel@0 20 if nargin < 2; fs = 16000; end
Daniel@0 21 if nargin < 3; plotChannel = 0; end
Daniel@0 22
Daniel@0 23 if exist('SeneffFS') ~= 1 | length(SeneffFS) == 0 | SeneffFS ~= fs
Daniel@0 24 [SeneffPreemphasis, SeneffFilterBank, ...
Daniel@0 25 SeneffForward, SeneffBackward] = SeneffEarSetup(fs);
Daniel@0 26 SeneffFS = fs;
Daniel@0 27 end
Daniel@0 28
Daniel@0 29 y=soscascade(filter(SeneffPreemphasis, [1], x), ...
Daniel@0 30 SeneffFilterBank);
Daniel@0 31
Daniel@0 32 [width,channels] = size(SeneffForward);
Daniel@0 33 for j=1:channels
Daniel@0 34 y(j,:) = filter(SeneffForward(:,j),SeneffBackward(:,j),y(j,:));
Daniel@0 35 end
Daniel@0 36
Daniel@0 37 if plotChannel > 0
Daniel@0 38 clf
Daniel@0 39 subplot(4,2,1);
Daniel@0 40 plot(y(plotChannel,:))
Daniel@0 41 subplot(4,2,2);
Daniel@0 42 f=find(y(plotChannel,:)>max(y(plotChannel,:))/20);
Daniel@0 43 plotStart = max(1,f(1)-10);
Daniel@0 44 plotEnd = min(plotStart+84,length(y(plotChannel,:)));
Daniel@0 45 plot(y(plotChannel,plotStart:plotEnd));
Daniel@0 46 ylabel('Filter Bank')
Daniel@0 47 end
Daniel@0 48
Daniel@0 49 % Implement Seneff's detector non-linearity.
Daniel@0 50 hwrA = 10;
Daniel@0 51 hwrB = 65;
Daniel@0 52 hwrG = 2.35;
Daniel@0 53
Daniel@0 54 y = hwrA*atan(hwrB*max(0,y))+exp(hwrA*hwrB*min(0,y));
Daniel@0 55 if plotChannel > 0
Daniel@0 56 subplot(4,2,3);
Daniel@0 57 plot(y(plotChannel,:))
Daniel@0 58 subplot(4,2,4);
Daniel@0 59 plot(y(plotChannel,plotStart:plotEnd));
Daniel@0 60 ylabel('HWR');
Daniel@0 61 end
Daniel@0 62
Daniel@0 63 % Implement Seneff's short-term adaptation (a reservoir hair cell
Daniel@0 64 % model.)
Daniel@0 65 start_Cn = 442.96875;
Daniel@0 66 Tua = 58.3333/fs;
Daniel@0 67 Tub = 8.3333/fs;
Daniel@0 68
Daniel@0 69 len = length(x);
Daniel@0 70 Cn = start_Cn*ones(channels,1)*0; % Does this work non zero?
Daniel@0 71 for j=1:len
Daniel@0 72 Sn = y(:,j);
Daniel@0 73 flow = max(0,Tua*(Sn-Cn));
Daniel@0 74 Cn = Cn + flow - Tub*Cn;
Daniel@0 75 y(:,j) = flow;
Daniel@0 76 end
Daniel@0 77
Daniel@0 78 % Implement Seneff's Low Pass filter (to model the loss of
Daniel@0 79 % Synchrony.
Daniel@0 80
Daniel@0 81 lpAlpha = .209611;
Daniel@0 82 lpPoly = poly([lpAlpha lpAlpha lpAlpha lpAlpha]);
Daniel@0 83 Glp = sum(lpPoly);
Daniel@0 84
Daniel@0 85 for j=1:channels
Daniel@0 86 y(j,:) = filter([Glp],lpPoly,y(j,:));
Daniel@0 87 end
Daniel@0 88
Daniel@0 89 if plotChannel > 0
Daniel@0 90 subplot(4,2,5);
Daniel@0 91 plot(y(plotChannel,:))
Daniel@0 92 subplot(4,2,6);
Daniel@0 93 plot(y(plotChannel,plotStart:plotEnd));
Daniel@0 94 ylabel('Adaptation');
Daniel@0 95 end
Daniel@0 96
Daniel@0 97 % Finally implement Seneff's Adaptive Gain Control. This computes
Daniel@0 98 % y(n) = y(n)/(1+k y'(n))
Daniel@0 99 % where y'(n) is a low-pass filtered version of the input. Note,
Daniel@0 100 % this is a single channel AGC.
Daniel@0 101
Daniel@0 102 initial_yn = 0.23071276;
Daniel@0 103 alpha_agc = 0.979382181;
Daniel@0 104 kagc = 0.002;
Daniel@0 105
Daniel@0 106 for j=1:channels
Daniel@0 107 averageY(j,:) = filter([0 1-alpha_agc],[alpha_agc],y(j,:),initial_yn);
Daniel@0 108 end
Daniel@0 109 y = y./(1+kagc*averageY);
Daniel@0 110
Daniel@0 111 if plotChannel > 0
Daniel@0 112 subplot(4,2,7);
Daniel@0 113 plot(y(plotChannel,:))
Daniel@0 114 subplot(4,2,8);
Daniel@0 115 plot(y(plotChannel,plotStart:plotEnd));
Daniel@0 116 ylabel('AGC');
Daniel@0 117 end
Daniel@0 118