Skip to content

Commit b3c2518

Browse files
committed
THIS COMMIT IS FOR REVIEW: audio update functions clarity review in examples
1 parent 79a6188 commit b3c2518

File tree

5 files changed

+125
-89
lines changed

5 files changed

+125
-89
lines changed

examples/audio/audio_raw_stream.c

Lines changed: 4 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
*
55
* Example complexity rating: [★★★☆] 3/4
66
*
7-
* Example originally created with raylib 1.6, last time updated with raylib 4.2
7+
* Example originally created with raylib 1.6, last time updated with raylib 6.0
88
*
99
* Example created by Ramon Santamaria (@raysan5) and reviewed by James Hofmann (@triplefox)
1010
*
@@ -24,34 +24,6 @@
2424
#define MAX_SAMPLES 512
2525
#define MAX_SAMPLES_PER_UPDATE 4096
2626

27-
// Cycles per second (hz)
28-
float frequency = 440.0f;
29-
30-
// Audio frequency, for smoothing
31-
float audioFrequency = 440.0f;
32-
33-
// Previous value, used to test if sine needs to be rewritten, and to smoothly modulate frequency
34-
float oldFrequency = 1.0f;
35-
36-
// Index for audio rendering
37-
float sineIdx = 0.0f;
38-
39-
// Audio input processing callback
40-
void AudioInputCallback(void *buffer, unsigned int frames)
41-
{
42-
audioFrequency = frequency + (audioFrequency - frequency)*0.95f;
43-
44-
float incr = audioFrequency/44100.0f;
45-
short *d = (short *)buffer;
46-
47-
for (unsigned int i = 0; i < frames; i++)
48-
{
49-
d[i] = (short)(32000.0f*sinf(2*PI*sineIdx));
50-
sineIdx += incr;
51-
if (sineIdx > 1.0f) sineIdx -= 1.0f;
52-
}
53-
}
54-
5527
//------------------------------------------------------------------------------------
5628
// Program main entry point
5729
//------------------------------------------------------------------------------------
@@ -71,8 +43,6 @@ int main(void)
7143
// Init raw audio stream (sample rate: 44100, sample size: 16bit-short, channels: 1-mono)
7244
AudioStream stream = LoadAudioStream(44100, 16, 1);
7345

74-
SetAudioStreamCallback(stream, AudioInputCallback);
75-
7646
// Buffer for the single cycle waveform we are synthesizing
7747
short *data = (short *)malloc(sizeof(short)*MAX_SAMPLES);
7848

@@ -84,7 +54,6 @@ int main(void)
8454
// Position read in to determine next frequency
8555
Vector2 mousePosition = { -100.0f, -100.0f };
8656

87-
/*
8857
// Cycles per second (hz)
8958
float frequency = 440.0f;
9059

@@ -93,7 +62,6 @@ int main(void)
9362

9463
// Cursor to read and copy the samples of the sine wave buffer
9564
int readCursor = 0;
96-
*/
9765

9866
// Computed size in samples of the sine wave
9967
int waveLength = 1;
@@ -124,8 +92,8 @@ int main(void)
12492
if (frequency != oldFrequency)
12593
{
12694
// Compute wavelength. Limit size in both directions
127-
//int oldWavelength = waveLength;
128-
waveLength = (int)(22050/frequency);
95+
int oldWavelength = waveLength;
96+
waveLength = (int)(stream.sampleRate/frequency);
12997
if (waveLength > MAX_SAMPLES/2) waveLength = MAX_SAMPLES/2;
13098
if (waveLength < 1) waveLength = 1;
13199

@@ -141,11 +109,10 @@ int main(void)
141109
}
142110

143111
// Scale read cursor's position to minimize transition artifacts
144-
//readCursor = (int)(readCursor*((float)waveLength/(float)oldWavelength));
112+
readCursor = (int)(readCursor*((float)waveLength/(float)oldWavelength));
145113
oldFrequency = frequency;
146114
}
147115

148-
/*
149116
// Refill audio stream if required
150117
if (IsAudioStreamProcessed(stream))
151118
{
@@ -174,7 +141,6 @@ int main(void)
174141
// Copy finished frame to audio stream
175142
UpdateAudioStream(stream, writeBuf, MAX_SAMPLES_PER_UPDATE);
176143
}
177-
*/
178144
//----------------------------------------------------------------------------------
179145

180146
// Draw

examples/audio/audio_raw_stream_callback.c

Lines changed: 90 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
*
55
* Example complexity rating: [★★★☆] 3/4
66
*
7-
* Example originally created with raylib 1.6, last time updated with raylib 4.2
7+
* Example originally created with raylib 1.6, last time updated with raylib 6.0
88
*
99
* Example created by Ramon Santamaria (@raysan5) and reviewed by James Hofmann (@triplefox)
1010
*
@@ -19,7 +19,12 @@
1919

2020
#include <stdlib.h> // Required for: malloc(), free()
2121
#include <math.h> // Required for: sinf()
22-
#include <string.h> // Required for: memcpy()
22+
23+
enum Flags { FLAG_CHANNEL_MONO = 1u<<0, FLAG_SAMPLESIZE_SHORT = 1u<<1 };
24+
static unsigned int gflags = FLAG_CHANNEL_MONO | FLAG_SAMPLESIZE_SHORT; // mono + 16-bit to match initial stream specs
25+
#define CHANNEL_MONO() ((gflags & FLAG_CHANNEL_MONO) != 0)
26+
#define SAMPLESIZE_SHORT() ((gflags & FLAG_SAMPLESIZE_SHORT) != 0)
27+
#define TOGGLE(K, F) do { if (IsKeyPressed(K)) { gflags ^= (F); } } while (0)
2328

2429
#define MAX_SAMPLES 512
2530
#define MAX_SAMPLES_PER_UPDATE 4096
@@ -37,7 +42,7 @@ float oldFrequency = 1.0f;
3742
float sineIdx = 0.0f;
3843

3944
// Audio input processing callback
40-
void AudioInputCallback(void *buffer, unsigned int frames)
45+
void AudioInputCallbackMonoShort(void *buffer, unsigned int frames)
4146
{
4247
audioFrequency = frequency + (audioFrequency - frequency)*0.95f;
4348

@@ -52,6 +57,54 @@ void AudioInputCallback(void *buffer, unsigned int frames)
5257
}
5358
}
5459

60+
void AudioInputCallbackStereoShort(void *buffer, unsigned int frames)
61+
{
62+
audioFrequency = frequency + (audioFrequency - frequency)*0.95f;
63+
64+
float incr = audioFrequency/44100.0f;
65+
short *d = (short *)buffer;
66+
67+
for (unsigned int i = 0; i < frames; i++)
68+
{
69+
short s = (short)(32000.0f*sinf(2*PI*sineIdx));
70+
d[2*i + 0] = s; // L
71+
d[2*i + 1] = s; // R
72+
sineIdx += incr;
73+
if (sineIdx > 1.0f) sineIdx -= 1.0f;
74+
}
75+
}
76+
77+
void AudioInputCallbackMonoFloat(void *buffer, unsigned int frames)
78+
{
79+
audioFrequency = frequency + (audioFrequency - frequency)*0.95f;
80+
81+
float incr = audioFrequency/44100.0f;
82+
float *d = (float *)buffer;
83+
84+
for (unsigned int i = 0; i < frames; i++)
85+
{
86+
d[i] = sinf(2*PI*sineIdx);
87+
sineIdx += incr;
88+
if (sineIdx > 1.0f) sineIdx -= 1.0f;
89+
}
90+
}
91+
92+
void AudioInputCallbackStereoFloat(void *buffer, unsigned int frames)
93+
{
94+
audioFrequency = frequency + (audioFrequency - frequency)*0.95f;
95+
float incr = audioFrequency/44100.0f;
96+
float *d = (float *)buffer;
97+
for (unsigned int i = 0; i < frames; i++)
98+
{
99+
float s = sinf(2*PI*sineIdx);
100+
d[2*i + 0] = s;
101+
d[2*i + 1] = s;
102+
103+
sineIdx += incr;
104+
if (sineIdx > 1.0f) sineIdx -= 1.0f;
105+
}
106+
}
107+
55108
//------------------------------------------------------------------------------------
56109
// Program main entry point
57110
//------------------------------------------------------------------------------------
@@ -62,7 +115,7 @@ int main(void)
62115
const int screenWidth = 800;
63116
const int screenHeight = 450;
64117

65-
InitWindow(screenWidth, screenHeight, "raylib [audio] example - raw stream");
118+
InitWindow(screenWidth, screenHeight, "raylib [audio] example - raw stream with callbacks");
66119

67120
InitAudioDevice(); // Initialize audio device
68121

@@ -71,7 +124,9 @@ int main(void)
71124
// Init raw audio stream (sample rate: 44100, sample size: 16bit-short, channels: 1-mono)
72125
AudioStream stream = LoadAudioStream(44100, 16, 1);
73126

74-
SetAudioStreamCallback(stream, AudioInputCallback);
127+
SetAudioStreamCallback(stream, AudioInputCallbackMonoShort);
128+
unsigned int previousSampleSize = stream.sampleSize;
129+
unsigned int previousChannels = stream.channels;
75130

76131
// Buffer for the single cycle waveform we are synthesizing
77132
short *data = (short *)malloc(sizeof(short)*MAX_SAMPLES);
@@ -84,17 +139,6 @@ int main(void)
84139
// Position read in to determine next frequency
85140
Vector2 mousePosition = { -100.0f, -100.0f };
86141

87-
/*
88-
// Cycles per second (hz)
89-
float frequency = 440.0f;
90-
91-
// Previous value, used to test if sine needs to be rewritten, and to smoothly modulate frequency
92-
float oldFrequency = 1.0f;
93-
94-
// Cursor to read and copy the samples of the sine wave buffer
95-
int readCursor = 0;
96-
*/
97-
98142
// Computed size in samples of the sine wave
99143
int waveLength = 1;
100144

@@ -106,6 +150,32 @@ int main(void)
106150
// Main game loop
107151
while (!WindowShouldClose()) // Detect window close button or ESC key
108152
{
153+
TOGGLE(KEY_M, FLAG_CHANNEL_MONO);
154+
TOGGLE(KEY_F, FLAG_SAMPLESIZE_SHORT);
155+
unsigned int nextSampleSize = (SAMPLESIZE_SHORT())? 16u : 32u;
156+
unsigned int nextChannels = (CHANNEL_MONO())? 1u : 2u;
157+
if (nextSampleSize != previousSampleSize || nextChannels != previousChannels)
158+
{
159+
StopAudioStream(stream);
160+
UnloadAudioStream(stream);
161+
stream = LoadAudioStream(44100, nextSampleSize, nextChannels);
162+
// CORRECT ALIGNMENT
163+
if (nextChannels == 1 && nextSampleSize == 16) SetAudioStreamCallback(stream, AudioInputCallbackMonoShort);
164+
if (nextChannels == 2 && nextSampleSize == 16) SetAudioStreamCallback(stream, AudioInputCallbackStereoShort);
165+
if (nextChannels == 1 && nextSampleSize == 32) SetAudioStreamCallback(stream, AudioInputCallbackMonoFloat);
166+
if (nextChannels == 2 && nextSampleSize == 32) SetAudioStreamCallback(stream, AudioInputCallbackStereoFloat);
167+
168+
// INCORRECT ALIGNMENT TESTS: comment and uncomment or add your own to observe common misconfigurations
169+
// if (nextChannels == 1 && nextSampleSize == 16) SetAudioStreamCallback(stream, AudioInputCallbackStereoShort);
170+
// if (nextChannels == 1 && nextSampleSize == 32) SetAudioStreamCallback(stream, AudioInputCallbackMonoShort);
171+
// if (nextChannels == 2 && nextSampleSize == 32) SetAudioStreamCallback(stream, AudioInputCallbackMonoShort);
172+
// if (nextChannels == 2 && nextSampleSize == 16) SetAudioStreamCallback(stream, AudioInputCallbackMonoFloat);
173+
// if (nextChannels == 2 && nextSampleSize == 16) SetAudioStreamCallback(stream, AudioInputCallbackStereoFloat);
174+
175+
PlayAudioStream(stream);
176+
previousSampleSize = nextSampleSize;
177+
previousChannels = nextChannels;
178+
}
109179
// Update
110180
//----------------------------------------------------------------------------------
111181
mousePosition = GetMousePosition();
@@ -124,7 +194,6 @@ int main(void)
124194
if (frequency != oldFrequency)
125195
{
126196
// Compute wavelength. Limit size in both directions
127-
//int oldWavelength = waveLength;
128197
waveLength = (int)(22050/frequency);
129198
if (waveLength > MAX_SAMPLES/2) waveLength = MAX_SAMPLES/2;
130199
if (waveLength < 1) waveLength = 1;
@@ -140,41 +209,9 @@ int main(void)
140209
data[j] = (short)0;
141210
}
142211

143-
// Scale read cursor's position to minimize transition artifacts
144-
//readCursor = (int)(readCursor*((float)waveLength/(float)oldWavelength));
145212
oldFrequency = frequency;
146213
}
147214

148-
/*
149-
// Refill audio stream if required
150-
if (IsAudioStreamProcessed(stream))
151-
{
152-
// Synthesize a buffer that is exactly the requested size
153-
int writeCursor = 0;
154-
155-
while (writeCursor < MAX_SAMPLES_PER_UPDATE)
156-
{
157-
// Start by trying to write the whole chunk at once
158-
int writeLength = MAX_SAMPLES_PER_UPDATE-writeCursor;
159-
160-
// Limit to the maximum readable size
161-
int readLength = waveLength-readCursor;
162-
163-
if (writeLength > readLength) writeLength = readLength;
164-
165-
// Write the slice
166-
memcpy(writeBuf + writeCursor, data + readCursor, writeLength*sizeof(short));
167-
168-
// Update cursors and loop audio
169-
readCursor = (readCursor + writeLength) % waveLength;
170-
171-
writeCursor += writeLength;
172-
}
173-
174-
// Copy finished frame to audio stream
175-
UpdateAudioStream(stream, writeBuf, MAX_SAMPLES_PER_UPDATE);
176-
}
177-
*/
178215
//----------------------------------------------------------------------------------
179216

180217
// Draw
@@ -185,6 +222,10 @@ int main(void)
185222

186223
DrawText(TextFormat("sine frequency: %i",(int)frequency), GetScreenWidth() - 220, 10, 20, RED);
187224
DrawText("click mouse button to change frequency or pan", 10, 10, 20, DARKGRAY);
225+
DrawText("press M to SWAP channels [ M ]:", 250, 366, 20, BLUE);
226+
DrawText((CHANNEL_MONO())? "MONO" : "STEREO", 600, 366, 20, (CHANNEL_MONO())? GREEN : RED);
227+
DrawText("press F to SWAP Sample Size [ F ]:", 250, 400, 20, BLUE);
228+
DrawText((SAMPLESIZE_SHORT())? "16" : "32", 620, 400, 20, (SAMPLESIZE_SHORT())? GREEN : RED);
188229

189230
// Draw the current buffer state proportionate to the screen
190231
for (int i = 0; i < screenWidth; i++)
16 KB
Loading

examples/audio/audio_sound_loading.c

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
*
55
* Example complexity rating: [★☆☆☆] 1/4
66
*
7-
* Example originally created with raylib 1.1, last time updated with raylib 3.5
7+
* Example originally created with raylib 1.1, last time updated with raylib 6.0
88
*
99
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
1010
* BSD-like license that allows static linking with closed source software
@@ -14,6 +14,8 @@
1414
********************************************************************************************/
1515

1616
#include "raylib.h"
17+
#include <stdlib.h> // Required for: malloc(), free()
18+
#include <string.h> // Required for: memcpy()
1719

1820
//------------------------------------------------------------------------------------
1921
// Program main entry point
@@ -32,6 +34,17 @@ int main(void)
3234
Sound fxWav = LoadSound("resources/sound.wav"); // Load WAV audio file
3335
Sound fxOgg = LoadSound("resources/target.ogg"); // Load OGG audio file
3436

37+
bool soundReversed = false;
38+
39+
float *soundData = malloc(sizeof(float)*fxWav.frameCount*fxWav.stream.channels);
40+
float *scratchSoundData = malloc(sizeof(float)*fxWav.frameCount*fxWav.stream.channels);
41+
42+
Wave wave = LoadWave("resources/sound.wav");
43+
// Sounds always have 32bit sampleSize:
44+
WaveFormat(&wave, fxWav.stream.sampleRate, 32, fxWav.stream.channels);
45+
memcpy(soundData, wave.data, sizeof(float)*fxWav.frameCount*fxWav.stream.channels);
46+
UnloadWave(wave);
47+
3548
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
3649
//--------------------------------------------------------------------------------------
3750

@@ -40,6 +53,18 @@ int main(void)
4053
{
4154
// Update
4255
//----------------------------------------------------------------------------------
56+
if (IsKeyPressed(KEY_R))
57+
{
58+
soundReversed = !soundReversed;
59+
for (unsigned int i = 0; i < fxWav.frameCount; i++)
60+
{
61+
unsigned int src = (soundReversed)? fxWav.frameCount - 1 - i : i;
62+
// Sounds always have STEREO channels:
63+
scratchSoundData[i * fxWav.stream.channels + 0] = soundData[src * fxWav.stream.channels + 0];
64+
scratchSoundData[i * fxWav.stream.channels + 1] = soundData[src * fxWav.stream.channels + 1];
65+
}
66+
UpdateSound(fxWav, scratchSoundData, fxWav.frameCount);
67+
}
4368
if (IsKeyPressed(KEY_SPACE)) PlaySound(fxWav); // Play WAV sound
4469
if (IsKeyPressed(KEY_ENTER)) PlaySound(fxOgg); // Play OGG sound
4570
//----------------------------------------------------------------------------------
@@ -51,14 +76,18 @@ int main(void)
5176
ClearBackground(RAYWHITE);
5277

5378
DrawText("Press SPACE to PLAY the WAV sound!", 200, 180, 20, LIGHTGRAY);
54-
DrawText("Press ENTER to PLAY the OGG sound!", 200, 220, 20, LIGHTGRAY);
79+
DrawText(TextFormat("Press R to REVERSE the WAV sound : "), 120, 220, 20, LIGHTGRAY);
80+
DrawText((soundReversed)? "BACKWARDS" : "FORWARDS", 525, 220, 20, (soundReversed)? MAROON : DARKGREEN);
81+
DrawText("Press ENTER to PLAY the OGG sound!", 200, 260, 20, LIGHTGRAY);
5582

5683
EndDrawing();
5784
//----------------------------------------------------------------------------------
5885
}
5986

6087
// De-Initialization
6188
//--------------------------------------------------------------------------------------
89+
free(soundData);
90+
free(scratchSoundData);
6291
UnloadSound(fxWav); // Unload sound data
6392
UnloadSound(fxOgg); // Unload sound data
6493

549 Bytes
Loading

0 commit comments

Comments
 (0)