#include "../JuceLibraryCode/JuceHeader.h" enum State { Done, Start, Play, Stop, Paused, Pause }; class MainContentComponent : public AudioAppComponent, public ChangeListener, public Button::Listener, public Timer { public: MainContentComponent() : state(Done) { addAndMakeVisible(&time); time.setText("00:00:00", NotificationType::dontSendNotification); addAndMakeVisible(&openbtn); openbtn.setButtonText("Open"); openbtn.addListener(this); addAndMakeVisible(&playbtn); playbtn.setButtonText("Play"); playbtn.addListener(this); playbtn.setColour(TextButton::buttonColourId, Colours::green); playbtn.setEnabled(false); addAndMakeVisible (&stopbtn); stopbtn.setButtonText("Stop"); stopbtn.addListener(this); stopbtn.setColour(TextButton::buttonColourId, Colours::red); stopbtn.setEnabled(false); formats.registerBasicFormats(); source.addChangeListener(this); setSize(300, 200); setAudioChannels(0, 2); } ~MainContentComponent() { shutdownAudio(); } int truncn(double i, int n) { return ((int) trunc(i)) % n; } void timerCallback() override { RelativeTime pos = RelativeTime(source.getCurrentPosition()); String str = String::formatted("%02d:%02d:%02d", truncn(pos.inMinutes(), 60), truncn(pos.inSeconds(), 60), truncn(pos.inMilliseconds(), 1000)/10); time.setText(str, NotificationType::dontSendNotification); } void changeListenerCallback(ChangeBroadcaster* s) override { if (s == &source) { if (source.isPlaying()) changeState(Play); else if(state == Stop || state == Play) changeState(Done); else if (state == Pause) changeState(Paused); } } void prepareToPlay(int s, double r) override { source.prepareToPlay(s, r); } void getNextAudioBlock(const AudioSourceChannelInfo& buf) override { if (readers == nullptr) { buf.clearActiveBufferRegion(); return; } source.getNextAudioBlock(buf); } void releaseResources() override { source.releaseResources(); } void paint (Graphics& g) override { g.fillAll(getLookAndFeel().findColour(ResizableWindow::backgroundColourId)); } void resized() override { int w = getWidth() - 20; time.setBounds(10, 10, w, 20); openbtn.setBounds(10, 30, w, 20); playbtn.setBounds(10, 60, w, 20); stopbtn.setBounds(10, 90, w, 20); } private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainContentComponent) TextButton openbtn; TextButton playbtn; TextButton stopbtn; Label time; AudioFormatManager formats; ScopedPointer readers; AudioTransportSource source; State state; void changeState(State news) { if (state == news) return; state = news; switch (state) { case Done: stopbtn.setEnabled(false); playbtn.setEnabled(true); source.setPosition(0.0); time.setText("00:00:00", NotificationType::dontSendNotification); break; case Start: source.start(); playbtn.setButtonText("Pause"); stopbtn.setButtonText("Stop"); break; case Play: stopbtn.setEnabled(true); startTimer(30); break; case Pause: source.stop(); stopTimer(); break; case Paused: playbtn.setButtonText("Resume"); stopbtn.setButtonText("Restart"); break; case Stop: source.stop(); stopTimer(); playbtn.setButtonText("Play"); break; } } void buttonClicked(Button* button) override { if (button == &openbtn) openClicked(); if (button == &playbtn) playClicked(); if (button == &stopbtn) stopClicked(); } void openClicked() { FileChooser chooser ("Select a file", File::nonexistent, "*.wav"); if (!chooser.browseForFileToOpen()) return; File file(chooser.getResult()); AudioFormatReader* reader = formats.createReaderFor(file); if (reader == nullptr) return; ScopedPointer news = new AudioFormatReaderSource(reader, true); source.setSource(news, 0, nullptr, reader->sampleRate); playbtn.setEnabled(true); readers = news.release(); } void playClicked() { if (state == Stop || state == Done || state == Paused) changeState(Start); else if (state == Play) changeState(Pause); } void stopClicked() { if (state == Paused) { changeState(Done); changeState(Start); } else changeState(Stop); } }; Component* createMainContentComponent() { return new MainContentComponent(); }