
%This function is longer than it should be because it was extracted from
%speakerTest
function [fftMagnitude, soundPart, filteredPart, audioData, ampFiltered, amplitudeResult, amplitudeResult2 outSound] = testFrequency(recObject, amplitude, soundFreq, playTime, sampleRate)
    %Playing test sound
    outSound = playSound(amplitude, soundFreq, playTime, sampleRate);

    %Recording the sound
    audioData = recordSound(recObject, 1);

    flattenedData = abs(audioData);

    %Using low pass filter to find the amplitude of the sound
    Fnorm = soundFreq / 200 / (sampleRate / 2);
    filterSpec = fdesign.lowpass('N,Fc', 500, Fnorm);
    lpFilter = design(filterSpec);
    ampFiltered = filter(lpFilter, flattenedData);

    %Getting the interesting parts of the sound
    [soundPart, filteredPart] = getSoundPart(ampFiltered, audioData);

    %If there is sound to analyze
    if(length(soundPart) > 0)
        %Using fourier transform to calculate the amplitude
        audioFFT = fft(soundPart);
        fftMagnitude = abs(audioFFT);
        f = (0:length(audioFFT)-1) * soundFreq / length(audioFFT);
        
        amplitudeResult = max(fftMagnitude);
        amplitudeResult2 = filteredPart(ceil(length(filteredPart) * 2 / 3));
    end
end

%Plays sound at a specific amplitude and frequency. Returns the played sound
function outSound = playSound(amplitude, frequency, time, sampleRate)
    %Generate samples
    samples = (0:1:sampleRate * time) * frequency / (sampleRate / (2*pi));
    
    outSound = sin(samples);
    
    sound(outSound * amplitude, sampleRate);
end

%Plays a sound wave with a gaussian bell shape
function outSound = playGaussSound(stdDiv, amplitude, frequency, time, sampleRate)
    gaussWave = generateGaussFunction(sampleRate, amplitude, time, stdDiv);
    sinWave = generateSineWave(sampleRate, 1, frequency, time);

    %Adding some padding to get rid of weird effects at the start

    outSound = zeros(1, sampleRate * 0.1);
    outSound = [outSound, gaussWave .* sinWave];

    sound(outSound, sampleRate);
end

%Record sound from the microphone and return the result
function output = recordSound(recObject, time)
    recordblocking(recObject, time);
    
    output = getaudiodata(recObject);
end

%Return the biggest part of a sound that has more than noise in it. 
%avgAmps: Filtered version of the absolute sound wave
function [sound, filteredSound] = getSoundPart(avgAmps, audioData)
    noiseAmplitude = 1 * 10^-3;
    %Finding the start of the sound
    startPos = 1;
    endPos = length(audioData);

    %Array of found blocks of sound
    blocks = {};
    %0 = Searching for the start of a block
    %1 = Searching for the end of a block
    state = 0; 
    blockStart = 0;
    
    iterator = 1 : 50 : length(avgAmps);
    
    for n = iterator
        if state == 0
            if avgAmps(n) > noiseAmplitude
                blockStart = n;
                state = 1;
            end
        elseif state == 1
            if avgAmps(n) < noiseAmplitude || n == iterator(end);
                blocks(end+1) = {{blockStart, n}};
                state = 0;
            end
        end
    end

    %Looking for the largest block that was found
    largestBlock = -1;
    largestSize = 0;
    
    for n = 1 : length(blocks)
        blockSize = blocks{n}{2} - blocks{n}{1};
        
        if blockSize > largestSize
            largestSize = blockSize;
            largestBlock = n;
        end
    end

    %If a large block was found, use that, otherwise just use the whole sound
    %sample
    if largestBlock > -1
        startPos = blocks{largestBlock}{1};
        endPos = blocks{largestBlock}{2};
    end

    %'Return' the results of the search
    sound = audioData(startPos : endPos);
    filteredSound = avgAmps(startPos: endPos);
end

