From b3c25186d9cf395bab53f8b4b5f4162d88897242 Mon Sep 17 00:00:00 2001 From: iann Date: Thu, 13 Nov 2025 07:31:47 +0900 Subject: [PATCH] THIS COMMIT IS FOR REVIEW: audio update functions clarity review in examples --- examples/audio/audio_raw_stream.c | 42 +----- examples/audio/audio_raw_stream_callback.c | 139 ++++++++++++------- examples/audio/audio_raw_stream_callback.png | Bin 0 -> 16434 bytes examples/audio/audio_sound_loading.c | 33 ++++- examples/audio/audio_sound_loading.png | Bin 15438 -> 15987 bytes 5 files changed, 125 insertions(+), 89 deletions(-) create mode 100644 examples/audio/audio_raw_stream_callback.png diff --git a/examples/audio/audio_raw_stream.c b/examples/audio/audio_raw_stream.c index 4deae2090..0195efba8 100644 --- a/examples/audio/audio_raw_stream.c +++ b/examples/audio/audio_raw_stream.c @@ -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) * @@ -24,34 +24,6 @@ #define MAX_SAMPLES 512 #define MAX_SAMPLES_PER_UPDATE 4096 -// Cycles per second (hz) -float frequency = 440.0f; - -// Audio frequency, for smoothing -float audioFrequency = 440.0f; - -// Previous value, used to test if sine needs to be rewritten, and to smoothly modulate frequency -float oldFrequency = 1.0f; - -// Index for audio rendering -float sineIdx = 0.0f; - -// Audio input processing callback -void AudioInputCallback(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++) - { - d[i] = (short)(32000.0f*sinf(2*PI*sineIdx)); - sineIdx += incr; - if (sineIdx > 1.0f) sineIdx -= 1.0f; - } -} - //------------------------------------------------------------------------------------ // Program main entry point //------------------------------------------------------------------------------------ @@ -71,8 +43,6 @@ 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); - // Buffer for the single cycle waveform we are synthesizing short *data = (short *)malloc(sizeof(short)*MAX_SAMPLES); @@ -84,7 +54,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; @@ -93,7 +62,6 @@ int main(void) // 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; @@ -124,8 +92,8 @@ int main(void) if (frequency != oldFrequency) { // Compute wavelength. Limit size in both directions - //int oldWavelength = waveLength; - waveLength = (int)(22050/frequency); + int oldWavelength = waveLength; + waveLength = (int)(stream.sampleRate/frequency); if (waveLength > MAX_SAMPLES/2) waveLength = MAX_SAMPLES/2; if (waveLength < 1) waveLength = 1; @@ -141,11 +109,10 @@ int main(void) } // Scale read cursor's position to minimize transition artifacts - //readCursor = (int)(readCursor*((float)waveLength/(float)oldWavelength)); + readCursor = (int)(readCursor*((float)waveLength/(float)oldWavelength)); oldFrequency = frequency; } - /* // Refill audio stream if required if (IsAudioStreamProcessed(stream)) { @@ -174,7 +141,6 @@ int main(void) // Copy finished frame to audio stream UpdateAudioStream(stream, writeBuf, MAX_SAMPLES_PER_UPDATE); } - */ //---------------------------------------------------------------------------------- // Draw diff --git a/examples/audio/audio_raw_stream_callback.c b/examples/audio/audio_raw_stream_callback.c index 501a0c324..746b29716 100644 --- a/examples/audio/audio_raw_stream_callback.c +++ b/examples/audio/audio_raw_stream_callback.c @@ -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 // Required for: malloc(), free() #include // Required for: sinf() -#include // 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++) diff --git a/examples/audio/audio_raw_stream_callback.png b/examples/audio/audio_raw_stream_callback.png new file mode 100644 index 0000000000000000000000000000000000000000..08ab77ac95d4c4c1c8ef94597196085a3ede0140 GIT binary patch literal 16434 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 KT-G@yGywq6n^eF6 literal 0 HcmV?d00001 diff --git a/examples/audio/audio_sound_loading.c b/examples/audio/audio_sound_loading.c index 97e26a450..997c93b19 100644 --- a/examples/audio/audio_sound_loading.c +++ b/examples/audio/audio_sound_loading.c @@ -4,7 +4,7 @@ * * Example complexity rating: [★☆☆☆] 1/4 * -* Example originally created with raylib 1.1, last time updated with raylib 3.5 +* Example originally created with raylib 1.1, last time updated with raylib 6.0 * * Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, * BSD-like license that allows static linking with closed source software @@ -14,6 +14,8 @@ ********************************************************************************************/ #include "raylib.h" +#include // Required for: malloc(), free() +#include // Required for: memcpy() //------------------------------------------------------------------------------------ // Program main entry point @@ -32,6 +34,17 @@ int main(void) Sound fxWav = LoadSound("resources/sound.wav"); // Load WAV audio file Sound fxOgg = LoadSound("resources/target.ogg"); // Load OGG audio file + bool soundReversed = false; + + float *soundData = malloc(sizeof(float)*fxWav.frameCount*fxWav.stream.channels); + float *scratchSoundData = malloc(sizeof(float)*fxWav.frameCount*fxWav.stream.channels); + + Wave wave = LoadWave("resources/sound.wav"); + // Sounds always have 32bit sampleSize: + WaveFormat(&wave, fxWav.stream.sampleRate, 32, fxWav.stream.channels); + memcpy(soundData, wave.data, sizeof(float)*fxWav.frameCount*fxWav.stream.channels); + UnloadWave(wave); + SetTargetFPS(60); // Set our game to run at 60 frames-per-second //-------------------------------------------------------------------------------------- @@ -40,6 +53,18 @@ int main(void) { // Update //---------------------------------------------------------------------------------- + if (IsKeyPressed(KEY_R)) + { + soundReversed = !soundReversed; + for (unsigned int i = 0; i < fxWav.frameCount; i++) + { + unsigned int src = (soundReversed)? fxWav.frameCount - 1 - i : i; + // Sounds always have STEREO channels: + scratchSoundData[i * fxWav.stream.channels + 0] = soundData[src * fxWav.stream.channels + 0]; + scratchSoundData[i * fxWav.stream.channels + 1] = soundData[src * fxWav.stream.channels + 1]; + } + UpdateSound(fxWav, scratchSoundData, fxWav.frameCount); + } if (IsKeyPressed(KEY_SPACE)) PlaySound(fxWav); // Play WAV sound if (IsKeyPressed(KEY_ENTER)) PlaySound(fxOgg); // Play OGG sound //---------------------------------------------------------------------------------- @@ -51,7 +76,9 @@ int main(void) ClearBackground(RAYWHITE); DrawText("Press SPACE to PLAY the WAV sound!", 200, 180, 20, LIGHTGRAY); - DrawText("Press ENTER to PLAY the OGG sound!", 200, 220, 20, LIGHTGRAY); + DrawText(TextFormat("Press R to REVERSE the WAV sound : "), 120, 220, 20, LIGHTGRAY); + DrawText((soundReversed)? "BACKWARDS" : "FORWARDS", 525, 220, 20, (soundReversed)? MAROON : DARKGREEN); + DrawText("Press ENTER to PLAY the OGG sound!", 200, 260, 20, LIGHTGRAY); EndDrawing(); //---------------------------------------------------------------------------------- @@ -59,6 +86,8 @@ int main(void) // De-Initialization //-------------------------------------------------------------------------------------- + free(soundData); + free(scratchSoundData); UnloadSound(fxWav); // Unload sound data UnloadSound(fxOgg); // Unload sound data diff --git a/examples/audio/audio_sound_loading.png b/examples/audio/audio_sound_loading.png index 24071ce3ccc7e93f29e8eb9d3655c9d90ec585bd..64b463f6c0f820c7837fe05c2966378d833542f1 100644 GIT binary patch delta 1734 zcmX?C@wsM#GLxOvM%514$qTeNCL0(l)-QFN5DpE$>NejaS|qw>Wi|<;uq{ zK_6zt-((N75BQbv?QxOGnb;TaRF?3k$?5$)!X~u$5c^&GC&!Lw%q}!xSs}`_*jQn4 zW~RyHMW*7D15{YTteB0QgrpZvbO~~=YWLp2yS+g1x;?Y$XV-OmzkFN%j$@{zidp<* zt3!5C|9JLywcVJ>S~CA~wER{lx!PsT6LvP6)?B#j`o`yc#_k#umKCxP^Rp%|G?f4u zA8W;IH0#EOHinJHN=w#FT|WI+V_(>p56<$8YNj>rlV5(|VRU-Q@+{lwW$T?9)1b?u zdrz6i7~4O2H&wAbUua>4+>5<#S3KI6^gWquwb(FC*|WR*|xeY5NtGQS{gOorl4~4@xTjdAn4u&OdUiS-bWn-^Sn#Y`1%u7k+Rq*Y~kq z`m#IVqu<+4DJolIJ@&>ki96m5$(a|w{XfCk zcu{h~#VdAFOp6r_q?i^@KFKH&F_%%&Hz$ObG0DB_q^#i4rx97bKZLA5S%pmEUHiBB zbWPQH72fR?i%n`@@=dPx&X~H-L$|)I+SKq$dY$7(=XbWU&3{dFinq*u;{H9U$Lv;{ zH%HI8hMr|lCl|8FOkOX+TE94pLtyu^Syv>vtJY^OFL9ZBV=v2>PvVOI1zz*TC?9{) zCcgCBBK0^Y1iGX8>wJ$fE{T+@Pg+=MwaB{ zi-r>M(9D>@(bLB8PC%hF#5+8^+=WGb=R>B;?izD0T%BmWi(_+p(03u}l}C=*Z+z(R z_K3^tisqfu@4ajeu$Vae-HW+1U(WS&KW+XgsbayW_ZhLaQcQ<6Aujt2N~e?Gi*uX4 z>G208o+(++A;6VCBhTrfU!I-JiysTG z@+j=u|049CptZ4=_V=D=+d-ko_{lk;ge}G7>*SBpl9S9?ChJIY#Vwg9#%w(4ilDob za@7mJrPF>sQDaJS?<(9m`<}7llU>vA{7@HJcjTD-%9l+O_HOyaziaQ4TgF!o&A#=~ z`K{B;8#CpdKDxjD)OPKm$J$R*<9?=ZDU#!Dd?*7h3|>~l3WFGMVc_Q6&>?VP>E*w2 zOZwJKv|8lCKZ1 kS*#|RHxDRE5o2Ho`>9a#@8#An3=9kmp00i_>zopr0R0~v;Q#;t literal 15438 zcmeAS@N?(olHy`uVBq!ia0y~yU{+vYU_8XZ#=yWJp1k%11A~pIr;B4qMO^ZqUteF> zw*?wVF)dcaL6mSXF1r{Y$J=;OKmselSk-zUgFVG$ZExFw42~Wwgh5Z4gPZU{?2*GaR-HNW5+6QQL;o4Z9$2*oe~&ASYbL;l7@>10Ntx2pM&POg9YOWlXef+^0<3v6nifXW!f0ARZtIWch|wG|nj=PY1bQEP zv|Jc17e>p4(Q;w5TmW~a(TLH~anP5JB5enro}Mo0P+_9r?wnx4!qE;M?w$%O)X-uy zgX4lOON86uDianrXNGc)30AX~u3l}e)HL}{f#kbi9Ikd}{(tdPpVDT%@!is`woBUN zH@;%mic5Ie8dQJLy3XCp(mdkx=Zv|wQcQ;xS=`bc+%A8_umWl~!(FF@61EhRjlFFQ zf{G3qNAj1f`>k58GUd((nVes3QO_2JTgjc(zv3ym_d`wO-IHh6 zCra6W(YnrYRDJE~n-~9>gY0pr;^;Zo(6ek7zG3?pJSQ@eq zTle!xUzR6*S0+o(`*JVa`Avt#%7^YbdnQ^3^`Ex=!nOaP*#0eC`B}&Lm$n-2{mj1c z-O^G^kF|f=wg0e1+w_OsTC8Xw1M#D5KM{Tu5M~H6+xdM_ZKTo7y0K@Ot4zy zp`pcb)BCMp!rjEO_1t^^IA_@e&YH)zN{*>I`GG0W2Q zO7P5g2D1%i&wgF3=x|yKW(}5(SZ&`|J*->PE!uANaPEAk z8YaI|dH#`iy^=Z)eR6iGm}_6WHUCJP`O0_8%XU04>W_QLaNUPv@8i-1r_D?L3%!<` zvFqZ@2^Z6jW^f4bfhTH0j6kuAZNA81yFdbHPU-)}4|r#cS`L7s-AWqkgi_;0fd$bV zpa~mL`hzBQ^y&jN;ZNcVZ%T`D=f`A~?k-i)KTMjI_-ovj~?IGK#a((Y%-G48i&c9gW9M|cPx8q{; z{fwuE&{E<_8#uS$k^}`MwmD=_B0C3}-d*6xA+USftSh!$UxNH!yBO|jlM*`g;w4Kh z%j_#9CbMRKY-d>bq3tEO$~oNFCm(f|VbSmIxTo?PjTdhzI-gMoE>aZi!PQsrdE`0` z*;i;4=c`OZ17%OyLKTxm?e9XeX8PwTDU>adn7;d^t+3O&>XW_oP7l3u{!E;u$8pnJ z`~QO5-s^0gb@!~4wZEb_<>KMVH%i>s*;P%gU(zPL^;CG(Q+e=|`e6&OD<*#@&J_#1 zm;bi)kd0I>b(w!hk|D;?C3DAtFNg2AzAjL^UQ<&0rAU9Rk^0_C#){P|OpWX>wBAUN z7j!?Lexyx&=dXlk!MpcJu3ZDEg#00u&@()V2plCz(!7vL$S1furE-CLfu?Nc(sGeY z)z8vQCiA@$Sa7}PQh+D>l4<_Vwzd7o{%3HSN--^I2kTu$Oms@PC_22Em6`QkRMDKH zqm+H6vGtZ&6Bll+_LSv3`c$r@nC-M2bJY5m%eUHh^5zG9X5Mr zk>G87C=SjHE5ZF0Y(5>$4AfX2G@2O(MXP=^Gk{u<-~o)$n!zo2v}PEs8Adb1Xfp}a zJbK&EGnyGjGs9?R7|jfzPBr7eZz&k^6VqkD`jz2i}r)32L0|SGntDnm{r-UW|qH&mB