THIS COMMIT IS FOR REVIEW: audio update functions clarity review in examples

This commit is contained in:
iann 2025-11-13 07:31:47 +09:00
commit b3c25186d9

View file

@ -4,7 +4,7 @@
*
* Example complexity rating: [★★★☆] 3/4
*
* Example originally created with raylib 1.6, last time updated with raylib 4.2
* Example originally created with raylib 1.6, last time updated with raylib 6.0
*
* Example created by Ramon Santamaria (@raysan5) and reviewed by James Hofmann (@triplefox)
*
@ -19,7 +19,12 @@
#include <stdlib.h> // Required for: malloc(), free()
#include <math.h> // Required for: sinf()
#include <string.h> // Required for: memcpy()
enum Flags { FLAG_CHANNEL_MONO = 1u<<0, FLAG_SAMPLESIZE_SHORT = 1u<<1 };
static unsigned int gflags = FLAG_CHANNEL_MONO | FLAG_SAMPLESIZE_SHORT; // mono + 16-bit to match initial stream specs
#define CHANNEL_MONO() ((gflags & FLAG_CHANNEL_MONO) != 0)
#define SAMPLESIZE_SHORT() ((gflags & FLAG_SAMPLESIZE_SHORT) != 0)
#define TOGGLE(K, F) do { if (IsKeyPressed(K)) { gflags ^= (F); } } while (0)
#define MAX_SAMPLES 512
#define MAX_SAMPLES_PER_UPDATE 4096
@ -37,7 +42,7 @@ float oldFrequency = 1.0f;
float sineIdx = 0.0f;
// Audio input processing callback
void AudioInputCallback(void *buffer, unsigned int frames)
void AudioInputCallbackMonoShort(void *buffer, unsigned int frames)
{
audioFrequency = frequency + (audioFrequency - frequency)*0.95f;
@ -52,6 +57,54 @@ void AudioInputCallback(void *buffer, unsigned int frames)
}
}
void AudioInputCallbackStereoShort(void *buffer, unsigned int frames)
{
audioFrequency = frequency + (audioFrequency - frequency)*0.95f;
float incr = audioFrequency/44100.0f;
short *d = (short *)buffer;
for (unsigned int i = 0; i < frames; i++)
{
short s = (short)(32000.0f*sinf(2*PI*sineIdx));
d[2*i + 0] = s; // L
d[2*i + 1] = s; // R
sineIdx += incr;
if (sineIdx > 1.0f) sineIdx -= 1.0f;
}
}
void AudioInputCallbackMonoFloat(void *buffer, unsigned int frames)
{
audioFrequency = frequency + (audioFrequency - frequency)*0.95f;
float incr = audioFrequency/44100.0f;
float *d = (float *)buffer;
for (unsigned int i = 0; i < frames; i++)
{
d[i] = sinf(2*PI*sineIdx);
sineIdx += incr;
if (sineIdx > 1.0f) sineIdx -= 1.0f;
}
}
void AudioInputCallbackStereoFloat(void *buffer, unsigned int frames)
{
audioFrequency = frequency + (audioFrequency - frequency)*0.95f;
float incr = audioFrequency/44100.0f;
float *d = (float *)buffer;
for (unsigned int i = 0; i < frames; i++)
{
float s = sinf(2*PI*sineIdx);
d[2*i + 0] = s;
d[2*i + 1] = s;
sineIdx += incr;
if (sineIdx > 1.0f) sineIdx -= 1.0f;
}
}
//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
@ -62,7 +115,7 @@ int main(void)
const int screenWidth = 800;
const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [audio] example - raw stream");
InitWindow(screenWidth, screenHeight, "raylib [audio] example - raw stream with callbacks");
InitAudioDevice(); // Initialize audio device
@ -71,7 +124,9 @@ int main(void)
// Init raw audio stream (sample rate: 44100, sample size: 16bit-short, channels: 1-mono)
AudioStream stream = LoadAudioStream(44100, 16, 1);
SetAudioStreamCallback(stream, AudioInputCallback);
SetAudioStreamCallback(stream, AudioInputCallbackMonoShort);
unsigned int previousSampleSize = stream.sampleSize;
unsigned int previousChannels = stream.channels;
// Buffer for the single cycle waveform we are synthesizing
short *data = (short *)malloc(sizeof(short)*MAX_SAMPLES);
@ -84,17 +139,6 @@ int main(void)
// Position read in to determine next frequency
Vector2 mousePosition = { -100.0f, -100.0f };
/*
// Cycles per second (hz)
float frequency = 440.0f;
// Previous value, used to test if sine needs to be rewritten, and to smoothly modulate frequency
float oldFrequency = 1.0f;
// Cursor to read and copy the samples of the sine wave buffer
int readCursor = 0;
*/
// Computed size in samples of the sine wave
int waveLength = 1;
@ -106,6 +150,32 @@ int main(void)
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
TOGGLE(KEY_M, FLAG_CHANNEL_MONO);
TOGGLE(KEY_F, FLAG_SAMPLESIZE_SHORT);
unsigned int nextSampleSize = (SAMPLESIZE_SHORT())? 16u : 32u;
unsigned int nextChannels = (CHANNEL_MONO())? 1u : 2u;
if (nextSampleSize != previousSampleSize || nextChannels != previousChannels)
{
StopAudioStream(stream);
UnloadAudioStream(stream);
stream = LoadAudioStream(44100, nextSampleSize, nextChannels);
// CORRECT ALIGNMENT
if (nextChannels == 1 && nextSampleSize == 16) SetAudioStreamCallback(stream, AudioInputCallbackMonoShort);
if (nextChannels == 2 && nextSampleSize == 16) SetAudioStreamCallback(stream, AudioInputCallbackStereoShort);
if (nextChannels == 1 && nextSampleSize == 32) SetAudioStreamCallback(stream, AudioInputCallbackMonoFloat);
if (nextChannels == 2 && nextSampleSize == 32) SetAudioStreamCallback(stream, AudioInputCallbackStereoFloat);
// INCORRECT ALIGNMENT TESTS: comment and uncomment or add your own to observe common misconfigurations
// if (nextChannels == 1 && nextSampleSize == 16) SetAudioStreamCallback(stream, AudioInputCallbackStereoShort);
// if (nextChannels == 1 && nextSampleSize == 32) SetAudioStreamCallback(stream, AudioInputCallbackMonoShort);
// if (nextChannels == 2 && nextSampleSize == 32) SetAudioStreamCallback(stream, AudioInputCallbackMonoShort);
// if (nextChannels == 2 && nextSampleSize == 16) SetAudioStreamCallback(stream, AudioInputCallbackMonoFloat);
// if (nextChannels == 2 && nextSampleSize == 16) SetAudioStreamCallback(stream, AudioInputCallbackStereoFloat);
PlayAudioStream(stream);
previousSampleSize = nextSampleSize;
previousChannels = nextChannels;
}
// Update
//----------------------------------------------------------------------------------
mousePosition = GetMousePosition();
@ -124,7 +194,6 @@ int main(void)
if (frequency != oldFrequency)
{
// Compute wavelength. Limit size in both directions
//int oldWavelength = waveLength;
waveLength = (int)(22050/frequency);
if (waveLength > MAX_SAMPLES/2) waveLength = MAX_SAMPLES/2;
if (waveLength < 1) waveLength = 1;
@ -140,41 +209,9 @@ int main(void)
data[j] = (short)0;
}
// Scale read cursor's position to minimize transition artifacts
//readCursor = (int)(readCursor*((float)waveLength/(float)oldWavelength));
oldFrequency = frequency;
}
/*
// Refill audio stream if required
if (IsAudioStreamProcessed(stream))
{
// Synthesize a buffer that is exactly the requested size
int writeCursor = 0;
while (writeCursor < MAX_SAMPLES_PER_UPDATE)
{
// Start by trying to write the whole chunk at once
int writeLength = MAX_SAMPLES_PER_UPDATE-writeCursor;
// Limit to the maximum readable size
int readLength = waveLength-readCursor;
if (writeLength > readLength) writeLength = readLength;
// Write the slice
memcpy(writeBuf + writeCursor, data + readCursor, writeLength*sizeof(short));
// Update cursors and loop audio
readCursor = (readCursor + writeLength) % waveLength;
writeCursor += writeLength;
}
// Copy finished frame to audio stream
UpdateAudioStream(stream, writeBuf, MAX_SAMPLES_PER_UPDATE);
}
*/
//----------------------------------------------------------------------------------
// Draw
@ -185,6 +222,10 @@ int main(void)
DrawText(TextFormat("sine frequency: %i",(int)frequency), GetScreenWidth() - 220, 10, 20, RED);
DrawText("click mouse button to change frequency or pan", 10, 10, 20, DARKGRAY);
DrawText("press M to SWAP channels [ M ]:", 250, 366, 20, BLUE);
DrawText((CHANNEL_MONO())? "MONO" : "STEREO", 600, 366, 20, (CHANNEL_MONO())? GREEN : RED);
DrawText("press F to SWAP Sample Size [ F ]:", 250, 400, 20, BLUE);
DrawText((SAMPLESIZE_SHORT())? "16" : "32", 620, 400, 20, (SAMPLESIZE_SHORT())? GREEN : RED);
// Draw the current buffer state proportionate to the screen
for (int i = 0; i < screenWidth; i++)