ascii-chat
Binary v0.15.83-53-gb711d8720
Library lib/v0.3.2-701-gb711d8720
Video chat in your terminal
Loading...
Searching...
No Matches
recording.h File Reference

Go to the source code of this file.

Typedefs

typedef struct audio_recording audio_recording_t

Enumerations

enum  audio_recording_source_t { AUDIO_RECORDING_MIC , AUDIO_RECORDING_MEDIA , AUDIO_RECORDING_REMOTE , AUDIO_RECORDING_SOURCE_COUNT }

Functions

asciichat_error_t audio_recording_create (audio_recording_t **out)
asciichat_error_t audio_recording_create_channels (audio_recording_t **out, unsigned channels)
void audio_recording_destroy (audio_recording_t *recording)
void audio_recording_start (audio_recording_t *recording, uint64_t epoch_ns)
void audio_recording_submit (audio_recording_source_t source, const float *samples, size_t count, uint64_t start_ns)
void audio_recording_read (audio_recording_t *recording, float *samples, size_t count)

Typedef Documentation

◆ audio_recording_t

Definition at line 8 of file recording.h.

Enumeration Type Documentation

◆ audio_recording_source_t

Enumerator
AUDIO_RECORDING_MIC 
AUDIO_RECORDING_MEDIA 
AUDIO_RECORDING_REMOTE 
AUDIO_RECORDING_SOURCE_COUNT 

Definition at line 9 of file recording.h.

9 {
audio_recording_source_t
Definition recording.h:9
@ AUDIO_RECORDING_SOURCE_COUNT
Definition recording.h:13
@ AUDIO_RECORDING_MIC
Definition recording.h:10
@ AUDIO_RECORDING_REMOTE
Definition recording.h:12
@ AUDIO_RECORDING_MEDIA
Definition recording.h:11

Function Documentation

◆ audio_recording_create()

asciichat_error_t audio_recording_create ( audio_recording_t ** out)

Definition at line 30 of file recording.c.

30 {
32}
static bool size_t gotel_query_t * out
Definition queries.h:8
asciichat_error_t audio_recording_create_channels(audio_recording_t **out, unsigned channels)
Definition recording.c:34

References audio_recording_create_channels(), and out.

◆ audio_recording_create_channels()

asciichat_error_t audio_recording_create_channels ( audio_recording_t ** out,
unsigned channels )

Definition at line 34 of file recording.c.

34 {
35 if (channels != 1 && channels != 2)
36 return SET_ERRNO(ERROR_INVALID_PARAM, "Invalid recording channel count");
37 if (!out)
38 return SET_ERRNO(ERROR_INVALID_PARAM, "Missing recording output");
39 *out = NULL;
40 static_mutex_lock_named(&recording_mutex, "audio_recording");
41 if (active_recording) {
42 static_mutex_unlock(&recording_mutex);
43 return SET_ERRNO(ERROR_INVALID_STATE, "A session recording is already active");
44 }
45 audio_recording_t *recording = SAFE_CALLOC(1, sizeof(*recording), audio_recording_t *);
46 recording->channels = channels;
47 recording->mix = SAFE_CALLOC(RECORDING_CAPACITY * channels, sizeof(float), float *);
48 active_recording = recording;
49 *out = recording;
50 static_mutex_unlock(&recording_mutex);
51 return ASCIICHAT_OK;
52}
#define SET_ERRNO(code,...)
#define SAFE_CALLOC(count, size, cast)
Definition common.h:275
@ ERROR_INVALID_STATE
@ ASCIICHAT_OK
Definition error_codes.h:46
@ ERROR_INVALID_PARAM
#define RECORDING_CAPACITY
Definition recording.c:9
struct audio_recording audio_recording_t
Definition recording.h:8
unsigned channels
Definition recording.c:18

References ASCIICHAT_OK, audio_recording::channels, ERROR_INVALID_PARAM, ERROR_INVALID_STATE, audio_recording::mix, out, RECORDING_CAPACITY, SAFE_CALLOC, and SET_ERRNO.

Referenced by audio_recording_create(), and render_file_create().

◆ audio_recording_destroy()

void audio_recording_destroy ( audio_recording_t * recording)

Definition at line 54 of file recording.c.

54 {
55 if (!recording)
56 return;
57 static_mutex_lock_named(&recording_mutex, "audio_recording");
58 if (active_recording == recording) {
59 atomic_store_explicit(&recording_accepts_samples, false, memory_order_release);
60 active_recording = NULL;
61 }
62 SAFE_FREE(recording->mix);
63 SAFE_FREE(recording);
64 static_mutex_unlock(&recording_mutex);
65}
#define SAFE_FREE(ptr)
Definition common.h:377

References audio_recording::mix, and SAFE_FREE.

Referenced by render_file_destroy().

◆ audio_recording_read()

void audio_recording_read ( audio_recording_t * recording,
float * samples,
size_t count )

Definition at line 127 of file recording.c.

127 {
128 if (!recording || !samples)
129 return;
130 static_mutex_lock_named(&recording_mutex, "audio_recording");
131 for (size_t i = 0; i < count; i++) {
132 size_t slot = recording->read_position++ % (RECORDING_CAPACITY * recording->channels);
133 float sample = recording->mix[slot];
134 samples[i] = fmaxf(-1.0f, fminf(1.0f, sample));
135 recording->mix[slot] = 0;
136 }
137 static_mutex_unlock(&recording_mutex);
138}
uint64_t read_position
Definition recording.c:20

References audio_recording::channels, audio_recording::mix, audio_recording::read_position, and RECORDING_CAPACITY.

Referenced by render_file_destroy().

◆ audio_recording_start()

void audio_recording_start ( audio_recording_t * recording,
uint64_t epoch_ns )

Definition at line 67 of file recording.c.

67 {
68 if (!recording)
69 return;
70 static_mutex_lock_named(&recording_mutex, "audio_recording");
71 if (!recording->started) {
72 recording->epoch_ns = epoch_ns;
73 recording->started = true;
74 atomic_store_explicit(&recording_accepts_samples, true, memory_order_release);
75 }
76 static_mutex_unlock(&recording_mutex);
77}
uint64_t epoch_ns
Definition recording.c:19

References audio_recording::epoch_ns, and audio_recording::started.

◆ audio_recording_submit()

void audio_recording_submit ( audio_recording_source_t source,
const float * samples,
size_t count,
uint64_t start_ns )

Definition at line 79 of file recording.c.

79 {
80 // This is only a hint: the locked pointer/state check protects destruction.
81 if (!atomic_load_explicit(&recording_accepts_samples, memory_order_acquire) || !samples || !count || source < 0 ||
83 return;
84 static_mutex_lock_named(&recording_mutex, "audio_recording");
85 audio_recording_t *recording = active_recording;
86 if (!recording || !recording->started) {
87 static_mutex_unlock(&recording_mutex);
88 return;
89 }
90 uint64_t delta = start_ns > recording->epoch_ns ? start_ns - recording->epoch_ns : 0;
91 uint64_t position = delta / 1000000000ULL * RECORDING_RATE + delta % 1000000000ULL * RECORDING_RATE / 1000000000ULL;
92 position *= recording->channels;
93 /* Smooth callback jitter while preserving gaps longer than 100 ms. */
94 if (recording->source_started[source] &&
95 position < recording->source_position[source] + RECORDING_RATE * recording->channels / 10)
96 position = recording->source_position[source];
97 if (position < recording->read_position) {
98 position = recording->read_position;
99 if (position % recording->channels) {
100 uint64_t padding = recording->channels - position % recording->channels;
101 if (position > UINT64_MAX - padding) {
102 static_mutex_unlock(&recording_mutex);
103 return;
104 }
105 position += padding;
106 }
107 }
108 if (position > UINT64_MAX - (recording->channels - 1) || count > UINT64_MAX - position - (recording->channels - 1)) {
109 static_mutex_unlock(&recording_mutex);
110 return;
111 }
112 recording->source_started[source] = true;
113 // Each submission starts at channel zero. An incomplete final frame leaves
114 // its missing channels silent rather than shifting the next submission.
115 recording->source_position[source] = position + count;
116 if (recording->source_position[source] % recording->channels)
117 recording->source_position[source] +=
118 recording->channels - recording->source_position[source] % recording->channels;
119 for (size_t i = 0; i < count; i++, position++) {
120 if (position >= recording->read_position &&
121 position - recording->read_position < RECORDING_CAPACITY * recording->channels && isfinite(samples[i]))
122 recording->mix[position % (RECORDING_CAPACITY * recording->channels)] += samples[i];
123 }
124 static_mutex_unlock(&recording_mutex);
125}
audio_visualization_source_t source
Definition fft.c:24
unsigned long long uint64_t
Definition common.h:63
#define RECORDING_RATE
Definition recording.c:8
bool source_started[AUDIO_RECORDING_SOURCE_COUNT]
Definition recording.c:23
uint64_t source_position[AUDIO_RECORDING_SOURCE_COUNT]
Definition recording.c:21

References AUDIO_RECORDING_SOURCE_COUNT, audio_recording::channels, audio_recording::epoch_ns, audio_recording::mix, audio_recording::read_position, RECORDING_CAPACITY, RECORDING_RATE, source, audio_recording::source_position, audio_recording::source_started, and audio_recording::started.

Referenced by audio_write_samples(), and session_host_render_audio().