%% Calculate Spectral Flux of Streaming Audio
% Spectral flux measures the change in consecutive spectrums. To calculate spectral flux for a streaming audio signal, you must input at least two frames of audio data.
% Create a dsp.AudioFileReader object to read in audio data frame-by-frame. Create a dsp.AsyncBuffer to buffer audio into overlapped frames. Create a dsp.SignalSink to log the spectral flux calculation.

fileReader = dsp.AudioFileReader('Counting-16-44p1-mono-15secs.wav');
buff = dsp.AsyncBuffer;
logger = dsp.SignalSink;

%
% In an audio stream loop:
% Read in a frame of audio data from your source.
% Write the audio data to a dsp.AsyncBuffer
% If a frame of data is available from the buffer, read a frame and one hop of data, with overlap equal to samples per frame. This represents the two most recent audio frames.
% Calculate the spectral flux for the two most recent audio frames.
% Log the spectral flux for later plotting. Because flux is defined by a current frame and a previous frame, and because the condition before the first frame is unknown to the function, spectral flux outputs a flux of zero for the first frame. Log only the second value output from spectralFlux.

fs = fileReader.SampleRate;

samplesPerFrame = round(fs*0.05);
samplesOverlap = round(fs*0.025);

samplesPerHop = samplesPerFrame - samplesOverlap;

win = hamming(samplesPerFrame);

while ~isDone(fileReader)
    audioIn = fileReader();
    write(buff,audioIn);
    
    while buff.NumUnreadSamples >= samplesPerHop
        audioBuffered = read(buff,samplesPerFrame+samplesPerHop,samplesPerFrame);
        flux = spectralFlux(audioBuffered,fs, ...
                            'Window',win, ...
                            'OverlapLength',samplesOverlap);
        logger(flux(end))
    end
    
end
release(fileReader)

%
% Plot the logged data.

plot(logger.Buffer)
ylabel('Flux')

%
% Copyright 2018 The MathWorks, Inc.