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

Go to the source code of this file.

Data Structures

struct  waveform_color_stop_t
 waveform color stop keeps the values that move through the subsystem: frequency, red, green, blue. Some members are pointers into caller- or subsystem-owned memory, so lifetime follows the API that populated them rather than the struct copy itself. More...

Functions

void visualization_color_for_level (float frequency_hz, float level, int color_mode, unsigned char *red, unsigned char *green, unsigned char *blue)
void audio_visualization_submit_stereo (audio_visualization_source_t source, const float *samples, size_t count)
void audio_visualization_submit (audio_visualization_source_t source, const float *samples, size_t count)
void audio_visualization_read (audio_visualization_source_t source, float *samples, size_t count)
char * visualization_encode (const char *cells, const unsigned char *colors, bool column_colors, unsigned int width, unsigned int height, bool use_color, bool flip_x, bool flip_y)

Function Documentation

◆ audio_visualization_read()

void audio_visualization_read ( audio_visualization_source_t source,
float * samples,
size_t count )

Definition at line 108 of file visualization.c.

108 {
109 if (!samples)
110 return;
112 memset(samples, 0, count * sizeof(float));
113 return;
114 }
115 static_mutex_lock_named(&history_mutex, "audio_visualization_history");
116 size_t available_count = count < VISUALIZATION_HISTORY ? count : VISUALIZATION_HISTORY;
117 size_t output_offset = count - available_count;
118 for (size_t i = 0; i < count; i++)
119 samples[i] = 0.0f;
120 size_t first_source = source;
121 size_t last_source = source;
123 first_source = AUDIO_VISUALIZATION_SOURCE_MIC;
126 first_source = AUDIO_VISUALIZATION_SOURCE_MIC;
128 }
129 for (size_t current = first_source; current <= last_source; current++) {
130 size_t start = (write_position[current] + VISUALIZATION_HISTORY - available_count) % VISUALIZATION_HISTORY;
131 for (size_t i = 0; i < available_count; i++)
132 samples[output_offset + i] += history[current][(start + i) % VISUALIZATION_HISTORY];
133 }
134 static_mutex_unlock(&history_mutex);
135 for (size_t i = 0; i < count; i++)
136 samples[i] = fmaxf(-1.0f, fminf(1.0f, samples[i]));
137}
audio_visualization_source_t source
Definition fft.c:24
@ AUDIO_VISUALIZATION_SOURCE_MIX
@ AUDIO_VISUALIZATION_SOURCE_MEDIA
@ AUDIO_VISUALIZATION_SOURCE_LOCAL_MIX
@ AUDIO_VISUALIZATION_SOURCE_COUNT
@ AUDIO_VISUALIZATION_SOURCE_MIC
@ AUDIO_VISUALIZATION_SOURCE_REMOTE
#define VISUALIZATION_HISTORY

References AUDIO_VISUALIZATION_SOURCE_COUNT, AUDIO_VISUALIZATION_SOURCE_LOCAL_MIX, AUDIO_VISUALIZATION_SOURCE_MEDIA, AUDIO_VISUALIZATION_SOURCE_MIC, AUDIO_VISUALIZATION_SOURCE_MIX, AUDIO_VISUALIZATION_SOURCE_REMOTE, source, and VISUALIZATION_HISTORY.

Referenced by audio_visualization_render_fft(), and audio_visualization_render_waveform().

◆ audio_visualization_submit()

void audio_visualization_submit ( audio_visualization_source_t source,
const float * samples,
size_t count )

Definition at line 93 of file visualization.c.

93 {
94 if ((!GET_OPTION(waveform) && !GET_OPTION(fft)) || !samples || source < AUDIO_VISUALIZATION_SOURCE_MIC ||
96 return;
97 static_mutex_lock_named(&history_mutex, "audio_visualization_history");
98 size_t position = write_position[source];
99 for (size_t i = 0; i < count; i++) {
100 float sample = samples[i];
101 history[source][position] = isfinite(sample) ? fmaxf(-1.0f, fminf(1.0f, sample)) : 0.0f;
102 position = (position + 1) % VISUALIZATION_HISTORY;
103 }
104 write_position[source] = position;
105 static_mutex_unlock(&history_mutex);
106}
#define GET_OPTION(field)
Safely get a specific option field (lock-free read).
Definition options.h:1336

References AUDIO_VISUALIZATION_SOURCE_MIC, AUDIO_VISUALIZATION_SOURCE_REMOTE, GET_OPTION, source, and VISUALIZATION_HISTORY.

Referenced by audio_visualization_submit_stereo(), and mirror_submit_audio_samples().

◆ audio_visualization_submit_stereo()

void audio_visualization_submit_stereo ( audio_visualization_source_t source,
const float * samples,
size_t count )

Downmix interleaved stereo only for display analysis, preserving its sample clock.

Definition at line 78 of file visualization.c.

78 {
79 if (!samples || count % 2)
80 return;
81 float mono[480];
82 for (size_t offset = 0; offset < count;) {
83 size_t frames = (count - offset) / 2;
84 if (frames > 480)
85 frames = 480;
86 for (size_t i = 0; i < frames; i++)
87 mono[i] = samples[offset + i * 2] * 0.5f + samples[offset + i * 2 + 1] * 0.5f;
89 offset += frames * 2;
90 }
91}
void audio_visualization_submit(audio_visualization_source_t source, const float *samples, size_t count)

References audio_visualization_submit(), and source.

Referenced by audio_write_samples().

◆ visualization_color_for_level()

void visualization_color_for_level ( float frequency_hz,
float level,
int color_mode,
unsigned char * red,
unsigned char * green,
unsigned char * blue )

Definition at line 62 of file visualization.c.

63 {
64 visualization_color_for_frequency(frequency_hz, red, green, blue);
65 float brightness = 0.5f + 0.5f * level;
66 float white_mix = 0.0f;
68 brightness = 0.24f + 0.76f * level;
70 brightness = 0.62f + 0.38f * level;
71 white_mix = 0.10f;
72 }
73 *red = (unsigned char)lrintf(fminf(255.0f, *red * brightness + 255.0f * white_mix));
74 *green = (unsigned char)lrintf(fminf(255.0f, *green * brightness + 255.0f * white_mix));
75 *blue = (unsigned char)lrintf(fminf(255.0f, *blue * brightness + 255.0f * white_mix));
76}
int color_mode
Definition fft.c:25
#define AUDIO_VISUALIZATION_COLOR_BRIGHTER
#define AUDIO_VISUALIZATION_COLOR_DARKER

References AUDIO_VISUALIZATION_COLOR_BRIGHTER, AUDIO_VISUALIZATION_COLOR_DARKER, and color_mode.

Referenced by audio_visualization_render_fft(), and audio_visualization_render_waveform().

◆ visualization_encode()

char * visualization_encode ( const char * cells,
const unsigned char * colors,
bool column_colors,
unsigned int width,
unsigned int height,
bool use_color,
bool flip_x,
bool flip_y )

Definition at line 154 of file visualization.c.

155 {
156 int mode = GET_OPTION(render_mode);
160 use_color = use_color && color_mode != COLOR_MODE_NONE;
161 palette_type_t palette_type = (palette_type_t)GET_OPTION(palette_type);
162 const palette_def_t *builtin = get_builtin_palette(palette_type);
163 const char *palette =
164 palette_type == PALETTE_CUSTOM ? GET_OPTION(palette_custom) : (builtin ? builtin->chars : PALETTE_CHARS_STANDARD);
165 if (!palette || !*palette)
166 palette = PALETTE_CHARS_STANDARD;
167 const char *characters[256];
168 size_t lengths[256], count = 0;
169 for (const char *p = palette; *p && count < 256;) {
170 uint32_t codepoint;
171 int length = utf8_decode((const uint8_t *)p, &codepoint);
172 if (length <= 0)
173 break;
174 characters[count] = p;
175 lengths[count++] = (size_t)length;
176 p += length;
177 }
178 bool half = mode == RENDER_MODE_HALF_BLOCK;
179 unsigned int rows = half ? height / 2 : height;
180 size_t capacity = (size_t)width * rows * 64 + rows + 1;
181 char *frame = SAFE_MALLOC(capacity, char *);
182 if (!frame)
183 return NULL;
184 size_t used = 0;
185 for (unsigned int y = 0; y < rows; y++) {
186 for (unsigned int x = 0; x < width; x++) {
187 unsigned int sx = flip_x ? width - x - 1 : x;
188 unsigned int sy = half ? y * 2 : y;
189 unsigned int top = flip_y ? height - sy - 1 : sy;
190 size_t cell = (size_t)top * width + sx;
191 const unsigned char *color = colors + (column_colors ? sx : cell) * 3;
192 char ch = cells[cell];
193 if (half) {
194 unsigned int bottom = flip_y ? height - sy - 2 : sy + 1;
195 size_t lower = (size_t)bottom * width + sx;
196 const unsigned char *lower_color = colors + (column_colors ? sx : lower) * 3;
197 bool upper_on = ch != ' ', lower_on = cells[lower] != ' ';
198 if (use_color) {
199 const unsigned char black[3] = {0};
200 char *out = visualization_color(frame + used, upper_on ? color : black, false, color_mode);
201 out = visualization_color(out, lower_on ? lower_color : black, true, color_mode);
202 memcpy(out, "▀\033[0m", sizeof("▀\033[0m") - 1);
203 used = (size_t)(out - frame) + sizeof("▀\033[0m") - 1;
204 } else {
205 const char *glyph = upper_on ? (lower_on ? "█" : "▀") : (lower_on ? "▄" : " ");
206 size_t length = strlen(glyph);
207 memcpy(frame + used, glyph, length);
208 used += length;
209 }
210 } else if (ch != ' ') {
211 char *out = frame + used;
212 if (use_color)
213 out = visualization_color(out, color, mode == RENDER_MODE_BACKGROUND, color_mode);
214 if (mode == RENDER_MODE_BACKGROUND && use_color) {
215 *out++ = ' ';
216 } else if (count) {
217 unsigned int luminance = 2126u * color[0] + 7152u * color[1] + 722u * color[2];
218 size_t index = (luminance * (count - 1) + 1275000u) / 2550000u;
219 memcpy(out, characters[index], lengths[index]);
220 out += lengths[index];
221 } else {
222 *out++ = ch;
223 }
224 if (use_color) {
225 memcpy(out, "\033[0m", 4);
226 out += 4;
227 }
228 used = (size_t)(out - frame);
229 } else {
230 frame[used++] = ch;
231 }
232 }
233 frame[used++] = '\n';
234 }
235 frame[used] = '\0';
236 return frame;
237}
char cells[(512 *256 *2)]
Definition fft.c:21
unsigned char colors[(512 *256 *2) *3]
Definition fft.c:22
unsigned int height
Definition fft.c:23
unsigned int width
Definition fft.c:23
unsigned int uint32_t
Definition common.h:62
#define SAFE_MALLOC(size, cast)
Definition common.h:265
unsigned char uint8_t
Definition common.h:60
#define COLOR_MODE_TRUECOLOR
24-bit truecolor mode
Definition options.h:228
#define COLOR_MODE_AUTO
Backward compatibility aliases for color mode enum values.
Definition options.h:222
#define COLOR_MODE_NONE
Monochrome mode.
Definition options.h:223
const palette_def_t * get_builtin_palette(palette_type_t type)
Get built-in palette definition.
Definition palette.c:53
palette_type_t
Built-in palette type enumeration.
Definition palette.h:90
#define PALETTE_CHARS_STANDARD
Standard ASCII palette character string.
Definition palette.h:171
@ PALETTE_CUSTOM
User-defined via –palette-chars.
Definition palette.h:104
int utf8_decode(const uint8_t *s, uint32_t *codepoint)
Decode a UTF-8 sequence to a Unicode codepoint.
Definition utf8.c:27
static bool size_t index
Definition queries.h:8
static bool size_t gotel_query_t * out
Definition queries.h:8
Validated luminance palette used to turn brightness into characters.
Definition palette.h:124

References cells, palette_def_t::chars, color_mode, COLOR_MODE_AUTO, COLOR_MODE_NONE, COLOR_MODE_TRUECOLOR, colors, get_builtin_palette(), GET_OPTION, height, index, out, PALETTE_CHARS_STANDARD, PALETTE_CUSTOM, SAFE_MALLOC, utf8_decode(), and width.

Referenced by audio_visualization_render_fft(), and audio_visualization_render_waveform().