function featureVector = extractSpeechFeatures(x)
%extractSpeechFeatures Extract multiple features from batch audio
%   featureVector = extractSpeechFeatures(audioIn) returns audio features
%   extracted from audioIn.
%
%   Parameters of the audioFeatureExtractor used to generate this
%   function must be honored when calling this function.
%    - Sample rate of the input should be 16000 Hz.
%
%
%      % EXAMPLE 1: Extract features
%        source = dsp.ColoredNoise("SamplesPerFrame",16000);
%        for ii = 1:10
%            audioIn = source();
%            featureArray = extractSpeechFeatures(audioIn);
%            % ... do something with featureArray ...
%        end
%
%
%      % EXAMPLE 2: Generate code
%        targetDataType = "single";
%        codegen extractSpeechFeatures -args {ones(16000,1,targetDataType)}
%        source = dsp.ColoredNoise("SamplesPerFrame",16000, ...
%                                  "OutputDataType",targetDataType);
%        for ii = 1:10
%            audioIn = source();
%            featureArray = extractSpeechFeatures_mex(audioIn);
%            % ... do something with featureArray ...
%        end
%
%   See also audioFeatureExtractor, dsp.AsyncBuffer, codegen.

%   Generated by audioFeatureExtractor on 14-Jan-2021 15:01:10 -0500
%#codegen

dataType = class(x);
[numSamples,numChannels] = size(x);

props = coder.const(getProps(dataType));

persistent config outputIndex
if isempty(config)
    [config, outputIndex] = coder.const(@getConfig,dataType,props);
end

% Preallocate feature vector
numHops = floor((numSamples-numel(props.Window))/(numel(props.Window) - props.OverlapLength)) + 1;
featureVector = coder.nullcopy(zeros(numHops,props.NumFeatures,numChannels,dataType));

% Short-time Fourier transform
Y = stft(x,"Window",props.Window,"OverlapLength",props.OverlapLength,"FFTLength",props.FFTLength,"FrequencyRange","onesided");
Z = reshape(Y,[],numHops*numChannels);
Zpower = real(Z.*conj(Z));

% Bark spectrum
barkSpectrum = reshape(config.barkSpectrum.FilterBank*Zpower,[],numHops,numChannels);
featureVector(:,outputIndex.barkSpectrum,:) = permute(barkSpectrum,[2,1,3]);
end

function props = getProps(dataType)
props.Window = cast([0;6.1683759169706142699851625366136e-05;0.00024671981713419999238112723105587;0.00055506251901499270573481226165313;0.00098663578586422051586168890935369;0.0015413331334360180768783266103128;0.0022190176984600018528226428315975;0.0030195222724101467015600519516738;0.0039426493427610620479129011073383;0.0049881711417212315495817165356129;0.0061558297024311148248898462043144;0.0074453369226130661218121531419456;0.008856374635655639426801144509227;0.010388594689117125469124403025489;0.012041619030626282693674511392601;0.013815039801161721477740229602205;0.015708419435684461973323777783662;0.017721290771100961514150640141452;0.019853157161528467433697642263724;0.022103492600834939718623672888498;0.024471741852423234409030783353955;0.026957320586227351277841535193147;0.029559615522887272565100147403427;0.032277984585066366030048357060878;0.035111757055874270871953513051267;0.038060233744356630758431947469944;0.0411226871580094299751806374843;0.044298361682277354045567108187242;0.047586473766990267098009326218744;0.050986212119692175814833490221645;0.054496737905816050595575461557019;0.058117184955653267142139384304755;0.06184665997806820803006644382549;0.06568424278090440049382436882297;0.069628986498028178075969663041178;0.073679917822953855388590227448731;0.077836037248992462345142939739162;0.082096319315864862975473670303472;0.086459712862719084736085051190457;0.090925141287488298047492207842879;0.095491502812526274368565282202326;0.10015767075645470862710340043122;0.10492249381215479342444041321869;0.10978479633083509936497534908995;0.11474337861210537337086634579464;0.11979701719998453457449727466155;0.12494446518477025920290657268197;0.13018445251069510337771362173953;0.13551568628929422377638047692017;0.14093685111840553725315317024069;0.14644660940672621363134453531529;0.15204360170384284556277521005541;0.15772644703565563695235596242128;0.16349374324511334322096445248462;0.16934406733817408685638383758487;0.17527597583490822641394402126025;0.18128800512565518276986153978214;0.1873786718321473476756011677935;0.19354647317351170165977691794978;0.1997898873370579364561194779526;0.20610737385376343144827160358545;0.21249737397836071517431832944567;0.21895831107393470826849579680129;0.22548859100093410212650724133709;0.23208660251050172718123576487415;0.23875071764202554502887210219342;0.24547929212481439664728100069624;0.25227066578379619965488700472633;0.25912316294914239378499587473925;0.26603509286971327441051471396349;0.27300475013022657000405502003559;0.28003041507204240456729849029216;0.28711035421746367024553592273151;0.29424282069744556178392258516396;0.3014260546826097453276815940626;0.30865828381745508135480804412509;0.31593772365766092935501774263685;0.32326257811037140132981448914506;0.33063103987735426025906804170518;0.33804129090092527309963088555378;0.34549150281252627436856528220233;0.35297983738384808294341610235278;0.36050444698038525137562260169943;0.36806347501731351279374848672887;0.37565505641757251931167616021412;0.38327731807204723502024990011705;0.39092837930172863458722076757113;0.39860635232174373987490412218904;0.40630934270713764400184686564899;0.4140354498602952237895635789755;0.42178276747988452388682389937458;0.42954938403120868084528183317161;0.43733338321784787083856826939154;0.44513284445447742765367138417787;0.45294584334074272646830650046468;0.46077045213607747964346117441892;0.4686047402353432644872555101756;0.47644677464517865006499164337583;0.4842946204609357985226836262882;0.49214634134408968835217024206941;0.49999999999999994448884876874217;0.50785365865591025613667852667277;0.51570537953906414596616514245397;0.52355322535482129442385712536634;0.5313952597646567355127444898244;0.53922954786392240933423636306543;0.54705415665925716250939103701967;0.55486715554552257234632861582213;0.56266661678215212916143173060846;0.57045061596879131915471816682839;0.57821723252011547611317610062542;0.58596455013970483172158765228232;0.59369065729286241150930436560884;0.60139364767825609359164218403748;0.60907162069827114336817430739757;0.61672268192795254293514517485164;0.6243449435824273141548701460124;0.63193652498268626516164658823982;0.63949555301961458209092370452709;0.64702016261615191705658389764722;0.65450849718747372563143471779767;0.66195870909907461587806665193057;0.669368960122645684229780727037;0.67673742188962848764788304833928;0.6840622763423389596226797948475;0.69134171618254480762288949335925;0.6985739453173902546723184059374;0.70575717930255432719377495232038;0.71288964578253632975446407726849;0.71996958492795759543270150970784;0.72699524986977337448479374870658;0.73396490713028661456718282352085;0.7408768370508577172373065877764;0.74772933421620380034511299527367;0.75452070787518565886387023056159;0.76124928235797439945997666654876;0.76791339748949849486336916015716;0.77451140899906589787349275866291;0.78104168892606518070920174068306;0.78750262602163911829222797678085;0.79389262614623645752942593389889;0.80021011266294195252157805953175;0.80645352682648807629561815701891;0.81262132816785248579094513843302;0.81871199487434487274128969147569;0.82472402416509171807490474748192;0.83065593266182591314361616241513;0.83650625675488654575673308499972;0.84227355296434436304764403757872;0.84795639829615709892607355868677;0.85355339059327373085750423342688;0.85906314888159429621339313598583;0.86448431371070566520131706056418;0.86981554748930489662228637826047;0.87505553481522979630824465857586;0.88020298280001540991435149408062;0.88525662138789451560683119168971;0.89021520366916495614617588216788;0.89507750618784520657555958678131;0.89984232924354523586174536831095;0.90450849718747372563143471779767;0.90907485871251181297481025467278;0.91354028713728097077506618006737;0.91790368068413497049107263592305;0.92216396275100742663255459774518;0.92632008217704608910025854129344;0.93037101350197182192403033695882;0.9343157572190955439950243999192;0.93815334002193173645878232491668;0.94188281504434678836901184695307;0.94550326209418389389327330718515;0.94901378788030776867401527852053;0.95241352623300967739083944252343;0.95570163831772259044328166055493;0.95887731284199051451366813125787;0.96193976625564336924156805253006;0.96488824294412567361689525569091;0.96772201541493363396995164293912;0.9704403844771127829460510838544;0.97304267941377264872215846480685;0.97552825814757682110212044790387;0.97789650739916500477022509585368;0.98014684283847153256630235773628;0.98227870922889903848584935985855;0.98429158056431553802667622221634;0.9861849601988382785222597703978;0.9879583809693737173063254886074;0.98961140531088287453087559697451;0.99114362536434430506204762423295;0.99255466307738693387818784685805;0.99384417029756888517511015379569;0.99501182885827876845041828346439;0.99605735065723888244093586763483;0.9969804777275897977872887167905;0.9977809823015399981471773571684;0.99845866686656403743427290464751;0.99901336421413577948413831109065;0.99944493748098495178311395648052;0.99975328018286580000761887276894;0.99993831624083029385730014837463;1;0.99993831624083029385730014837463;0.99975328018286580000761887276894;0.99944493748098495178311395648052;0.99901336421413577948413831109065;0.99845866686656403743427290464751;0.9977809823015399981471773571684;0.9969804777275897977872887167905;0.99605735065723888244093586763483;0.99501182885827876845041828346439;0.99384417029756888517511015379569;0.99255466307738693387818784685805;0.99114362536434430506204762423295;0.98961140531088287453087559697451;0.9879583809693737173063254886074;0.9861849601988382785222597703978;0.98429158056431553802667622221634;0.98227870922889903848584935985855;0.98014684283847153256630235773628;0.97789650739916500477022509585368;0.97552825814757682110212044790387;0.97304267941377264872215846480685;0.9704403844771127829460510838544;0.96772201541493363396995164293912;0.96488824294412567361689525569091;0.96193976625564336924156805253006;0.95887731284199051451366813125787;0.95570163831772259044328166055493;0.95241352623300967739083944252343;0.94901378788030776867401527852053;0.94550326209418389389327330718515;0.94188281504434678836901184695307;0.93815334002193173645878232491668;0.9343157572190955439950243999192;0.93037101350197182192403033695882;0.92632008217704608910025854129344;0.92216396275100742663255459774518;0.91790368068413497049107263592305;0.91354028713728097077506618006737;0.90907485871251181297481025467278;0.90450849718747372563143471779767;0.89984232924354523586174536831095;0.89507750618784520657555958678131;0.89021520366916495614617588216788;0.88525662138789451560683119168971;0.88020298280001540991435149408062;0.87505553481522979630824465857586;0.86981554748930489662228637826047;0.86448431371070566520131706056418;0.85906314888159429621339313598583;0.85355339059327373085750423342688;0.84795639829615709892607355868677;0.84227355296434436304764403757872;0.83650625675488654575673308499972;0.83065593266182591314361616241513;0.82472402416509171807490474748192;0.81871199487434487274128969147569;0.81262132816785248579094513843302;0.80645352682648807629561815701891;0.80021011266294195252157805953175;0.79389262614623645752942593389889;0.78750262602163911829222797678085;0.78104168892606518070920174068306;0.77451140899906589787349275866291;0.76791339748949849486336916015716;0.76124928235797439945997666654876;0.75452070787518565886387023056159;0.74772933421620380034511299527367;0.7408768370508577172373065877764;0.73396490713028661456718282352085;0.72699524986977337448479374870658;0.71996958492795759543270150970784;0.71288964578253632975446407726849;0.70575717930255432719377495232038;0.6985739453173902546723184059374;0.69134171618254480762288949335925;0.6840622763423389596226797948475;0.67673742188962848764788304833928;0.669368960122645684229780727037;0.66195870909907461587806665193057;0.65450849718747372563143471779767;0.64702016261615191705658389764722;0.63949555301961458209092370452709;0.63193652498268626516164658823982;0.6243449435824273141548701460124;0.61672268192795254293514517485164;0.60907162069827114336817430739757;0.60139364767825609359164218403748;0.59369065729286241150930436560884;0.58596455013970483172158765228232;0.57821723252011547611317610062542;0.57045061596879131915471816682839;0.56266661678215212916143173060846;0.55486715554552257234632861582213;0.54705415665925716250939103701967;0.53922954786392240933423636306543;0.5313952597646567355127444898244;0.52355322535482129442385712536634;0.51570537953906414596616514245397;0.50785365865591025613667852667277;0.49999999999999994448884876874217;0.49214634134408968835217024206941;0.4842946204609357985226836262882;0.47644677464517865006499164337583;0.4686047402353432644872555101756;0.46077045213607747964346117441892;0.45294584334074272646830650046468;0.44513284445447742765367138417787;0.43733338321784787083856826939154;0.42954938403120868084528183317161;0.42178276747988452388682389937458;0.4140354498602952237895635789755;0.40630934270713764400184686564899;0.39860635232174373987490412218904;0.39092837930172863458722076757113;0.38327731807204723502024990011705;0.37565505641757251931167616021412;0.36806347501731351279374848672887;0.36050444698038525137562260169943;0.35297983738384808294341610235278;0.34549150281252627436856528220233;0.33804129090092527309963088555378;0.33063103987735426025906804170518;0.32326257811037140132981448914506;0.31593772365766092935501774263685;0.30865828381745508135480804412509;0.3014260546826097453276815940626;0.29424282069744556178392258516396;0.28711035421746367024553592273151;0.28003041507204240456729849029216;0.27300475013022657000405502003559;0.26603509286971327441051471396349;0.25912316294914239378499587473925;0.25227066578379619965488700472633;0.24547929212481439664728100069624;0.23875071764202554502887210219342;0.23208660251050172718123576487415;0.22548859100093410212650724133709;0.21895831107393470826849579680129;0.21249737397836071517431832944567;0.20610737385376343144827160358545;0.1997898873370579364561194779526;0.19354647317351170165977691794978;0.1873786718321473476756011677935;0.18128800512565518276986153978214;0.17527597583490822641394402126025;0.16934406733817408685638383758487;0.16349374324511334322096445248462;0.15772644703565563695235596242128;0.15204360170384284556277521005541;0.14644660940672621363134453531529;0.14093685111840553725315317024069;0.13551568628929422377638047692017;0.13018445251069510337771362173953;0.12494446518477025920290657268197;0.11979701719998453457449727466155;0.11474337861210537337086634579464;0.10978479633083509936497534908995;0.10492249381215479342444041321869;0.10015767075645470862710340043122;0.095491502812526274368565282202326;0.090925141287488298047492207842879;0.086459712862719084736085051190457;0.082096319315864862975473670303472;0.077836037248992462345142939739162;0.073679917822953855388590227448731;0.069628986498028178075969663041178;0.06568424278090440049382436882297;0.06184665997806820803006644382549;0.058117184955653267142139384304755;0.054496737905816050595575461557019;0.050986212119692175814833490221645;0.047586473766990267098009326218744;0.044298361682277354045567108187242;0.0411226871580094299751806374843;0.038060233744356630758431947469944;0.035111757055874270871953513051267;0.032277984585066366030048357060878;0.029559615522887272565100147403427;0.026957320586227351277841535193147;0.024471741852423234409030783353955;0.022103492600834939718623672888498;0.019853157161528467433697642263724;0.017721290771100961514150640141452;0.015708419435684461973323777783662;0.013815039801161721477740229602205;0.012041619030626282693674511392601;0.010388594689117125469124403025489;0.008856374635655639426801144509227;0.0074453369226130661218121531419456;0.0061558297024311148248898462043144;0.0049881711417212315495817165356129;0.0039426493427610620479129011073383;0.0030195222724101467015600519516738;0.0022190176984600018528226428315975;0.0015413331334360180768783266103128;0.00098663578586422051586168890935369;0.00055506251901499270573481226165313;0.00024671981713419999238112723105587;6.1683759169706142699851625366136e-05],dataType);
props.OverlapLength = cast(240,dataType);
props.SampleRate = cast(16000,dataType);
props.FFTLength = uint16(512);
props.NumFeatures = uint8(50);
end

function [config, outputIndex] = getConfig(dataType, props)

barkFilterbank = designAuditoryFilterBank(props.SampleRate, ...
    "FrequencyScale","bark", ...
    "FFTLength",props.FFTLength, ...
    "OneSided",true, ...
    "FrequencyRange",[0 8000], ...
    "NumBands",50, ...
    "Normalization","bandwidth", ...
    "FilterBankDesignDomain","linear");
config.barkSpectrum.FilterBank = cast(barkFilterbank,dataType);

outputIndex.barkSpectrum = uint8(1:50);
end
