|  | /*
  ==============================================================================
   This file is part of the JUCE library.
   Copyright (c) 2017 - ROLI Ltd.
   JUCE is an open source library subject to commercial or open-source
   licensing.
   By using JUCE, you agree to the terms of both the JUCE 5 End-User License
   Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
   27th April 2017).
   End User License Agreement: www.juce.com/juce-5-licence
   Privacy Policy: www.juce.com/juce-5-privacy-policy
   Or: You may also use this code under the terms of the GPL v3 (see
   www.gnu.org/licenses).
   JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
   EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
   DISCLAIMED.
  ==============================================================================
*/
#include "Main.h"
DSPSamplesApplication::DSPSamplesApplication()
    : TimeSliceThread ("Audio File Reader Thread"), demoIndex (-1)
{
    loopState.addListener (this);
}
void DSPSamplesApplication::initialise (const String&)
{
    formatManager.registerBasicFormats();
    audioDeviceManager.addAudioCallback (&audioSourcePlayer);
    audioDeviceManager.initialiseWithDefaultDevices (0, 2);
    setCurrentDemo (0);
    startThread();
    mainWindow = new MainWindow (getApplicationName());
}
void DSPSamplesApplication::shutdown()
{
    signalThreadShouldExit();
    stop();
    audioDeviceManager.removeAudioCallback (&audioSourcePlayer);
    waitForThreadToExit (10000);
    mainWindow = nullptr;
}
//==============================================================================
DSPSamplesApplication& DSPSamplesApplication::getApp()
{
    auto* app = dynamic_cast<DSPSamplesApplication*> (JUCEApplication::getInstance());
    jassert (app != nullptr);
    return *app;
}
//==============================================================================
bool DSPSamplesApplication::loadFile (const File& fileToPlay)
{
    stop();
    audioSourcePlayer.setSource (nullptr);
    mainWindow->setTransportSource (nullptr);
    transportSource = nullptr;
    readerSource = nullptr;
    reader = formatManager.createReaderFor (fileToPlay);
    if (reader != nullptr)
    {
        readerSource = new AudioFormatReaderSource (reader, false);
        readerSource->setLooping (loopState.getValue());
        init();
        return true;
    }
    return false;
}
void DSPSamplesApplication::togglePlay()
{
    if (playState.getValue())
        stop();
    else
        play();
}
void DSPSamplesApplication::stop()
{
    playState = false;
    if (transportSource != nullptr)
    {
        transportSource->stop();
        transportSource->setPosition (0);
    }
}
void DSPSamplesApplication::init()
{
    if (transportSource == nullptr)
    {
        transportSource = new AudioTransportSource();
        transportSource->addChangeListener (this);
        if (readerSource != nullptr)
        {
            if (auto* device = audioDeviceManager.getCurrentAudioDevice())
            {
                transportSource->setSource (readerSource, roundToInt (device->getCurrentSampleRate()), this, reader->sampleRate);
                // tell the main window about this so that it can do the seeking behaviour...
                mainWindow->setTransportSource (transportSource);
            }
        }
    }
    audioSourcePlayer.setSource (nullptr);
    currentDemo = nullptr;
    if (currentDemo == nullptr)
        if (auto demo = Demo::getList()[demoIndex])
            if (demo->name.isNotEmpty())
                currentDemo = demo->createDemo (*transportSource);
    audioSourcePlayer.setSource (currentDemo);
    if (mainWindow != nullptr)
        mainWindow->initParameters();
}
void DSPSamplesApplication::play()
{
    if (readerSource == nullptr)
        return;
    if (transportSource->getCurrentPosition() >= transportSource->getLengthInSeconds()
         || transportSource->getCurrentPosition() < 0)
        transportSource->setPosition (0);
    transportSource->start();
    playState = true;
}
void DSPSamplesApplication::setLooping (bool shouldLoop)
{
    if (readerSource != nullptr)
        readerSource->setLooping (shouldLoop);
}
void DSPSamplesApplication::changeListenerCallback (ChangeBroadcaster*)
{
    if (playState.getValue() && ! transportSource->isPlaying())
        stop();
}
void DSPSamplesApplication::setCurrentDemo (int index, bool force)
{
    if ((index != demoIndex || force) && isPositiveAndBelow (index, Demo::getList().size()))
    {
        demoIndex = index;
        init();
        if (playState.getValue())
            play();
    }
}
void DSPSamplesApplication::valueChanged (Value& v)
{
    if (readerSource != nullptr)
        readerSource->setLooping (v.getValue());
}
//==============================================================================
// This macro generates the main() routine that launches the app.
START_JUCE_APPLICATION (DSPSamplesApplication)
 |