drivers: tones: add SDL-based beep generator

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Ryan Turner <ryan@turnrye.com>
This commit is contained in:
Ryan Turner 2026-07-23 21:58:09 -05:00 committed by Silvano Seva
parent 5c0df5478e
commit 578c48a39c
4 changed files with 153 additions and 3 deletions

View file

@ -356,12 +356,14 @@ linux_src = ['platform/targets/linux/emulator/emulator.c',
'platform/drivers/audio/file_source.c',
'platform/drivers/audio/audio_sdl.cpp',
'platform/targets/linux/platform.c',
'platform/drivers/tones/toneGenerator_sdl.cpp',
'platform/drivers/CPS/cps_io_libc.c',
'platform/drivers/NVM/posix_file.c']
linux_inc = ['platform/targets/linux',
'platform/targets/linux/emulator',
'platform/drivers/audio']
'platform/drivers/audio',
'platform/drivers/tones']
linux_def = {'PLATFORM_LINUX': '', 'VP_USE_FILESYSTEM':''}

View file

@ -0,0 +1,108 @@
/*
* SPDX-FileCopyrightText: Copyright 2020-2026 OpenRTX Contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
#include <math.h>
#include <pthread.h>
#include "SDL2/SDL.h"
#include "toneGenerator_sdl.h"
#include "interfaces/audio.h"
#define BEEP_RATE 48000
#define BEEP_CHUNK (BEEP_RATE / 50) // 20 ms of samples
#define BEEP_AMPLITUDE 8000
// Number of extra queued chunks tolerated before a playback sync() blocks.
#define PLAY_QUEUE_SLACK 2
static pthread_t beepThread;
static pthread_once_t beepOnce = PTHREAD_ONCE_INIT;
static pthread_mutex_t beepMutex = PTHREAD_MUTEX_INITIALIZER;
static int beepActive = 0;
static uint16_t beepFreq = 0;
static void *beepThreadFunc(void *arg)
{
(void)arg;
SDL_AudioSpec want;
SDL_AudioSpec have;
SDL_zero(want);
want.freq = BEEP_RATE;
want.format = AUDIO_S16SYS;
want.channels = 1;
want.samples = 512;
SDL_AudioDeviceID dev = SDL_OpenAudioDevice(NULL, 0, &want, &have, 0);
if (dev == 0)
return NULL;
stream_sample_t chunk[BEEP_CHUNK];
double phase = 0.0;
int playing = 0;
for (;;) {
pthread_mutex_lock(&beepMutex);
int active = beepActive;
uint16_t freq = beepFreq;
pthread_mutex_unlock(&beepMutex);
if (active != 0) {
if (playing == 0) {
SDL_ClearQueuedAudio(dev);
SDL_PauseAudioDevice(dev, 0);
playing = 1;
}
double step = (2.0 * M_PI * (double)freq) / (double)BEEP_RATE;
for (size_t i = 0; i < BEEP_CHUNK; i++) {
chunk[i] = (stream_sample_t)(BEEP_AMPLITUDE * sin(phase));
phase += step;
if (phase >= (2.0 * M_PI))
phase -= (2.0 * M_PI);
}
Uint32 chunkBytes = (Uint32)sizeof(chunk);
while (SDL_GetQueuedAudioSize(dev)
> (PLAY_QUEUE_SLACK * chunkBytes))
SDL_Delay(1);
SDL_QueueAudio(dev, chunk, chunkBytes);
} else {
if (playing != 0) {
SDL_ClearQueuedAudio(dev);
SDL_PauseAudioDevice(dev, 1);
playing = 0;
phase = 0.0;
}
SDL_Delay(5);
}
}
return NULL;
}
static void beepThreadStart(void)
{
pthread_create(&beepThread, NULL, beepThreadFunc, NULL);
}
void toneGen_sdl_start(uint16_t freq)
{
pthread_once(&beepOnce, beepThreadStart);
pthread_mutex_lock(&beepMutex);
beepFreq = freq;
beepActive = 1;
pthread_mutex_unlock(&beepMutex);
}
void toneGen_sdl_stop(void)
{
pthread_mutex_lock(&beepMutex);
beepActive = 0;
pthread_mutex_unlock(&beepMutex);
}

View file

@ -0,0 +1,39 @@
/*
* SPDX-FileCopyrightText: Copyright 2020-2026 OpenRTX Contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
#ifndef TONE_GENERATOR_SDL_H
#define TONE_GENERATOR_SDL_H
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* SDL2-backed beep tone generator for the Linux emulator and WebAssembly
* targets. Drives a dedicated audio device on a background thread that
* synthesizes a phase-continuous sine wave.
*/
/**
* Start a continuous beep tone at the given frequency on a dedicated output
* device. Calling it again while a beep is active retunes the tone.
*
* @param freq: beep frequency, in Hz.
*/
void toneGen_sdl_start(uint16_t freq);
/**
* Stop an ongoing beep tone.
*/
void toneGen_sdl_stop(void);
#ifdef __cplusplus
}
#endif
#endif /* TONE_GENERATOR_SDL_H */

View file

@ -10,6 +10,7 @@
#include <stdio.h>
#include "core/gps.h"
#include "emulator.h"
#include "toneGenerator_sdl.h"
/*
* Create the data structure holding Module17 calibration data to make the
@ -109,12 +110,12 @@ void platform_ledOff(led_t led)
void platform_beepStart(uint16_t freq)
{
printf("platform_beepStart(%u)\n", freq);
toneGen_sdl_start(freq);
}
void platform_beepStop()
{
printf("platform_beepStop()\n");
toneGen_sdl_stop();
}
datetime_t platform_getCurrentTime()