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

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