Skip to content

Commit

Permalink
Merge pull request #1 from Moros1138/develop
Browse files Browse the repository at this point in the history
Merge Develop into Main
  • Loading branch information
Moros1138 authored Sep 12, 2023
2 parents 156eea4 + 04d9eb6 commit 2d7c0e9
Show file tree
Hide file tree
Showing 16 changed files with 714 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
demo/demo*
!demo/demo.cpp

6 changes: 6 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[submodule "miniaudio"]
path = third_party/miniaudio
url = https://github.com/mackron/miniaudio
[submodule "olcPixelGameEngine"]
path = third_party/olcPixelGameEngine
url = https://github.com/OneLoneCoder/olcPixelGameEngine
37 changes: 37 additions & 0 deletions LICENSE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2023 Moros Smith <[email protected]>
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions or derivations of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions or derivative works in binary form must reproduce the above
copyright notice. This list of conditions and the following disclaimer must be
reproduced in the documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may
be used to endorse or promote products derived from this software without specific
prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
Music License for Example
~~~~~~~~~~~~~~~

Music: Joy Ride [Full version] by MusicLFiles
Free download: https://filmmusic.io/song/11627-joy-ride-full-version
Licensed under CC BY 4.0: https://filmmusic.io/standard-license
103 changes: 103 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1 +1,104 @@
# olcPGEX_MiniAudio

This extension abstracts the very robust and powerful miniaudio
library. It provides simple loading and playback of WAV and MP3
files. Because it's built on top of [miniaudio](https://miniaud.io), it requires next
to no additional build configurations in order to be built
for cross-platform.

See the emscripten version [running on the web here](https://www.moros1138.com/demos/olcPGEX_MiniAudio/).

# This is an olc::PixelGameEngine Extension

This is an extension module for the awesome and wonderful [olcPixelGameEngine](https://github.com/OneLoneCoder/olcPixelGameEngine) by Javidx9.

It relies on the equally amazing sound library [miniaudio](https://miniaud.io) by Mackron.

Go show them lots of love, they work hard for it!

# Features

Cross-Platform, out-of-the-box. Easily use in your Linux, Windows, MacOS, and Emscripten projects.

### Loading Features
* Loads WAV files
* Loads MP3 files

### Playback Features
* Play a sample in one off, or looping mode.
* Stop a sample and reset it for future playback.
* Pause a sample.
* Toggle (Play/Pause), convenience function.

### Seeking Features
* Seek to a position in the sample by milliseconds, or by float.
* Seek forward from current position by milliseconds.
* Seek back (rewind) from current position by milliseconds.

### Expression Features
* Set volume of a sample, by float 0.0f is mute, 1.0f is full
* Set pan of a sample, by float -1.0f is left, 1.0f is right, 0.0f is center
* Set pitch of a sample, by float 1.0f is normal pitch

### Misc Getter Features
* Get the current position in the sample, in milliseconds.
* Get the current position in the sample, as float 0.0f is start, 1.0f is end.

# Usage

Add miniaudio.h and olcPGEX_MiniAudio.h to your project. (THE PGEX EXPECTS miniaudio.h to be either in the same directory, or in the include path of your toolchain)

Excerpts from demo.cpp, [for full example click here](demo/demo.cpp).


```cpp
#define OLC_PGE_APPLICATION
#include "olcPixelGameEngine.h"

#define OLC_PGEX_MINIAUDIO
#include "olcPGEX_MiniAudio.h"
```

Declare an instance of the PGEX in your PGE derived class like so..

```cpp
// The instance of the audio engine, no fancy config required.
olc::MiniAudio ma;

// To keep track of our sample ID
int song1;
```

In OnUserCreate, load your sounds

```cpp
bool OnUserCreate() override
{
// Load a sample from a file, currently decodes WAV and MP3
// files, out-of-the-box without further coding or configuration.
// returns a sample ID (int), for future control calls.
song1 = ma.LoadSound("assets/sounds/song1.mp3");

return true;
}
```
Then use them in your OnUserUpdate, like so
```cpp
if(GetKey(olc::SPACE).bPressed)
ma.Toggle(song1);
```
# Building

For Windows MSVC and Emscripten the instructions match any other olcPixelGameEngine!

For Linux, add ``-ldl`` to the build command..

TODO: instructions for MacOS, I'm not a Mac user and have no way to test it!

That's it!

# Acknowledgements

I'd like to give a special thanks for JavidX9 (aka OneLoneCoder), AniCator, JustinRichardsMusic, and everybody else who was a part of that audiophile conversation when I asked for help! Your patience and feedback made this project possible. Thank you!
20 changes: 20 additions & 0 deletions demo/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
INCLUDE := -I../ -I../third_party/miniaudio -I../third_party/olcPixelGameEngine
GCC_FLAGS := -std=c++17 -O2 -lX11 -lGL -lpthread -lpng -lstdc++fs -std=c++17 -ldl -lm
EM_FLAGS := -std=c++17 -O2 -s ALLOW_MEMORY_GROWTH=1 -s MAX_WEBGL_VERSION=2 -s MIN_WEBGL_VERSION=2 -s USE_LIBPNG=1

.PHONY: all linux emscripten clean

all: linux emscripten

demo: demo.cpp
g++ demo.cpp -o demo ${INCLUDE} ${GCC_FLAGS}

demo.html: demo.cpp
em++ demo.cpp -o demo.html ${INCLUDE} ${EM_FLAGS} --preload-file=./assets@assets

linux: demo

emscripten: demo.html

clean:
@rm -f demo demo.html demo.js demo.wasm demo.data
24 changes: 24 additions & 0 deletions demo/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Examples

To see the demo running, [visit here](https://www.moros1138.com/demos/olcPGEX_MiniAudio/).


I'm going to assume you're here because you already build with PGE, so I don't have to walk you through setting up your environments. HOWEVER, if my assumption proves incorrect, I suggest you spend some time reading the PGE header file, it's loaded with instructions and helpful advice!


To build the demo for linux:
```
make linux
```

To build the demo for emscripten:

```
make emscripten
```

If you want to build both, and have both environments active, run:

```
make
```
Binary file added demo/assets/sounds/SampleA.wav
Binary file not shown.
Binary file added demo/assets/sounds/SampleB.wav
Binary file not shown.
Binary file added demo/assets/sounds/SampleC.wav
Binary file not shown.
Binary file added demo/assets/sounds/Sample_Test_44100.wav
Binary file not shown.
Binary file added demo/assets/sounds/Sample_Test_48000.wav
Binary file not shown.
Binary file added demo/assets/sounds/song1.mp3
Binary file not shown.
147 changes: 147 additions & 0 deletions demo/demo.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
#define OLC_PGE_APPLICATION
#include "olcPixelGameEngine.h"

#define OLC_PGEX_MINIAUDIO
#include "olcPGEX_MiniAudio.h"

class Demo : public olc::PixelGameEngine
{
public:
Demo()
{
sAppName = "Demo MiniAudio";
}

public:
bool OnUserCreate() override
{
// Load a sample from a file, currently decodes WAV and MP3
// files, out-of-the-box without further coding or configuration.
// returns a sample ID (int), for future control calls.
song1 = ma.LoadSound("assets/sounds/song1.mp3");

return true;
}

bool OnUserUpdate(float fElapsedTime) override
{

if(GetKey(olc::SPACE).bPressed)
{
// Toggle takes a sample ID (int) and either starts playback or pauses playback
// depending on whether the sample is currently playing, or not.
ma.Toggle(song1);
}


if(GetKey(olc::MINUS).bHeld)
{
pan -= 1.0f * fElapsedTime;
if(pan < -1.0f) pan = -1.0f;
}

if(GetKey(olc::EQUALS).bHeld)
{
pan += 1.0f * fElapsedTime;
if(pan > 1.0f) pan = 1.0f;
}

if(GetKey(olc::OEM_4).bHeld)
pitch -= 1.0f * fElapsedTime;

if(GetKey(olc::OEM_6).bHeld)
pitch += 1.0f * fElapsedTime;

if(GetKey(olc::DOWN).bHeld)
{
volume -= 1.0f * fElapsedTime;
if(volume < 0.0f) volume = 0.0f;
}

if(GetKey(olc::UP).bHeld)
{
volume += 1.0f * fElapsedTime;
if(volume > 1.0f) volume = 1.0f;
}


// Reset pan, pitch, and volume
if(GetKey(olc::R).bPressed)
{
pan = 0.0f;
pitch = 1.0f;
volume = 1.0f;
}

// Set pan, takes a sample ID (int), and a float
// -1.0 to 1.0 where 0 is center
ma.SetPan(song1, pan);

// Set pitch, takes a sample ID (int), and a float
// 1.0 is normal pitch
ma.SetPitch(song1, pitch);

// Set volume, takes a sample ID (int), and a float
// 0.0 to 1.0 where 1.0 is full volume
ma.SetVolume(song1, volume);

// Gets the current playback position in the provided sample ID (int),
// returns float 0.0 to 1.0, nearer 1.0 is near the end
seek = ma.GetCursorFloat(song1);

// Draw Instructions and Indicators
Clear(olc::BLACK);

DrawStringDecal({5, 5}, \
"-------- INFO --- CONTROLS -\n"
"\n"
"Pan <" + std::to_string(pan) + "> -, =\n"
"\n"
"Pitch <" + std::to_string(pitch) + "> [, ]\n"
"\n"
"Volume <" + std::to_string(volume) + "> Up, Down\n", \
olc::WHITE, {0.5f, 0.5f});

olc::vi2d center = (GetScreenSize() / 2);

DrawStringDecal((center - olc::vi2d{0, 24}) - (olc::vf2d(GetTextSize("olcPGEX_MiniAudio Demo")) * 1.5f / 2.0f), "olcPGEX_MiniAudio Demo", olc::WHITE, {1.5f, 1.5f});
DrawStringDecal(center - (GetTextSize("Hit <SPACE> To Toggle Playback") / 2), "Hit <SPACE> To Toggle Playback", olc::WHITE);
DrawStringDecal((center + olc::vi2d{0, 16}) - (GetTextSize("Hit <R> TO Reset Pan/Pitch/Volume") / 2), "Hit <R> TO Reset Pan/Pitch/Volume", olc::WHITE);

DrawStringDecal({5, 160}, \
"Music: Joy Ride [Full version] by MusicLFiles\n"
"Free download: https://filmmusic.io/song/11627-joy-ride-full-version\n"
"Licensed under CC BY 4.0: https://filmmusic.io/standard-license\n", \
olc::WHITE, {0.5f, 0.5f});

// Draw The Playback Cursor (aka the position in the sound file)
FillRect({0, 175}, { (int)(ScreenWidth() * seek), 10 }, olc::YELLOW);

#if defined(__EMSCRIPTEN__)
return true;
#else
return !GetKey(olc::ESCAPE).bPressed;
#endif
}

// The instance of the audio engine, no fancy config required.
olc::MiniAudio ma;

// To keep track of our sample ID
int song1;

// For demonstration controls, with sensible default values
float pan = 0.0f;
float pitch = 1.0f;
float seek = 0.0f;
float volume = 1.0f;

};

int main()
{
Demo demo;
if (demo.Construct(320, 180, 4, 4))
demo.Start();
return 0;
}
Loading

0 comments on commit 2d7c0e9

Please sign in to comment.