diff --git a/play_sound/Source/Main.cpp b/play_sound/Source/Main.cpp new file mode 100644 index 0000000..54a6e40 --- /dev/null +++ b/play_sound/Source/Main.cpp @@ -0,0 +1,102 @@ +/* + ============================================================================== + + This file was auto-generated! + + It contains the basic startup code for a Juce application. + + ============================================================================== +*/ + +#include "../JuceLibraryCode/JuceHeader.h" + +Component* createMainContentComponent(); + +//============================================================================== +class play_soundApplication : public JUCEApplication +{ +public: + //============================================================================== + play_soundApplication() {} + + const String getApplicationName() override { return ProjectInfo::projectName; } + const String getApplicationVersion() override { return ProjectInfo::versionString; } + bool moreThanOneInstanceAllowed() override { return true; } + + //============================================================================== + void initialise (const String& commandLine) override + { + // This method is where you should put your application's initialisation code.. + + mainWindow = new MainWindow (getApplicationName()); + } + + void shutdown() override + { + // Add your application's shutdown code here.. + + mainWindow = nullptr; // (deletes our window) + } + + //============================================================================== + void systemRequestedQuit() override + { + // This is called when the app is being asked to quit: you can ignore this + // request and let the app carry on running, or call quit() to allow the app to close. + quit(); + } + + void anotherInstanceStarted (const String& commandLine) override + { + // When another instance of the app is launched while this one is running, + // this method is invoked, and the commandLine parameter tells you what + // the other instance's command-line arguments were. + } + + //============================================================================== + /* + This class implements the desktop window that contains an instance of + our MainContentComponent class. + */ + class MainWindow : public DocumentWindow + { + public: + MainWindow (String name) : DocumentWindow (name, + Desktop::getInstance().getDefaultLookAndFeel() + .findColour (ResizableWindow::backgroundColourId), + DocumentWindow::allButtons) + { + setUsingNativeTitleBar (true); + setContentOwned (createMainContentComponent(), true); + setResizable (true, true); + + centreWithSize (getWidth(), getHeight()); + setVisible (true); + } + + void closeButtonPressed() override + { + // This is called when the user tries to close this window. Here, we'll just + // ask the app to quit when this happens, but you can change this to do + // whatever you need. + JUCEApplication::getInstance()->systemRequestedQuit(); + } + + /* Note: Be careful if you override any DocumentWindow methods - the base + class uses a lot of them, so by overriding you might break its functionality. + It's best to do all your work in your content component instead, but if + you really have to override any DocumentWindow methods, make sure your + subclass also calls the superclass's method. + */ + + private: + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainWindow) + }; + +private: + ScopedPointer mainWindow; +}; + +//============================================================================== +// This macro generates the main() routine that launches the app. +START_JUCE_APPLICATION (play_soundApplication) diff --git a/play_sound/Source/MainComponent.cpp b/play_sound/Source/MainComponent.cpp new file mode 100644 index 0000000..5da72f1 --- /dev/null +++ b/play_sound/Source/MainComponent.cpp @@ -0,0 +1,146 @@ +#include "../JuceLibraryCode/JuceHeader.h" + +enum State { + Done, + Start, + Play, + Stop +}; + +class MainContentComponent : public AudioAppComponent, + public ChangeListener, + public Button::Listener { +public: + MainContentComponent() : state(Done) { + + 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); + + formatManager.registerBasicFormats(); + transportSource.addChangeListener(this); + + setSize(300, 200); + + setAudioChannels(0, 2); + } + + ~MainContentComponent() { + shutdownAudio(); + } + + void changeListenerCallback(ChangeBroadcaster* source) override { + if (source == &transportSource) { + if (transportSource.isPlaying()) changeState(Play); + else changeState(Done); + } + } + + void prepareToPlay(int s, double r) override { + transportSource.prepareToPlay(s, r); + } + + void getNextAudioBlock(const AudioSourceChannelInfo& buf) override { + if (readerSource == nullptr) { + buf.clearActiveBufferRegion(); + return; + } + + transportSource.getNextAudioBlock(buf); + } + + void releaseResources() override { + transportSource.releaseResources(); + } + + void paint (Graphics& g) override { + g.fillAll(getLookAndFeel().findColour(ResizableWindow::backgroundColourId)); + } + + void resized() override { + openbtn.setBounds(10, 10, getWidth() - 20, 20); + playbtn.setBounds(10, 40, getWidth() - 20, 20); + stopbtn.setBounds (10, 70, getWidth() - 20, 20); + } + + +private: + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainContentComponent) + TextButton openbtn; + TextButton playbtn; + TextButton stopbtn; + AudioFormatManager formatManager; + ScopedPointer readerSource; + AudioTransportSource transportSource; + State state; + + void changeState(State news) { + if (state == news) return; + + state = news; + + switch (state) { + case Done: + stopbtn.setEnabled(false); + playbtn.setEnabled(true); + transportSource.setPosition (0.0); + break; + + case Start: + playbtn.setEnabled (false); + transportSource.start(); + break; + + case Play: + stopbtn.setEnabled (true); + break; + + case Stop: + transportSource.stop(); + 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 = formatManager.createReaderFor(file); + + if (reader == nullptr) return; + + ScopedPointer news = new AudioFormatReaderSource(reader, true); + transportSource.setSource(news, 0, nullptr, reader->sampleRate); + playbtn.setEnabled(true); + readerSource = news.release(); + } + + void playClicked() { + changeState(Start); + } + + void stopClicked() { + changeState(Stop); + } +}; + +Component* createMainContentComponent() { return new MainContentComponent(); } diff --git a/play_sound/play_sound.jucer b/play_sound/play_sound.jucer new file mode 100644 index 0000000..5ebc538 --- /dev/null +++ b/play_sound/play_sound.jucer @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +