voice-chat/src/main.c

96 lines
2.5 KiB
C
Raw Normal View History

// beep.c
// Build (Linux/macOS): cc beep.c -lm -o beep
// Build (Windows MSVC): cl /O2 beep.c
#define MINIAUDIO_IMPLEMENTATION
#include "miniaudio.h"
2026-01-14 22:49:49 -05:00
#include <math.h>
#include <stdint.h>
#include <stdio.h>
2026-01-14 22:49:49 -05:00
typedef struct {
double phase;
double phase_inc;
uint32_t frames_left;
ma_uint32 channels;
} beep_state;
static void data_callback(ma_device* dev, void* out, const void* in, ma_uint32 frameCount)
2026-01-14 22:49:49 -05:00
{
(void)in;
beep_state* s = (beep_state*)dev->pUserData;
float* output = (float*)out;
2026-01-14 22:49:49 -05:00
ma_uint32 framesToWrite = frameCount;
if (s->frames_left < framesToWrite) framesToWrite = s->frames_left;
2026-01-14 22:49:49 -05:00
for (ma_uint32 i = 0; i < framesToWrite; i++) {
float sample = (float)sin(s->phase) * 0.2f; // volume
s->phase += s->phase_inc;
2026-01-14 22:49:49 -05:00
// keep phase bounded (optional)
if (s->phase >= (2.0 * M_PI)) s->phase -= (2.0 * M_PI);
2026-01-14 22:49:49 -05:00
for (ma_uint32 ch = 0; ch < s->channels; ch++) {
output[i * s->channels + ch] = sample;
}
2026-01-14 22:49:49 -05:00
}
// If we ran out early, zero the rest (silence).
for (ma_uint32 i = framesToWrite; i < frameCount; i++) {
for (ma_uint32 ch = 0; ch < s->channels; ch++) {
output[i * s->channels + ch] = 0.0f;
}
2026-01-14 22:49:49 -05:00
}
s->frames_left -= framesToWrite;
2026-01-14 22:49:49 -05:00
// Stop after the beep finishes.
if (s->frames_left == 0) {
ma_device_stop(dev); // safe to request stop
2026-01-14 22:49:49 -05:00
}
}
2026-01-14 22:49:49 -05:00
int main(void)
{
const double freq = 440.0;
const ma_uint32 sampleRate = 48000;
const double durationSec = 1.0;
beep_state s = {0};
s.phase = 0.0;
s.phase_inc = (2.0 * M_PI * freq) / (double)sampleRate;
s.frames_left = (uint32_t)(durationSec * (double)sampleRate);
ma_device_config cfg = ma_device_config_init(ma_device_type_playback);
cfg.playback.format = ma_format_f32;
cfg.playback.channels = 2;
cfg.sampleRate = sampleRate;
cfg.dataCallback = data_callback;
cfg.pUserData = &s;
ma_device dev;
if (ma_device_init(NULL, &cfg, &dev) != MA_SUCCESS) {
fprintf(stderr, "Failed to init audio device\n");
2026-01-14 22:49:49 -05:00
return 1;
}
s.channels = dev.playback.channels; // in case backend adjusts
2026-01-14 22:49:49 -05:00
if (ma_device_start(&dev) != MA_SUCCESS) {
fprintf(stderr, "Failed to start audio device\n");
ma_device_uninit(&dev);
2026-01-14 22:49:49 -05:00
return 1;
}
// Wait until callback stops the device.
while (ma_device_is_started(&dev)) {
ma_sleep(10);
2026-01-14 22:49:49 -05:00
}
ma_device_uninit(&dev);
2026-01-14 22:33:58 -05:00
return 0;
}