summaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
Diffstat (limited to 'examples')
-rw-r--r--examples/audio_stream_effects/main.lua100
-rw-r--r--examples/resources/clib/.gitignore1
-rw-r--r--examples/resources/clib/audioProcess.c100
-rw-r--r--examples/resources/music/Juhani Junkala [Retro Game Music Pack] Title Screen.oggbin0 -> 268705 bytes
-rw-r--r--examples/resources/music/LICENCE2
5 files changed, 203 insertions, 0 deletions
diff --git a/examples/audio_stream_effects/main.lua b/examples/audio_stream_effects/main.lua
new file mode 100644
index 0000000..575a5ce
--- /dev/null
+++ b/examples/audio_stream_effects/main.lua
@@ -0,0 +1,100 @@
+-- Based on raylib audio_stream_effects example
+
+package.path = package.path..";"..RL.GetBasePath().."../resources/lib/?.lua"
+package.cpath = package.cpath..";"..RL.GetBasePath().."../resources/clib/?.so"
+
+Vector2 = require( "vector2" )
+Rect = require( "rectangle" )
+
+-- NOTE! You have to compile the C lib containing the effects in resources/clib/audioProcess.c
+-- Implementing audio processors in Lua would probably be too slow.
+AudioProcess = require( "audioProcess" )
+
+local music = nil
+local rect = Rect:new()
+local rect2 = Rect:new()
+local effectLPF = nil
+local effectDelay = nil
+local enableEffectLPF = false
+local enableEffectDelay = false
+
+function RL.init()
+ RL.SetWindowTitle( "Audio stream effects" )
+ RL.SetWindowState( RL.FLAG_VSYNC_HINT )
+ RL.InitAudioDevice()
+
+ music = RL.LoadMusicStream( RL.GetBasePath().."../resources/music/Juhani Junkala [Retro Game Music Pack] Title Screen.ogg" )
+
+ RL.PlayMusicStream( music )
+
+ AudioProcess.init()
+ effectLPF = AudioProcess.AudioProcessEffectLPF()
+ effectDelay = AudioProcess.AudioProcessEffectDelay()
+
+ local winSize = Vector2:newT( RL.GetScreenSize() )
+ local barWidth = 256
+
+ rect:set(
+ winSize.x / 2 - barWidth / 2,
+ winSize.y / 2 - 5,
+ barWidth,
+ 10
+ )
+ rect2:setR( rect )
+end
+
+function RL.update( delta )
+ RL.UpdateMusicStream( music )
+
+ -- Add/Remove effect: lowpass filter
+ if RL.IsKeyPressed( RL.KEY_F ) then
+ local stream = RL.GetMusicStream( music )
+ enableEffectLPF = not enableEffectLPF
+
+ if enableEffectLPF then
+ RL.AttachAudioStreamProcessor( stream, effectLPF )
+ -- RL.AttachAudioMixedProcessor( effectLPF )
+ else
+ RL.DetachAudioStreamProcessor( stream, effectLPF )
+ -- RL.DetachAudioMixedProcessor( effectLPF )
+ end
+ end
+
+ -- Add/Remove effect: delay
+ if RL.IsKeyPressed( RL.KEY_D ) then
+ local stream = RL.GetMusicStream( music )
+ enableEffectDelay = not enableEffectDelay
+
+ if enableEffectDelay then
+ RL.AttachAudioStreamProcessor( stream, effectDelay )
+ -- RL.AttachAudioMixedProcessor( effectDelay )
+ else
+ RL.DetachAudioStreamProcessor( stream, effectDelay )
+ -- RL.DetachAudioMixedProcessor( effectDelay )
+ end
+ end
+end
+
+function RL.draw()
+ local musicLen = RL.GetMusicTimeLength( music )
+ local musicPos = RL.GetMusicTimePlayed( music )
+
+ RL.ClearBackground( RL.RAYWHITE )
+
+ RL.DrawText(
+ "PRESS F TO TOGGLE LPF EFFECT "..( enableEffectLPF and "ON" or "OFF" ),
+ Vector2:temp( rect.x - 80, rect.y - 80 ), 20, RL.GRAY
+ )
+ RL.DrawText(
+ "PRESS D TO TOGGLE DELAY EFFECT "..( enableEffectDelay and "ON" or "OFF" ),
+ Vector2:temp( rect.x - 90, rect.y - 40 ), 20, RL.GRAY
+ )
+
+ RL.DrawRectangleLines( rect + Rect:temp( 0, -1, 1, 1 ), RL.BLACK )
+ rect2.width = musicPos / musicLen * rect.width
+ RL.DrawRectangle( rect2, RL.RED )
+end
+
+function RL.exit()
+ AudioProcess.free()
+end
diff --git a/examples/resources/clib/.gitignore b/examples/resources/clib/.gitignore
new file mode 100644
index 0000000..f1fe8d1
--- /dev/null
+++ b/examples/resources/clib/.gitignore
@@ -0,0 +1 @@
+*.so \ No newline at end of file
diff --git a/examples/resources/clib/audioProcess.c b/examples/resources/clib/audioProcess.c
new file mode 100644
index 0000000..ad18117
--- /dev/null
+++ b/examples/resources/clib/audioProcess.c
@@ -0,0 +1,100 @@
+/* Based on raylib audio_stream_effects example */
+
+#include <lua.h>
+#include <lauxlib.h>
+#include <lualib.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* gcc audioProcess.c -shared -o audioProcess.so -fPIC -llua */
+
+// Audio effect: lowpass filter
+void AudioProcessEffectLPF(void *buffer, unsigned int frames)
+{
+ static float low[2] = { 0.0f, 0.0f };
+ static const float cutoff = 70.0f / 44100.0f; // 70 Hz lowpass filter
+ const float k = cutoff / (cutoff + 0.1591549431f); // RC filter formula
+
+ // Converts the buffer data before using it
+ float *bufferData = (float *)buffer;
+ for (unsigned int i = 0; i < frames*2; i += 2)
+ {
+ const float l = bufferData[i];
+ const float r = bufferData[i + 1];
+
+ low[0] += k * (l - low[0]);
+ low[1] += k * (r - low[1]);
+ bufferData[i] = low[0];
+ bufferData[i + 1] = low[1];
+ }
+}
+
+static float *delayBuffer = NULL;
+static unsigned int delayBufferSize = 0;
+static unsigned int delayReadIndex = 2;
+static unsigned int delayWriteIndex = 0;
+
+// Audio effect: delay
+static void AudioProcessEffectDelay(void *buffer, unsigned int frames)
+{
+ for (unsigned int i = 0; i < frames*2; i += 2)
+ {
+ float leftDelay = delayBuffer[delayReadIndex++]; // ERROR: Reading buffer -> WHY??? Maybe thread related???
+ float rightDelay = delayBuffer[delayReadIndex++];
+
+ if (delayReadIndex == delayBufferSize) delayReadIndex = 0;
+
+ ((float *)buffer)[i] = 0.5f*((float *)buffer)[i] + 0.5f*leftDelay;
+ ((float *)buffer)[i + 1] = 0.5f*((float *)buffer)[i + 1] + 0.5f*rightDelay;
+
+ delayBuffer[delayWriteIndex++] = ((float *)buffer)[i];
+ delayBuffer[delayWriteIndex++] = ((float *)buffer)[i + 1];
+ if (delayWriteIndex == delayBufferSize) delayWriteIndex = 0;
+ }
+}
+
+/* API. */
+
+static int apInit( lua_State* L ) {
+ // Allocate buffer for the delay effect
+ delayBufferSize = 48000*2; // 1 second delay (device sampleRate*channels)
+ delayBuffer = (float *)calloc(delayBufferSize, sizeof(float));
+
+ return 0;
+}
+
+static int getAudioProcessEffectLPF( lua_State* L ) {
+ lua_pushlightuserdata( L, AudioProcessEffectLPF );
+
+ return 1;
+}
+
+static int getAudioProcessEffectDelay( lua_State* L ) {
+ lua_pushlightuserdata( L, AudioProcessEffectDelay );
+
+ return 1;
+}
+
+static int apFree( lua_State* L ) {
+ free(delayBuffer); // Free delay buffer
+
+ return 0;
+}
+
+static const luaL_Reg audioProcess[] = {
+ { "init", apInit },
+ { "AudioProcessEffectLPF", getAudioProcessEffectLPF },
+ { "AudioProcessEffectDelay", getAudioProcessEffectDelay },
+ { "free", apFree },
+ { NULL, NULL } // sentinel.
+};
+
+int luaopen_audioProcess(lua_State *L) {
+#if LUA_VERSION_NUM <= 501
+ luaL_openlib( L, "audioProcess", audioProcess, 0 );
+#else
+ luaL_newlib( L, audioProcess );
+#endif
+ return 1;
+}
diff --git a/examples/resources/music/Juhani Junkala [Retro Game Music Pack] Title Screen.ogg b/examples/resources/music/Juhani Junkala [Retro Game Music Pack] Title Screen.ogg
new file mode 100644
index 0000000..755ddfb
--- /dev/null
+++ b/examples/resources/music/Juhani Junkala [Retro Game Music Pack] Title Screen.ogg
Binary files differ
diff --git a/examples/resources/music/LICENCE b/examples/resources/music/LICENCE
new file mode 100644
index 0000000..7b94830
--- /dev/null
+++ b/examples/resources/music/LICENCE
@@ -0,0 +1,2 @@
+Resource Author Licence Source Edits
+Juhani Junkala [Retro Game Music Pack] Title Screen Juhani Junkala CC0 https://opengameart.org/content/5-chiptunes-action