Skip to content

Instantly share code, notes, and snippets.

@hatkidchan
Created February 18, 2023 20:21
Show Gist options
  • Select an option

  • Save hatkidchan/28e37d692cc533bb14f9d8b1a6df65e6 to your computer and use it in GitHub Desktop.

Select an option

Save hatkidchan/28e37d692cc533bb14f9d8b1a6df65e6 to your computer and use it in GitHub Desktop.
// x-run: ~/scripts/runc.sh % libraylib.a -lm
#include "raylib.h"
#include <math.h>
#include <raylib.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
void audio_callback(float *_buf, unsigned int frames);
void sound_generator(short *buffer, unsigned int frames);
#define BUFFER_SIZE 2048
float audio_buffer[BUFFER_SIZE];
size_t buf_offset = 0;
int frames_requested = 0, frames_drawn = 0;
int main(void) {
InitWindow(512, 512, "");
InitAudioDevice();
AttachAudioMixedProcessor((AudioCallback)audio_callback);
SetTargetFPS(120);
SetAudioStreamBufferSizeDefault(BUFFER_SIZE);
AudioStream stream = LoadAudioStream(44100, 16, 2);
SetAudioStreamCallback(stream, (AudioCallback)sound_generator);
PlayAudioStream(stream);
ClearBackground(BLACK);
while (!WindowShouldClose()) {
BeginDrawing();
BeginBlendMode(BLEND_ALPHA);
DrawRectangle(0, 0, 512, 512, Fade(BLACK, GetFrameTime() * 10.0));
EndBlendMode();
BeginBlendMode(BLEND_ADDITIVE);
Vector2 oscilloscope[2][BUFFER_SIZE / 2];
int n_frames = BUFFER_SIZE / 2;
for (int i = 0; i < BUFFER_SIZE / 2; i++) {
float left = audio_buffer[i * 2 + 0], right = audio_buffer[i * 2 + 1];
Vector2 point = { 256 + left * 256, 256 - right * 256 };
DrawPixelV(point, Fade(GREEN, (n_frames - i) / (float)n_frames));
oscilloscope[0][i].x = i * 2.0;
oscilloscope[0][i].y = 512 - 128 - left * 128;
oscilloscope[1][i].x = i * 2.0;
oscilloscope[1][i].y = 512 - 128 - right * 128;
}
DrawLineStrip(oscilloscope[0], BUFFER_SIZE / 2, Fade(BLUE, 0.1));
DrawLineStrip(oscilloscope[1], BUFFER_SIZE / 2, Fade(RED, 0.1));
DrawFPS(8, 8);
DrawText(TextFormat("Frames generated: %d", frames_requested), 8, 32, 20, GRAY);
DrawText(TextFormat("Frames drawn: %d", frames_drawn), 8, 52, 20, GRAY);
if (frames_drawn > 0) {
DrawText(TextFormat("gen / drawn: %.9f", (float)frames_requested / (float)frames_drawn), 8, 72, 20, GRAY);
}
EndBlendMode();
EndDrawing();
}
}
float saw(double dt) {
return fmodf(dt, M_PI * 2.0) / M_PI - 1.0;
}
static float dt = 0.0;
void sound_generator(short *buffer, unsigned int frames) {
for (int i = 0; i < frames; i++) {
dt += 10000.0 * M_PI / 44100.0;
buffer[i * 2 + 0] = sinf(dt) * (saw(dt / 64.0) > 0.5 ? sin(dt / 64.0) : 0.1) * 8192;
buffer[i * 2 + 0] += saw(dt / 64.5 + M_PI) * cos(dt / 129.0) * 4096;
buffer[i * 2 + 1] = saw(dt / 64.0) * 16384;
}
frames_requested += frames;
}
void audio_callback(float *_buf, unsigned int frames) {
ssize_t can_write = BUFFER_SIZE - buf_offset;
if (frames > can_write) {
memcpy(&audio_buffer[buf_offset], _buf, can_write * sizeof(float));
memcpy(&audio_buffer[0], _buf + frames - can_write, frames - can_write);
buf_offset = frames - can_write;
} else {
memcpy(&audio_buffer[buf_offset], _buf, frames * sizeof(float));
buf_offset += frames;
}
frames_drawn += frames;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment