raw stream
There is no browser build of this example yet.
Is it the same as C?
- Desktop:builds The Zig version builds, but it is not compared with C, because the C example does not give the same frame twice: self-nondeterministic (C vs C differs): waveform depends on audio-callback timing.
- Browser:not checked yet The browser comparison does not cover this example yet.
//! raylib [audio] example - raw stream
//!
//! Zig-API translation of examples/audio/audio_raw_stream.c (raylib 6.2).
//! Example licensed under an unmodified zlib/libpng license.
//! Copyright (c) 2015-2026 Ramon Santamaria (@raysan5) and James Hofmann (@triplefox)
const rl = @import("raylib");
const buffer_size = 4096;
const sample_rate = 44100;
/// sin(2*PI*t/wavelength), with C's float evaluation order.
fn sineAt(t: i32, wavelength: i32) f32 {
return @sin(2 * rl.pi * @as(f32, @floatFromInt(t)) / @as(f32, @floatFromInt(wavelength)));
}
pub fn main() !void {
// Initialization
const screen_width = 800;
const screen_height = 450;
rl.initWindow(screen_width, screen_height, "raylib [audio] example - raw stream");
defer rl.closeWindow(); // Close window and OpenGL context
rl.initAudioDevice();
defer rl.closeAudioDevice(); // Close audio device (music streaming is automatically stopped)
// Set the number of samples the stream will keep in memory at a time to buffer_size
rl.setAudioStreamBufferSizeDefault(buffer_size);
var buffer: [buffer_size]f32 = @splat(0.0);
// Init raw audio stream (sample rate: 44100, sample size: 32bit-float, channels: 1-mono)
const stream = try rl.loadAudioStream(sample_rate, 32, 1);
defer rl.unloadAudioStream(stream); // Close raw audio stream and delete buffers from RAM
var pan: f32 = 0.0;
rl.setAudioStreamPan(stream, pan);
rl.playAudioStream(stream);
var sine_frequency: i32 = 440;
var new_sine_frequency: i32 = 440;
var sine_index: i32 = 0;
var sine_start_time: f64 = 0.0;
rl.setTargetFPS(30);
// Main game loop
while (!rl.windowShouldClose()) { // Detect window close button or ESC key
// Update
if (rl.isKeyDown(.up)) new_sine_frequency = @min(new_sine_frequency + 10, 12500);
if (rl.isKeyDown(.down)) new_sine_frequency = @max(new_sine_frequency - 10, 20);
if (rl.isKeyDown(.left)) {
pan -= 0.01;
if (pan < -1.0) pan = -1.0;
rl.setAudioStreamPan(stream, pan);
}
if (rl.isKeyDown(.right)) {
pan += 0.01;
if (pan > 1.0) pan = 1.0;
rl.setAudioStreamPan(stream, pan);
}
if (rl.isAudioStreamProcessed(stream)) {
for (&buffer) |*sample| {
const wavelength = @divTrunc(sample_rate, sine_frequency);
sample.* = sineAt(sine_index, wavelength);
sine_index += 1;
if (sine_index >= wavelength) {
sine_frequency = new_sine_frequency;
sine_index = 0;
sine_start_time = rl.getTime();
}
}
rl.updateAudioStream(stream, &buffer, buffer_size);
}
// Draw
rl.beginDrawing();
defer rl.endDrawing();
rl.clearBackground(.ray_white);
rl.drawText(rl.textFormat("sine frequency: {d}", .{sine_frequency}), screen_width - 220, 10, 20, .red);
rl.drawText(rl.textFormat("pan: {d:.2}", .{pan}), screen_width - 220, 30, 20, .red);
rl.drawText("Up/down to change frequency", 10, 10, 20, .dark_gray);
rl.drawText("Left/right to pan", 10, 30, 20, .dark_gray);
const window_start: i32 = @intFromFloat((rl.getTime() - sine_start_time) * sample_rate);
const window_size = sample_rate / 10;
const wavelength = @divTrunc(sample_rate, sine_frequency);
// Draw a sine wave with the same frequency as the one being sent to the audio stream
for (0..screen_width) |column| {
const i: i32 = @intCast(column);
const t0 = window_start + @divTrunc(i * window_size, screen_width);
const t1 = window_start + @divTrunc((i + 1) * window_size, screen_width);
const x: f32 = @floatFromInt(i);
const start_pos: rl.Vector2 = .{ .x = x, .y = 250 + 50 * sineAt(t0, wavelength) };
const end_pos: rl.Vector2 = .{ .x = x + 1, .y = 250 + 50 * sineAt(t1, wavelength) };
rl.drawLineV(start_pos, end_pos, .red);
}
}
}/*******************************************************************************************
*
* raylib [audio] example - raw stream
*
* Example complexity rating: [★★★☆] 3/4
*
* 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)
*
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
* BSD-like license that allows static linking with closed source software
*
* Copyright (c) 2015-2026 Ramon Santamaria (@raysan5) and James Hofmann (@triplefox)
*
********************************************************************************************/
#include "raylib.h"
#include <math.h>
#define BUFFER_SIZE 4096
#define SAMPLE_RATE 44100
//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
int main(void)
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [audio] example - raw stream");
InitAudioDevice();
// Set the number of samples the stream will keep in memory at a time to BUFFER_SIZE
SetAudioStreamBufferSizeDefault(BUFFER_SIZE);
float buffer[BUFFER_SIZE] = {};
// Init raw audio stream (sample rate: 44100, sample size: 32bit-float, channels: 1-mono)
AudioStream stream = LoadAudioStream(SAMPLE_RATE, 32, 1);
float pan = 0.0f;
SetAudioStreamPan(stream, pan);
PlayAudioStream(stream);
int sineFrequency = 440;
int newSineFrequency = 440;
int sineIndex = 0;
double sineStartTime = 0.0;
SetTargetFPS(30);
//--------------------------------------------------------------------------------------
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
if (IsKeyDown(KEY_UP))
{
newSineFrequency += 10;
if (newSineFrequency > 12500) newSineFrequency = 12500;
}
if (IsKeyDown(KEY_DOWN))
{
newSineFrequency -= 10;
if (newSineFrequency < 20) newSineFrequency = 20;
}
if (IsKeyDown(KEY_LEFT))
{
pan -= 0.01f;
if (pan < -1.0f) pan = -1.0f;
SetAudioStreamPan(stream, pan);
}
if (IsKeyDown(KEY_RIGHT))
{
pan += 0.01f;
if (pan > 1.0f) pan = 1.0f;
SetAudioStreamPan(stream, pan);
}
if (IsAudioStreamProcessed(stream))
{
for (int i = 0; i < BUFFER_SIZE; i++)
{
int wavelength = SAMPLE_RATE/sineFrequency;
buffer[i] = sinf(2*PI*sineIndex/wavelength);
sineIndex++;
if (sineIndex >= wavelength)
{
sineFrequency = newSineFrequency;
sineIndex = 0;
sineStartTime = GetTime();
}
}
UpdateAudioStream(stream, buffer, BUFFER_SIZE);
}
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
DrawText(TextFormat("sine frequency: %i", sineFrequency), screenWidth - 220, 10, 20, RED);
DrawText(TextFormat("pan: %.2f", pan), screenWidth - 220, 30, 20, RED);
DrawText("Up/down to change frequency", 10, 10, 20, DARKGRAY);
DrawText("Left/right to pan", 10, 30, 20, DARKGRAY);
int windowStart = (int)((GetTime() - sineStartTime)*SAMPLE_RATE);
int windowSize = SAMPLE_RATE/10;
int wavelength = SAMPLE_RATE/sineFrequency;
// Draw a sine wave with the same frequency as the one being sent to the audio stream
for (int i = 0; i < screenWidth; i++)
{
int t0 = windowStart + i*windowSize/screenWidth;
int t1 = windowStart + (i + 1)*windowSize/screenWidth;
Vector2 startPos = { (float)i, 250 + 50*sinf(2*PI*t0/wavelength) };
Vector2 endPos = { (float)i + 1, 250 + 50*sinf(2*PI*t1/wavelength) };
DrawLineV(startPos, endPos, RED);
}
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
UnloadAudioStream(stream); // Close raw audio stream and delete buffers from RAM
CloseAudioDevice(); // Close audio device (music streaming is automatically stopped)
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}From raylib 6.2. The original on GitHub.