ascii-chat
Binary v0.15.83-53-gb711d8720
Library lib/v0.3.2-701-gb711d8720
Video chat in your terminal
Loading...
Searching...
No Matches
mixer.h
Go to the documentation of this file.
1#include <ascii-chat/common.h>
2#pragma once
3
78
79#include <stdbool.h>
80#include <stdint.h>
81
82// Include ringbuffer.h to get the audio_ring_buffer_t type
83#include "../ringbuffer.h"
84#include <libplatform/rwlock.h>
85#include "../asciichat_errno.h"
86
87#ifdef __cplusplus
88extern "C" {
89#endif
90
96
105#define MIXER_MAX_SOURCES MAX_SESSION_PARTICIPANTS
106#define MIXER_MASK_WORDS ((MIXER_MAX_SOURCES + 63) / 64)
107
116#define MIXER_FRAME_SIZE 256
117
119
164
204
222typedef struct {
227
229 float alpha;
235
247typedef struct {
252
254 float alpha;
258
298
377
383
397mixer_t *mixer_create(int max_sources, int sample_rate);
398mixer_t *mixer_create_channels(int max_sources, int sample_rate, unsigned channels);
400int mixer_source_count(const mixer_t *mixer);
401
413void mixer_destroy(mixer_t *mixer);
414
416
422
439int mixer_add_source(mixer_t *mixer, const char *client_id, audio_ring_buffer_t *buffer);
440
455void mixer_remove_source(mixer_t *mixer, const char *client_id);
456
472void mixer_set_source_active(mixer_t *mixer, const char *client_id, bool active);
473
474/* ============================================================================
475 * Mixer Hash Table Helpers (Internal API)
476 * ============================================================================ */
477
479#define MIXER_HASH_INVALID 0xFF
480
487static inline uint8_t mixer_hash_client_id(uint32_t client_id) {
488 return (uint8_t)(client_id & 0xFF);
489}
490
497static inline void mixer_hash_mark_invalid(mixer_t *mixer, uint32_t client_id) {
498 if (mixer) {
499 mixer->source_id_to_index[mixer_hash_client_id(client_id)] = MIXER_HASH_INVALID;
500 }
501}
502
510static inline void mixer_hash_set_slot(mixer_t *mixer, uint32_t client_id, uint8_t slot) {
511 if (mixer) {
512 mixer->source_id_to_index[mixer_hash_client_id(client_id)] = slot;
513 }
514}
515
523static inline bool mixer_hash_is_invalid(mixer_t *mixer, uint32_t client_id) {
524 if (!mixer)
525 return true;
526 return mixer->source_id_to_index[mixer_hash_client_id(client_id)] == MIXER_HASH_INVALID;
527}
528
536static inline uint8_t mixer_hash_get_slot(mixer_t *mixer, uint32_t client_id) {
537 if (!mixer)
538 return MIXER_HASH_INVALID;
539 return mixer->source_id_to_index[mixer_hash_client_id(client_id)];
540}
541
543
549
570int mixer_process(mixer_t *mixer, float *output, int num_samples);
571
590int mixer_process_excluding_source(mixer_t *mixer, float *output, int num_samples, uint32_t exclude_client_id);
591
593
599
609float db_to_linear(float db);
610
620float linear_to_db(float linear);
621
634float clamp_float(float value, float min, float max);
635
637
643
654void compressor_init(compressor_t *comp, float sample_rate);
655
670void compressor_set_params(compressor_t *comp, float threshold_dB, float ratio, uint64_t attack_ns, uint64_t release_ns,
671 float makeup_dB);
672
687float compressor_process_sample(compressor_t *comp, float sidechain);
688
690
696
711int ducking_init(ducking_t *duck, int num_sources, float sample_rate);
712
721void ducking_destroy(ducking_t *duck);
722
737void ducking_set_params(ducking_t *duck, float threshold_dB, float leader_margin_dB, float atten_dB, uint64_t attack_ns,
738 uint64_t release_ns);
739
755void ducking_process_frame(ducking_t *duck, float *envelopes, float *gains, int num_sources);
756
758
764
775void noise_gate_init(noise_gate_t *gate, float sample_rate);
776
790void noise_gate_set_params(noise_gate_t *gate, float threshold, uint64_t attack_ns, uint64_t release_ns,
791 float hysteresis);
792
807float noise_gate_process_sample(noise_gate_t *gate, float input, float peak_amplitude);
808
821void noise_gate_process_buffer(noise_gate_t *gate, float *buffer, int num_samples);
822
832bool noise_gate_is_open(const noise_gate_t *gate);
833
835
841
853void highpass_filter_init(highpass_filter_t *filter, float cutoff_hz, float sample_rate);
854
865
877float highpass_filter_process_sample(highpass_filter_t *filter, float input);
878
889void highpass_filter_process_buffer(highpass_filter_t *filter, float *buffer, int num_samples);
890
892
898
910void lowpass_filter_init(lowpass_filter_t *filter, float cutoff_hz, float sample_rate);
911
921
933float lowpass_filter_process_sample(lowpass_filter_t *filter, float input);
934
945void lowpass_filter_process_buffer(lowpass_filter_t *filter, float *buffer, int num_samples);
946
948
954
965float smoothstep(float t);
966
977int16_t float_to_int16(float sample);
978
988float int16_to_float(int16_t sample);
989
1000void buffer_float_to_int16(const float *src, int16_t *dst, int count);
1001
1012void buffer_int16_to_float(const int16_t *src, float *dst, int count);
1013
1025float buffer_peak(const float *buffer, int count);
1026
1037void apply_gain_buffer(float *buffer, int count, float gain);
1038
1051void fade_buffer(float *buffer, int count, float start_gain, float end_gain);
1052
1063void fade_buffer_smooth(float *buffer, int count, bool fade_in);
1064
1077void copy_buffer_with_gain(const float *src, float *dst, int count, float gain);
1078
1080
1086
1107float soft_clip(float sample, float threshold, float steepness);
1108
1120void soft_clip_buffer(float *buffer, int num_samples, float threshold, float steepness);
1121
1123
1124#ifdef __cplusplus
1125}
1126#endif
Synchronized per-thread pending error stacks and value snapshots. SET_ERRNO pushes,...
⚙️ Common definitions, error codes, macros, and types shared throughout the application
float hysteresis
Hysteresis factor (0-1, prevents gate chatter).
Definition mixer.h:191
float release_coeff
Release coefficient (converted from release_ms).
Definition mixer.h:200
struct spectral_processor * spectral_left[128+1]
Definition mixer.h:342
bool noise_gate_is_open(const noise_gate_t *gate)
Check if noise gate is currently open.
Definition effects.c:178
uint8_t source_id_to_index[256]
Hash table mapping client_id → mixer source index (uses hash function for strings).
Definition mixer.h:357
float base_gain
Base gain before crowd scaling is applied.
Definition mixer.h:367
void copy_buffer_with_gain(const float *src, float *dst, int count, float gain)
Copy buffer with gain scaling.
Definition effects.c:395
float leader_margin_dB
Leader margin in dB (sources within this of loudest are leaders).
Definition mixer.h:281
void noise_gate_process_buffer(noise_gate_t *gate, float *buffer, int num_samples)
Process a buffer of samples through noise gate.
Definition effects.c:159
void buffer_float_to_int16(const float *src, int16_t *dst, int count)
Convert float buffer to int16 buffer.
Definition effects.c:334
float alpha
Filter coefficient alpha (calculated from cutoff_hz).
Definition mixer.h:229
float release_coeff
Release coefficient (converted from release_ms).
Definition mixer.h:292
float clamp_float(float value, float min, float max)
Clamp a float value to a range.
Definition effects.c:18
const char ** source_ids
Array of client ID strings (one per source slot).
Definition mixer.h:350
float ratio
Compression ratio (e.g., 4.0 for 4:1 compression).
Definition mixer.h:145
void highpass_filter_reset(highpass_filter_t *filter)
Reset high-pass filter state.
Definition effects.c:201
float sample_rate
Sample rate in Hz (set during initialization).
Definition mixer.h:226
void soft_clip_buffer(float *buffer, int num_samples, float threshold, float steepness)
Apply soft clipping to a buffer.
Definition effects.c:299
float prev_input
Previous input sample (filter state).
Definition mixer.h:231
float prev_output
Previous output sample (filter state).
Definition mixer.h:256
struct spectral_processor * spectral_right[128+1]
Definition mixer.h:343
#define MIXER_MAX_SOURCES
Maximum number of simultaneous audio sources.
Definition mixer.h:105
float highpass_filter_process_sample(highpass_filter_t *filter, float input)
Process a single sample through high-pass filter.
Definition effects.c:209
float envelope
Current envelope follower state (linear, 0-1).
Definition mixer.h:156
bool * source_active
Array of active flags (true if source is active).
Definition mixer.h:352
float cutoff_hz
Cutoff frequency in Hz (frequencies above this are attenuated).
Definition mixer.h:249
void apply_gain_buffer(float *buffer, int count, float gain)
Apply gain to buffer in-place.
Definition effects.c:363
float atten_dB
Attenuation in dB for non-leader sources.
Definition mixer.h:283
rwlock_t source_lock
Reader-writer lock protecting source arrays and bitset.
Definition mixer.h:362
atomic_t active_sources
Definition mixer.h:335
float * gain
Per-source ducking gain (linear, calculated from envelope).
Definition mixer.h:296
float attack_coeff
Attack coefficient (converted from attack_ms).
Definition mixer.h:290
mixer_t * mixer_create_channels(int max_sources, int sample_rate, unsigned channels)
Definition mixer.c:209
unsigned channels
Definition mixer.h:340
uint64_t release_ns
Ducking release time in nanoseconds.
Definition mixer.h:287
float threshold_dB
Speaking threshold in dB (sources below this are not "speaking").
Definition mixer.h:279
void ducking_process_frame(ducking_t *duck, float *envelopes, float *gains, int num_sources)
Process a frame of audio through ducking system.
Definition mixer.c:171
void noise_gate_init(noise_gate_t *gate, float sample_rate)
Initialize a noise gate.
Definition effects.c:102
float crowd_alpha
Crowd scaling exponent (typically 0.5 for sqrt scaling).
Definition mixer.h:365
void ducking_destroy(ducking_t *duck)
Free ducking system resources.
Definition mixer.c:153
float buffer_peak(const float *buffer, int count)
Find peak absolute value in buffer.
Definition effects.c:350
ducking_t ducking
Ducking system (active speaker detection and attenuation).
Definition mixer.h:370
float cutoff_hz
Cutoff frequency in Hz (frequencies below this are attenuated).
Definition mixer.h:224
int num_sources
Current number of active audio sources.
Definition mixer.h:334
float soft_clip(float sample, float threshold, float steepness)
Apply soft clipping to a sample.
Definition effects.c:286
float sample_rate
Sample rate in Hz (set during initialization).
Definition mixer.h:194
float knee_dB
Knee width in dB for soft knee (e.g., 2.0).
Definition mixer.h:143
void mixer_remove_source(mixer_t *mixer, const char *client_id)
Remove an audio source from the mixer.
Definition mixer.c:465
uint64_t active_sources_mask[((128+63)/64)]
Bitset of active sources (bit i = source i is active, O(1) iteration).
Definition mixer.h:355
void fade_buffer(float *buffer, int count, float start_gain, float end_gain)
Apply linear fade to buffer in-place.
Definition effects.c:372
void compressor_init(compressor_t *comp, float sample_rate)
Initialize a compressor.
Definition effects.c:29
float alpha
Filter coefficient alpha (calculated from cutoff_hz).
Definition mixer.h:254
void compressor_set_params(compressor_t *comp, float threshold_dB, float ratio, uint64_t attack_ns, uint64_t release_ns, float makeup_dB)
Set compressor parameters.
Definition effects.c:40
uint64_t attack_ns
Attack time in nanoseconds (how fast gate opens).
Definition mixer.h:187
int ducking_init(ducking_t *duck, int num_sources, float sample_rate)
Initialize ducking system.
Definition mixer.c:98
#define MIXER_MASK_WORDS
Definition mixer.h:106
void highpass_filter_init(highpass_filter_t *filter, float cutoff_hz, float sample_rate)
Initialize a high-pass filter.
Definition effects.c:187
float int16_to_float(int16_t sample)
Convert int16 sample to float.
Definition effects.c:330
uint64_t attack_ns
Ducking attack time in nanoseconds.
Definition mixer.h:285
float * envelope
Per-source envelope follower state (linear, allocated per source).
Definition mixer.h:294
float threshold_dB
Compression threshold in dB (e.g., -10.0).
Definition mixer.h:141
int max_sources
Maximum number of sources (allocated array sizes).
Definition mixer.h:337
float * mix_buffer
Temporary buffer for mixing operations (pre-allocated).
Definition mixer.h:375
float envelope
Current envelope follower state (linear, 0-1).
Definition mixer.h:196
float sample_rate
Sample rate in Hz (set during initialization).
Definition mixer.h:154
bool gate_open
True if gate is currently open (allowing audio through).
Definition mixer.h:202
float smoothstep(float t)
Compute smoothstep interpolation.
Definition effects.c:313
void fade_buffer_smooth(float *buffer, int count, bool fade_in)
Apply smoothstep fade to buffer in-place.
Definition effects.c:384
int16_t float_to_int16(float sample)
Convert float sample to int16 (WebRTC format).
Definition effects.c:321
compressor_t compressor
Compressor (dynamic range compression).
Definition mixer.h:372
float sample_rate
Sample rate in Hz (set during initialization).
Definition mixer.h:251
void lowpass_filter_init(lowpass_filter_t *filter, float cutoff_hz, float sample_rate)
Initialize a low-pass filter.
Definition effects.c:237
mixer_t * mixer_create(int max_sources, int sample_rate)
Create a new audio mixer.
Definition mixer.c:205
int mixer_process_excluding_source(mixer_t *mixer, float *output, int num_samples, uint32_t exclude_client_id)
Process audio from all sources except one (for per-client output).
Definition mixer.c:689
float db_to_linear(float db)
Convert decibels to linear gain.
Definition effects.c:10
const char * source_id_at_hash[256]
Client ID strings stored at each hash index for collision detection.
Definition mixer.h:359
void lowpass_filter_process_buffer(lowpass_filter_t *filter, float *buffer, int num_samples)
Process a buffer of samples through low-pass filter.
Definition effects.c:272
uint64_t release_ns
Release time in nanoseconds (how fast gate closes).
Definition mixer.h:189
#define MIXER_HASH_INVALID
Invalid index sentinel value for mixer hash table.
Definition mixer.h:479
void highpass_filter_process_buffer(highpass_filter_t *filter, float *buffer, int num_samples)
Process a buffer of samples through high-pass filter.
Definition effects.c:223
void ducking_set_params(ducking_t *duck, float threshold_dB, float leader_margin_dB, float atten_dB, uint64_t attack_ns, uint64_t release_ns)
Set ducking parameters.
Definition mixer.c:162
void mixer_set_source_active(mixer_t *mixer, const char *client_id, bool active)
Set whether a source is active (receiving audio).
Definition mixer.c:511
audio_ring_buffer_t ** source_buffers
Array of pointers to client audio ring buffers.
Definition mixer.h:346
struct mixer_listener_buffer * listener_buffers[128][128]
Definition mixer.h:348
int mixer_source_count(const mixer_t *mixer)
Definition mixer.c:507
float makeup_dB
Makeup gain in dB (compensates for gain reduction).
Definition mixer.h:151
float compressor_process_sample(compressor_t *comp, float sidechain)
Process a single sample through compressor.
Definition effects.c:74
void mixer_destroy(mixer_t *mixer)
Destroy a mixer and free all resources.
Definition mixer.c:372
int sample_rate
Sample rate in Hz (e.g., 44100).
Definition mixer.h:339
uint64_t attack_ns
Attack time in nanoseconds (how fast compression kicks in).
Definition mixer.h:147
float lowpass_filter_process_sample(lowpass_filter_t *filter, float input)
Process a single sample through low-pass filter.
Definition effects.c:260
void noise_gate_set_params(noise_gate_t *gate, float threshold, uint64_t attack_ns, uint64_t release_ns, float hysteresis)
Set noise gate parameters.
Definition effects.c:116
float linear_to_db(float linear)
Convert linear gain to decibels.
Definition effects.c:14
int mixer_add_source(mixer_t *mixer, const char *client_id, audio_ring_buffer_t *buffer)
Add an audio source to the mixer.
Definition mixer.c:404
uint64_t release_ns
Release time in nanoseconds (how fast compression releases).
Definition mixer.h:149
void lowpass_filter_reset(lowpass_filter_t *filter)
Reset low-pass filter state.
Definition effects.c:253
float attack_coeff
Attack coefficient (converted from attack_ms).
Definition mixer.h:160
int mixer_process(mixer_t *mixer, float *output, int num_samples)
Process audio from all active sources.
Definition mixer.c:538
void buffer_int16_to_float(const int16_t *src, float *dst, int count)
Convert int16 buffer to float buffer.
Definition effects.c:342
float threshold
Gate threshold in linear units (e.g., 0.01f for -40dB).
Definition mixer.h:185
float prev_output
Previous output sample (filter state).
Definition mixer.h:233
float release_coeff
Release coefficient (converted from release_ms).
Definition mixer.h:162
float gain_lin
Current gain multiplier (linear, calculated from envelope).
Definition mixer.h:158
float attack_coeff
Attack coefficient (converted from attack_ms).
Definition mixer.h:198
float noise_gate_process_sample(noise_gate_t *gate, float input, float peak_amplitude)
Process a single sample through noise gate.
Definition effects.c:134
unsigned int uint32_t
Definition common.h:62
unsigned long long uint64_t
Definition common.h:63
unsigned char uint8_t
Definition common.h:60
struct audio_ring_buffer audio_ring_buffer_t
Audio ring buffer for real-time audio streaming.
Lock-Free Ring Buffer and Frame Buffer Management.
Dynamic range compressor settings and state.
Definition mixer.h:139
Ducking system settings and state.
Definition mixer.h:277
noise gate keeps the values that move through the subsystem: threshold, attack_ns,...
Definition mixer.h:222
This is the handoff point for highpass filter. Callers fill cutoff_hz, sample_rate,...
Definition mixer.h:247
Owns the temporary storage used by mixer listener buffer. The data pointers and size or cursor fields...
Definition mixer.c:31
For ducking, this is the live record that ties threshold_dB, leader_margin_dB, atten_dB,...
Definition mixer.h:332
This is the handoff point for compressor. Callers fill threshold_dB, knee_dB, ratio,...
Definition mixer.h:183
Read-write lock type (POSIX: pthread_rwlock_t with debug tracking).
Definition rwlock.h:63
spectral processor keeps the values that move through the subsystem: config, forward,...
Definition spectral.c:17