98 lines
3.9 KiB
C
98 lines
3.9 KiB
C
/*
|
|
*
|
|
* Singe 3
|
|
* Copyright (C) 2006-2026 Scott Duensing <scott@kangaroopunch.com>
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 3
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
* 02110-1301, USA.
|
|
*
|
|
*/
|
|
|
|
|
|
#ifndef MIC_H
|
|
#define MIC_H
|
|
|
|
|
|
#include <stdbool.h>
|
|
#include <stdint.h>
|
|
|
|
|
|
// The microphone: one recording device at a time, heard as mono float samples at MIC_RATE. SDL's
|
|
// stream callback keeps the newest of them in a ring, with the level of each block; everything a
|
|
// game asks is answered from that ring on the engine's thread (PLAN.md section 62).
|
|
|
|
#define MIC_RATE 48000 // Opus's native rate, so a voice frame needs no resampling
|
|
#define MIC_LATENCY_UNKNOWN -1 // micLatency before any calibration has finished
|
|
#define MIC_LATENCY_MAX 1000 // A measured latency longer than this is not believed
|
|
#define MIC_RING_SECONDS 8 // The newest this much is kept; a slower reader loses the rest
|
|
|
|
typedef enum MicCalibrationE {
|
|
MIC_CALIBRATION_IDLE = 0, // Nothing asked, or the last one finished
|
|
MIC_CALIBRATION_RUNNING = 1,
|
|
MIC_CALIBRATION_DONE = 2, // micLatency holds the answer
|
|
MIC_CALIBRATION_FAILED = 3 // The clicks were never heard back
|
|
} MicCalibrationE;
|
|
|
|
|
|
// Starts a latency measurement: clicks played through the speakers and timed coming back through
|
|
// the microphone. False when no microphone is open or the speakers cannot be opened.
|
|
bool micCalibrate(void);
|
|
|
|
MicCalibrationE micCalibrationState(void);
|
|
|
|
void micClose(void);
|
|
|
|
// The recording devices SDL can see, and each one's name (NULL when the index names none). The
|
|
// list is taken afresh by micDeviceCount.
|
|
int32_t micDeviceCount(void);
|
|
const char *micDeviceName(int32_t index);
|
|
|
|
bool micIsOpen(void);
|
|
|
|
// The milliseconds between a sound being made and the game hearing it, or MIC_LATENCY_UNKNOWN.
|
|
int32_t micLatency(void);
|
|
|
|
// RMS and peak of the last block heard, 0 to 1.
|
|
void micLevel(float *rms, float *peak);
|
|
|
|
// Plays what the microphone hears through the speakers, at volume 0 to 1. Off by default.
|
|
bool micMonitor(bool on, float volume);
|
|
|
|
// Opens a recording device by name, or the default for NULL. Closes one already open.
|
|
bool micOpen(const char *name);
|
|
|
|
// The fundamental of what was heard most recently, in Hz, and how clearly periodic it is, 0 to 1;
|
|
// 0 Hz when nothing voiced is there.
|
|
void micPitch(float *hz, float *clarity);
|
|
|
|
void micQuit(void);
|
|
|
|
// Up to max samples heard since the last read, as 16-bit, oldest first. Returns how many. A reader
|
|
// that falls a whole ring behind skips to the oldest still kept.
|
|
int32_t micRead(int16_t *out, int32_t max);
|
|
|
|
// Writes everything heard from now on to a 16-bit mono WAV file at path, until micRecordStop.
|
|
bool micRecordStart(const char *path);
|
|
void micRecordStop(void);
|
|
|
|
// Sets the latency a game already knows (from the machine settings), MIC_LATENCY_UNKNOWN to forget.
|
|
void micSetLatency(int32_t milliseconds);
|
|
|
|
// Once a frame on the engine's thread: the recording written, the calibration stepped. True on the
|
|
// frame a calibration finishes with an answer, so the caller can keep it.
|
|
bool micUpdate(void);
|
|
|
|
|
|
#endif // MIC_H
|