mirror of
https://github.com/OpenRTX/OpenRTX
synced 2026-08-08 12:29:06 -04:00
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:
parent
5c0df5478e
commit
578c48a39c
4 changed files with 153 additions and 3 deletions
|
|
@ -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':''}
|
||||
|
||||
|
|
|
|||
108
platform/drivers/tones/toneGenerator_sdl.cpp
Normal file
108
platform/drivers/tones/toneGenerator_sdl.cpp
Normal 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);
|
||||
}
|
||||
39
platform/drivers/tones/toneGenerator_sdl.h
Normal file
39
platform/drivers/tones/toneGenerator_sdl.h
Normal 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 */
|
||||
|
|
@ -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()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue