/* * * Singe 3 * Copyright (C) 2006-2026 Scott Duensing * * 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 #include // 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