REVIEWED: example: audio_amp_envelope, code formating to follow raylib code conventions #5713

This commit is contained in:
Ray
2026-04-04 11:12:30 +02:00
parent bb7b8d70e9
commit ea6292e27a

View File

@ -20,7 +20,7 @@
#define RAYGUI_IMPLEMENTATION #define RAYGUI_IMPLEMENTATION
#include "raygui.h" #include "raygui.h"
#include <math.h> #include <math.h> // Required for: sinf()
#define BUFFER_SIZE 4096 #define BUFFER_SIZE 4096
#define SAMPLE_RATE 44100 #define SAMPLE_RATE 44100
@ -49,7 +49,7 @@ typedef struct {
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
static void FillAudioBuffer(int i, float *buffer, float envelopeValue, float *audioTime); static void FillAudioBuffer(int i, float *buffer, float envelopeValue, float *audioTime);
static void UpdateEnvelope(Envelope *env); static void UpdateEnvelope(Envelope *env);
static void DrawADSRGraph(const Envelope *env, Rectangle bounds); static void DrawADSRGraph(Envelope *env, Rectangle bounds);
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// Program main entry point // Program main entry point
@ -93,24 +93,22 @@ int main(void)
{ {
// Update // Update
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
if (IsKeyPressed(KEY_SPACE)) env.state = ATTACK;
if (IsKeyPressed(KEY_SPACE)) { if (IsKeyReleased(KEY_SPACE) && (env.state != IDLE)) env.state = RELEASE;
env.state = ATTACK;
}
if (IsKeyReleased(KEY_SPACE)) { if (IsAudioStreamProcessed(stream))
if (env.state != IDLE) env.state = RELEASE; {
} if ((env.state != IDLE) || (env.currentValue > 0.0f))
{
if (IsAudioStreamProcessed(stream)) {
if (env.state != IDLE || env.currentValue > 0.0f) {
for (int i = 0; i < BUFFER_SIZE; i++) for (int i = 0; i < BUFFER_SIZE; i++)
{ {
UpdateEnvelope(&env); UpdateEnvelope(&env);
FillAudioBuffer(i, buffer, env.currentValue, &audioTime); FillAudioBuffer(i, buffer, env.currentValue, &audioTime);
} }
} else { }
else
{
// Clear buffer if silent to avoid looping noise // Clear buffer if silent to avoid looping noise
for (int i = 0; i < BUFFER_SIZE; i++) buffer[i] = 0; for (int i = 0; i < BUFFER_SIZE; i++) buffer[i] = 0;
audioTime = 0.0f; audioTime = 0.0f;
@ -139,9 +137,11 @@ int main(void)
DrawText(TextFormat("Current Gain: %2.2f", env.currentValue), 535, 345 - (env.currentValue * 100), 10, MAROON); DrawText(TextFormat("Current Gain: %2.2f", env.currentValue), 535, 345 - (env.currentValue * 100), 10, MAROON);
DrawText("Press SPACE to PLAY the sound!", 200, 400, 20, LIGHTGRAY); DrawText("Press SPACE to PLAY the sound!", 200, 400, 20, LIGHTGRAY);
EndDrawing(); EndDrawing();
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
} }
// De-Initialization // De-Initialization
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
UnloadAudioStream(stream); UnloadAudioStream(stream);
@ -158,10 +158,9 @@ int main(void)
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
static void FillAudioBuffer(int i, float *buffer, float envelopeValue, float *audioTime) static void FillAudioBuffer(int i, float *buffer, float envelopeValue, float *audioTime)
{ {
int frequency = 440; int frequency = 440;
buffer[i] = envelopeValue*sinf(2.0f*PI*frequency*(*audioTime)); buffer[i] = envelopeValue*sinf(2.0f*PI*frequency*(*audioTime));
*audioTime += 1.0f / SAMPLE_RATE; *audioTime += (1.0f/SAMPLE_RATE);
} }
static void UpdateEnvelope(Envelope *env) static void UpdateEnvelope(Envelope *env)
@ -172,41 +171,45 @@ static void UpdateEnvelope(Envelope *env)
switch(env->state) switch(env->state)
{ {
case ATTACK: case ATTACK:
{
env->currentValue += (1.0f/env->attackTime)*sampleTime; env->currentValue += (1.0f/env->attackTime)*sampleTime;
if (env->currentValue >= 1.0f) if (env->currentValue >= 1.0f)
{ {
env->currentValue = 1.0f; env->currentValue = 1.0f;
env->state = DECAY; env->state = DECAY;
} }
break;
} break;
case DECAY: case DECAY:
{
env->currentValue -= ((1.0f - env->sustainLevel)/env->decayTime)*sampleTime; env->currentValue -= ((1.0f - env->sustainLevel)/env->decayTime)*sampleTime;
if (env->currentValue <= env->sustainLevel) if (env->currentValue <= env->sustainLevel)
{ {
env->currentValue = env->sustainLevel; env->currentValue = env->sustainLevel;
env->state = SUSTAIN; env->state = SUSTAIN;
} }
break;
} break;
case SUSTAIN: case SUSTAIN:
{
env->currentValue = env->sustainLevel; env->currentValue = env->sustainLevel;
break;
} break;
case RELEASE: case RELEASE:
{
env->currentValue -= (env->sustainLevel/env->releaseTime)*sampleTime; env->currentValue -= (env->sustainLevel/env->releaseTime)*sampleTime;
if (env->currentValue <= 0.001f) // Use a small threshold to avoid infinite tail if (env->currentValue <= 0.001f) // Use a small threshold to avoid infinite tail
{ {
env->currentValue = 0.0f; env->currentValue = 0.0f;
env->state = IDLE; env->state = IDLE;
} }
break;
} break;
default: break; default: break;
} }
} }
static void DrawADSRGraph(const Envelope *env, Rectangle bounds) static void DrawADSRGraph(Envelope *env, Rectangle bounds)
{ {
DrawRectangleRec(bounds, Fade(LIGHTGRAY, 0.3f)); DrawRectangleRec(bounds, Fade(LIGHTGRAY, 0.3f));
DrawRectangleLinesEx(bounds, 1, GRAY); DrawRectangleLinesEx(bounds, 1, GRAY);