%% Frequency-Domain Voice Activity Detection and Cepstral Feature Extraction
% Many feature extraction techniques operate on the frequency domain. Converting an audio signal to the frequency domain only once is efficient. In this example, you convert a streaming audio signal to the frequency domain and feed that signal into a voice activity detector. If speech is present, mel-frequency cepstral coefficients (MFCC) features are extracted from the frequency-domain signal using the cepstralFeatureExtractor System object™.
% Create a dsp.AudioFileReader System object to read from an audio file.

fileReader = dsp.AudioFileReader('Counting-16-44p1-mono-15secs.wav');
fs = fileReader.SampleRate;

% Process the audio in 30 ms frames with a 10 ms hop. Create a default dsp.AsyncBuffer object to manage overlap between audio frames.

samplesPerFrame = ceil(0.03*fs);
samplesPerHop = ceil(0.01*fs);
samplesPerOverlap = samplesPerFrame - samplesPerHop;

fileReader.SamplesPerFrame = samplesPerHop;
buffer = dsp.AsyncBuffer;

% Create a voiceActivityDetector System object and a cepstralFeatureExtractor System object. Specify that they operate in the frequency domain. Create a dsp.SignalSink to log the extracted cepstral features.

VAD = voiceActivityDetector('InputDomain','Frequency');
cepFeatures = cepstralFeatureExtractor('InputDomain','Frequency','SampleRate',fs,'LogEnergy','Replace');
sink = dsp.SignalSink;

% In an audio stream loop:
% Read one hop's of samples from the audio file and save the samples into the buffer.
% Read a frame from the buffer with specified overlap from the previous frame.
% Call the voice activity detector to get the probability of speech for the frame under analysis.
% If the frame under analysis has a probability of speech greater than 0.75, extract cepstral features and log the features using the signal sink. If the frame under analysis has a probability of speech less than 0.75, write a vector of NaNs to the sink.

threshold = 0.75;
nanVector = nan(1,13);
while ~isDone(fileReader)
    audioIn = fileReader();
    write(buffer,audioIn);
    
    overlappedAudio = read(buffer,samplesPerFrame,samplesPerOverlap);
    X = fft(overlappedAudio,2048);
    
    probabilityOfSpeech = VAD(X);
    if probabilityOfSpeech > threshold
        xFeatures = cepFeatures(X);
        sink(xFeatures')
    else
        sink(nanVector)
    end
end

% Visualize the cepstral coefficients over time.

timeVector = linspace(0,15,size(sink.Buffer,1));
plot(timeVector,sink.Buffer)
xlabel('Time (s)')
ylabel('MFCC Amplitude')
legend('Log-Energy','c1','c2','c3','c4','c5','c6','c7','c8','c9','c10','c11','c12')

% Copyright 2012 The MathWorks, Inc.