Mercurial > hg > camir-aes2014
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/toolboxes/MIRtoolbox1.3.2/AuditoryToolbox/SeneffEar.m Tue Feb 10 15:05:51 2015 +0000 @@ -0,0 +1,118 @@ +function y = SeneffEar(x, fs, plotChannel) + +% Compute the response of Stephanie Seneff's Auditory Model. The +% input waveform x (with sampling rate fs) is converted into fourty +% channels of auditory firing probabilities. +% +% This m-function is based on data from the following paper: +% Benjamin D. Bryant and John D. Gowdy, "Simulation of Stages +% I and II of Seneff's Auditory Model (SAM) Using Matlab", and +% published in the Proceedings of the 1993 Matlab User's Group +% Conference. +% Thanks to Benjamin Bryant for supplying us with his filter +% coefficients and the initial organization of this implementation. + +% (c) 1998 Interval Research Corporation + +global SeneffFS SeneffPreemphasis SeneffFilterBank +global SeneffForward SeneffBackward + +if nargin < 2; fs = 16000; end +if nargin < 3; plotChannel = 0; end + +if exist('SeneffFS') ~= 1 | length(SeneffFS) == 0 | SeneffFS ~= fs + [SeneffPreemphasis, SeneffFilterBank, ... + SeneffForward, SeneffBackward] = SeneffEarSetup(fs); + SeneffFS = fs; +end + +y=soscascade(filter(SeneffPreemphasis, [1], x), ... + SeneffFilterBank); + +[width,channels] = size(SeneffForward); +for j=1:channels + y(j,:) = filter(SeneffForward(:,j),SeneffBackward(:,j),y(j,:)); +end + +if plotChannel > 0 + clf + subplot(4,2,1); + plot(y(plotChannel,:)) + subplot(4,2,2); + f=find(y(plotChannel,:)>max(y(plotChannel,:))/20); + plotStart = max(1,f(1)-10); + plotEnd = min(plotStart+84,length(y(plotChannel,:))); + plot(y(plotChannel,plotStart:plotEnd)); + ylabel('Filter Bank') +end + +% Implement Seneff's detector non-linearity. +hwrA = 10; +hwrB = 65; +hwrG = 2.35; + +y = hwrA*atan(hwrB*max(0,y))+exp(hwrA*hwrB*min(0,y)); +if plotChannel > 0 + subplot(4,2,3); + plot(y(plotChannel,:)) + subplot(4,2,4); + plot(y(plotChannel,plotStart:plotEnd)); + ylabel('HWR'); +end + +% Implement Seneff's short-term adaptation (a reservoir hair cell +% model.) +start_Cn = 442.96875; +Tua = 58.3333/fs; +Tub = 8.3333/fs; + +len = length(x); +Cn = start_Cn*ones(channels,1)*0; % Does this work non zero? +for j=1:len + Sn = y(:,j); + flow = max(0,Tua*(Sn-Cn)); + Cn = Cn + flow - Tub*Cn; + y(:,j) = flow; +end + +% Implement Seneff's Low Pass filter (to model the loss of +% Synchrony. + +lpAlpha = .209611; +lpPoly = poly([lpAlpha lpAlpha lpAlpha lpAlpha]); +Glp = sum(lpPoly); + +for j=1:channels + y(j,:) = filter([Glp],lpPoly,y(j,:)); +end + +if plotChannel > 0 + subplot(4,2,5); + plot(y(plotChannel,:)) + subplot(4,2,6); + plot(y(plotChannel,plotStart:plotEnd)); + ylabel('Adaptation'); +end + +% Finally implement Seneff's Adaptive Gain Control. This computes +% y(n) = y(n)/(1+k y'(n)) +% where y'(n) is a low-pass filtered version of the input. Note, +% this is a single channel AGC. + +initial_yn = 0.23071276; +alpha_agc = 0.979382181; +kagc = 0.002; + +for j=1:channels + averageY(j,:) = filter([0 1-alpha_agc],[alpha_agc],y(j,:),initial_yn); +end +y = y./(1+kagc*averageY); + +if plotChannel > 0 + subplot(4,2,7); + plot(y(plotChannel,:)) + subplot(4,2,8); + plot(y(plotChannel,plotStart:plotEnd)); + ylabel('AGC'); +end +