Skip to content

Commit 79a6188

Browse files
committed
copy audio_raw_stream.c to new file as-is
1 parent 8ae2c9c commit 79a6188

File tree

2 files changed

+215
-0
lines changed

2 files changed

+215
-0
lines changed

examples/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -707,6 +707,7 @@ AUDIO = \
707707
audio/audio_module_playing \
708708
audio/audio_music_stream \
709709
audio/audio_raw_stream \
710+
audio/audio_raw_stream_callback \
710711
audio/audio_sound_loading \
711712
audio/audio_sound_multi \
712713
audio/audio_sound_positioning \
Lines changed: 214 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,214 @@
1+
/*******************************************************************************************
2+
*
3+
* raylib [audio] example - raw stream
4+
*
5+
* Example complexity rating: [★★★☆] 3/4
6+
*
7+
* Example originally created with raylib 1.6, last time updated with raylib 4.2
8+
*
9+
* Example created by Ramon Santamaria (@raysan5) and reviewed by James Hofmann (@triplefox)
10+
*
11+
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
12+
* BSD-like license that allows static linking with closed source software
13+
*
14+
* Copyright (c) 2015-2025 Ramon Santamaria (@raysan5) and James Hofmann (@triplefox)
15+
*
16+
********************************************************************************************/
17+
18+
#include "raylib.h"
19+
20+
#include <stdlib.h> // Required for: malloc(), free()
21+
#include <math.h> // Required for: sinf()
22+
#include <string.h> // Required for: memcpy()
23+
24+
#define MAX_SAMPLES 512
25+
#define MAX_SAMPLES_PER_UPDATE 4096
26+
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+
55+
//------------------------------------------------------------------------------------
56+
// Program main entry point
57+
//------------------------------------------------------------------------------------
58+
int main(void)
59+
{
60+
// Initialization
61+
//--------------------------------------------------------------------------------------
62+
const int screenWidth = 800;
63+
const int screenHeight = 450;
64+
65+
InitWindow(screenWidth, screenHeight, "raylib [audio] example - raw stream");
66+
67+
InitAudioDevice(); // Initialize audio device
68+
69+
SetAudioStreamBufferSizeDefault(MAX_SAMPLES_PER_UPDATE);
70+
71+
// Init raw audio stream (sample rate: 44100, sample size: 16bit-short, channels: 1-mono)
72+
AudioStream stream = LoadAudioStream(44100, 16, 1);
73+
74+
SetAudioStreamCallback(stream, AudioInputCallback);
75+
76+
// Buffer for the single cycle waveform we are synthesizing
77+
short *data = (short *)malloc(sizeof(short)*MAX_SAMPLES);
78+
79+
// Frame buffer, describing the waveform when repeated over the course of a frame
80+
short *writeBuf = (short *)malloc(sizeof(short)*MAX_SAMPLES_PER_UPDATE);
81+
82+
PlayAudioStream(stream); // Start processing stream buffer (no data loaded currently)
83+
84+
// Position read in to determine next frequency
85+
Vector2 mousePosition = { -100.0f, -100.0f };
86+
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+
98+
// Computed size in samples of the sine wave
99+
int waveLength = 1;
100+
101+
Vector2 position = { 0, 0 };
102+
103+
SetTargetFPS(30); // Set our game to run at 30 frames-per-second
104+
//--------------------------------------------------------------------------------------
105+
106+
// Main game loop
107+
while (!WindowShouldClose()) // Detect window close button or ESC key
108+
{
109+
// Update
110+
//----------------------------------------------------------------------------------
111+
mousePosition = GetMousePosition();
112+
113+
if (IsMouseButtonDown(MOUSE_BUTTON_LEFT))
114+
{
115+
float fp = (float)(mousePosition.y);
116+
frequency = 40.0f + (float)(fp);
117+
118+
float pan = (float)(mousePosition.x)/(float)screenWidth;
119+
SetAudioStreamPan(stream, pan);
120+
}
121+
122+
// Rewrite the sine wave
123+
// Compute two cycles to allow the buffer padding, simplifying any modulation, resampling, etc.
124+
if (frequency != oldFrequency)
125+
{
126+
// Compute wavelength. Limit size in both directions
127+
//int oldWavelength = waveLength;
128+
waveLength = (int)(22050/frequency);
129+
if (waveLength > MAX_SAMPLES/2) waveLength = MAX_SAMPLES/2;
130+
if (waveLength < 1) waveLength = 1;
131+
132+
// Write sine wave
133+
for (int i = 0; i < waveLength*2; i++)
134+
{
135+
data[i] = (short)(sinf(((2*PI*(float)i/waveLength)))*32000);
136+
}
137+
// Make sure the rest of the line is flat
138+
for (int j = waveLength*2; j < MAX_SAMPLES; j++)
139+
{
140+
data[j] = (short)0;
141+
}
142+
143+
// Scale read cursor's position to minimize transition artifacts
144+
//readCursor = (int)(readCursor*((float)waveLength/(float)oldWavelength));
145+
oldFrequency = frequency;
146+
}
147+
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+
*/
178+
//----------------------------------------------------------------------------------
179+
180+
// Draw
181+
//----------------------------------------------------------------------------------
182+
BeginDrawing();
183+
184+
ClearBackground(RAYWHITE);
185+
186+
DrawText(TextFormat("sine frequency: %i",(int)frequency), GetScreenWidth() - 220, 10, 20, RED);
187+
DrawText("click mouse button to change frequency or pan", 10, 10, 20, DARKGRAY);
188+
189+
// Draw the current buffer state proportionate to the screen
190+
for (int i = 0; i < screenWidth; i++)
191+
{
192+
position.x = (float)i;
193+
position.y = 250 + 50*data[i*MAX_SAMPLES/screenWidth]/32000.0f;
194+
195+
DrawPixelV(position, RED);
196+
}
197+
198+
EndDrawing();
199+
//----------------------------------------------------------------------------------
200+
}
201+
202+
// De-Initialization
203+
//--------------------------------------------------------------------------------------
204+
free(data); // Unload sine wave data
205+
free(writeBuf); // Unload write buffer
206+
207+
UnloadAudioStream(stream); // Close raw audio stream and delete buffers from RAM
208+
CloseAudioDevice(); // Close audio device (music streaming is automatically stopped)
209+
210+
CloseWindow(); // Close window and OpenGL context
211+
//--------------------------------------------------------------------------------------
212+
213+
return 0;
214+
}

0 commit comments

Comments
 (0)