Introduction
ascii-chat is a real-time terminal-based video chat application that converts video streams to ASCII art for display in terminals. It supports multiple clients, audio streaming, and end-to-end encryption.
This documentation provides comprehensive API reference and architectural guidance for developers working with ascii-chat. Whether you're integrating ascii-chat into your application, extending its functionality, or contributing to the project, this documentation will help you understand the codebase structure and implementation details.
- Note
- Getting Started? We recommend starting with the Build System topic to understand how to compile ascii-chat on Windows, Linux, and macOS, configure the build system, and set up your development environment.
- Warning
- Important: When exploring this documentation, navigate to Topics in the sidebar. Many topic pages have "README" in their title and provide comprehensive subsystem overviews. These are excellent entry points for understanding major subsystems. You can also start with Topic Categories for an organized index. See the Exploring the Documentation section below for detailed navigation guidance.
Exploring the Documentation
Understanding the Sidebar
The left sidebar is your primary navigation tool. It contains the following main sections:
- ascii-chat API Documentation - The main landing page (you are here)
- Topics - Comprehensive architectural documentation (the most important section for understanding the system)
- Topic Categories - Index page that lists all topics organized by category (start here to browse topics!)
- Data Structures - All struct and typedef definitions organized by functionality
- Files - Browse source files organized by directory structure
- Examples - Code examples and usage patterns
- Search - Use the search bar at the top of the page to find anything quickly
Finding Topics in the Sidebar
Topics are directly accessible in the sidebar. To access them:
- Look for Topics in the left sidebar (or click here)
- Click to expand the topics tree.
- Each topic has a tree to expand with files, functions, enums and structs, custom documentation pages, etc.
Alternatively, you can start with Topic Categories in the sidebar, which provides an organized index of all topics grouped by category. This is an excellent starting point!
The Topics page includes comprehensive architectural guides with names like:
- Warning
- Important: These links go to the full topic page that has all the topic's functions and enums and structs etc documentation listed first, before the documentation that you wanted when you clicked the link... either scroll down to where the custom documentation starts, or expand the topic in the sidebar to see a direct link to the page you desire (in the sidebar tree, it will be down past the topic's files and structs).
- Note
- Pro Tip: Many topic pages have "README" in their title and/or descriptive names with capitalized titles (Pages Titled Like This). These are comprehensive overview documents that explain entire subsystems in detail.
-
Pro Tip: Many topic pages have the same name as their topic. For instance the Packet Queue topic has a page called "Packet Queue" that explains the code in more detail than the header file documentation does. Look for these pages.
How to Navigate the Sidebar
Looking for architectural documentation?
- Click Topics in the sidebar to see all topic pages
- Or start with Topic Categories for an organized index of all topics
- Look for topic pages with "README" in the title for comprehensive subsystem overviews
Looking for a specific function or struct?
- Use the search bar at the top of the page (fastest method)
- Or check Data Structures to find type definitions
- Or browse Files to see all functions in a particular source file
Looking for implementation details? Check the sidebar!
- Check Files to browse source files by directory
- Review Data Structures to understand type definitions
- Read Topics for architectural context, then drill into specific files
- Check Examples for code samples and usage patterns
Topics: Comprehensive Architectural Documentation
Topics are detailed guides that explain subsystems comprehensively. They combine:
- Architectural overviews and design rationale
- API documentation with usage examples
- Integration patterns and best practices
- Performance considerations and optimization notes
Access topics directly via Topics in the sidebar, or start with Topic Categories in the sidebar for an organized index of all topics grouped by category.
Key topics to explore:
Getting Started:
- Build System: CMake configuration, cross-platform compilation, build types, platform-specific gotchas, static builds, and build optimizations (start here if new to the project!)
- Platform Abstraction Layer README: Complete cross-platform abstraction guide covering threads, mutexes, sockets, terminal I/O, crash handling, and OS portability (essential for understanding Windows/Linux/macOS support!)
- Testing Framework: Test infrastructure, test runner, Docker testing, coverage
Core Infrastructure:
Cryptography:
Data Structures:
Media Processing:
Network Layer:
Client Application:
Server Application:
For more details, explore the Topic Categories page, which provides links to all topics organized by category. Key topics include:
- Build System: Complete build documentation, CMake configuration, cross-platform compilation, build types, and optimization
- Platform Abstraction Layer README: Comprehensive guide to cross-platform abstractions, threading, sockets, terminal I/O, and OS portability
- Cryptography: Encryption architecture, cryptographic operations, and security details
- Handshake Module README: How client and server establish secure encrypted sessions using X25519 key exchange
- Keys Module README: SSH/GPG key handling, key validation, and authentication mechanisms
- Audio/Video Networking: Media packet APIs, compression, and streaming protocols
- Network I/O: Packet I/O operations, socket management, and network abstractions
- Note
- Finding Topics: All topics are accessible via Topics in the sidebar. Many topics have "README" in their title and/or descriptive names with capitalized titles (Pages Titled Like This), indicating they are comprehensive subsystem documentation. You can also start with Topic Categories for an organized index, or use the search bar at the top of the page to find topics.
Development & Debugging:
Quick Start
New to ascii-chat? Start here:
- Set up your build environment: Read Build System to learn how to compile ascii-chat on your platform (Windows, Linux, or macOS) and understand the CMake configuration, build types, and platform-specific considerations
- Read this main page to understand the project overview
- Visit Topic Categories to browse detailed guides
- Check out Getting Started section below for code examples
- Explore Topics for architectural documentation and Files or Data Structures for API reference
Finding Code Elements
Looking for a specific function or structure?
- Use the search bar at the top of the page (Ctrl+F / Cmd+F in browser)
- Browse Data Structures to find related types grouped together
- Check Files to see all functions in a particular source file
- Review Topics for architectural context and usage examples
Understanding the System
Want to understand how things work together?
- Start with Topics: Navigate to Topics in the sidebar, or visit Topic Categories for an organized index. Topics provide comprehensive architectural documentation that explains how subsystems work together.
- Look for README pages: Many topics have "README" in their title (e.g., "Build System README", "Cryptography Module README"). These are the most comprehensive guides and are excellent entry points.
- Follow cross-references: Click on
@ref links in documentation (like Build System or Cryptography) to navigate between related concepts.
- Review "See also" sections: Most documentation blocks include "See also" references at the bottom that link to related topics, modules, or functions.
- Check Integration sections: Topic pages include "Integration" sections that explain how modules interact with each other in the larger system.
Contributing to the Project
Planning to contribute code?
- Set up your build environment: Read Build System to configure your development environment and understand build types, CMake presets, and testing setup
- Read Topic Pages to understand the architecture before making changes
- Review Best Practices sections for coding standards and patterns
- Check
- Note
- @note tags that look like this and
- Warning
- @warning tags that look like this in documentation for important details
- Follow the existing documentation style when adding new code and format with clang-format
Library Structure
The library is organized into several major modules:
Core Library
Platform Abstractions
- Platform Abstraction Layer README - Comprehensive guide to cross-platform abstractions for threads, mutexes, sockets, terminal I/O, crash handling, and OS portability (Windows/Linux/macOS)
- Platform Layer - API reference for platform abstractions
- Webcam Capture - Cross-platform webcam capture functionality
Core Libraries
Network Layer
Cryptography
Media Processing
Utilities
- Utilities - String manipulation, path handling, IP parsing, math utilities, UTF-8 support
Getting Started
- Note
- Before diving into the code, make sure you've read the Build System topic to understand how to compile and configure ascii-chat for your platform.
This section provides a quick overview of how to use the ascii-chat library. For detailed documentation on each component, see the Topic Categories page.
Typical Workflow
The typical workflow for using the ascii-chat library:
- Initialize the logging system with log_init()
- Initialize common subsystems with asciichat_common_init()
- Initialize platform-specific components (audio, video, network)
- Set up cryptographic context and perform handshake
- Start audio/video capture and network streaming
- Handle incoming packets and render to terminal
Client Workflow: Connect, Handshake, Send Video, Display ASCII
Complete client workflow from connection to displaying ASCII frames:
socket_t sockfd = server_connection_connect(
"127.0.0.1", 27224);
}
return handshake_result;
}
log_info(
"Encrypted session established with server");
client_capabilities_packet_t caps = {
.terminal_width = htons(80),
.terminal_height = htons(24),
.supports_color = 1,
};
rgb_pixel_t *webcam_pixels = NULL;
int width = 640, height = 480;
if (webcam_capture_frame(&webcam_pixels, &width, &height) != 0) {
}
size_t frame_size =
sizeof(
uint32_t) * 2 + (
size_t)width * (size_t)height *
sizeof(rgb_pixel_t);
memcpy(frame_data +
sizeof(
uint32_t) * 2, webcam_pixels,
(size_t)width * (size_t)height * sizeof(rgb_pixel_t));
log_debug(
"Sent %dx%d webcam frame to server", width, height);
crypto_ready, &envelope);
header->width = ntohl(header->width);
header->height = ntohl(header->height);
header->original_size = ntohl(header->original_size);
header->checksum = ntohl(header->checksum);
char *ascii_frame =
SAFE_MALLOC(header->original_size + 1,
char *);
memcpy(ascii_frame, frame_data_ptr, header->original_size);
ascii_frame[header->original_size] = '\0';
if (actual_crc == header->checksum) {
log_debug(
"Displayed %ux%u ASCII frame", header->width, header->height);
}
}
void buffer_pool_free(buffer_pool_t *pool, void *data, size_t size)
Free a buffer back to the pool (lock-free)
asciichat_error_t threaded_send_packet(packet_type_t type, const void *data, size_t len)
Thread-safe packet transmission.
const crypto_context_t * crypto_client_get_context(void)
Get crypto context for encryption/decryption.
bool crypto_client_is_ready(void)
Check if crypto handshake is ready.
void display_render_frame(const char *frame_data, bool is_snapshot_frame)
Render ASCII frame to display.
#define SAFE_MALLOC(size, cast)
asciichat_error_t
Error and exit codes - unified status values (0-255)
#define log_error(...)
Log an ERROR message.
#define log_info(...)
Log an INFO message.
#define log_debug(...)
Log a DEBUG message.
void * allocated_buffer
Buffer that needs to be freed by caller (may be NULL if not allocated)
size_t allocated_size
Size of allocated buffer in bytes.
void * data
Packet payload data (decrypted and decompressed if applicable)
packet_recv_result_t receive_packet_secure(socket_t sockfd, void *crypto_ctx, bool enforce_encryption, packet_envelope_t *envelope)
Receive a packet with decryption and decompression support.
packet_type_t type
Packet type (from packet_types.h)
packet_recv_result_t
Packet reception result codes.
#define COLOR_MODE_TRUECOLOR
24-bit truecolor mode
@ PACKET_TYPE_IMAGE_FRAME
Complete RGB image with dimensions.
@ PACKET_TYPE_ASCII_FRAME
Complete ASCII frame with all metadata.
@ PACKET_TYPE_CLIENT_CAPABILITIES
Client reports terminal capabilities.
#define asciichat_crc32(data, len)
Main CRC32 dispatcher macro - use this in application code.
ASCII frame packet structure (Packet Type 2)
Cryptographic context structure.
Packet envelope containing received packet data.
Server Workflow: Receive Video, Convert to ASCII, Broadcast
Complete server workflow showing client connection, video reception, ASCII conversion, and broadcasting:
log_error(
"Failed to accept client connection");
return ERROR_NETWORK_ACCEPT;
}
uint32_t client_id = allocate_client_id();
client_info_t *client = create_client_info(client_id, client_sockfd);
log_error(
"Crypto handshake failed for client %u", client_id);
close_client_connection(client);
return handshake_result;
}
log_info(
"Client %u: Encrypted session established", client_id);
bool crypto_ready = crypto_server_client_is_ready(client);
crypto_ready, &envelope);
rgb_pixel_t *pixels = (rgb_pixel_t *)(envelope.
data +
sizeof(
uint32_t) * 2);
log_debug(
"Client %u: Received %ux%u video frame", client_id, img_width, img_height);
}
if (!atomic_load(&target_client->
active)) {
continue;
}
unsigned short term_height = target_client->
terminal_caps.height;
size_t ascii_size = 0;
target_client->
client_id, term_width, term_height, &ascii_size);
if (!ascii_frame) {
continue;
}
.
width = htonl(term_width),
.height = htonl(term_height),
.original_size = htonl(ascii_size),
.compressed_size = 0,
.flags = 0
};
size_t total_size = sizeof(packet_header) + ascii_size;
memcpy(packet_data, &packet_header, sizeof(packet_header));
memcpy(packet_data + sizeof(packet_header), ascii_frame, ascii_size);
packet_data, total_size);
}
if (!atomic_load(&target_client->
active)) {
continue;
}
int sample_count = mixer_get_mixed_audio_for_client(target_client->
client_id,
if (sample_count > 0) {
size_t audio_size = sample_count * sizeof(float);
}
}
#define MAX_CLIENTS
Maximum possible clients (static array size) - actual runtime limit set by –max-clients (1-32)
uint32_t width
Terminal width in characters.
size_t len
Length of payload data in bytes.
#define AUDIO_SAMPLES_PER_PACKET
Samples per audio packet (256 samples)
client_manager_t g_client_manager
Global client manager singleton - central coordination point.
char * create_mixed_ascii_frame_for_client(uint32_t target_client_id, unsigned short width, unsigned short height, bool wants_stretch, size_t *out_size, bool *out_grid_changed, int *out_sources_count)
Generate personalized ASCII frame for a specific client.
int queue_audio_for_client(client_info_t *client, const void *audio_data, size_t data_size)
Queue ASCII frame for delivery to specific client.
Per-client state structure for server-side client management.
terminal_capabilities_t terminal_caps
video_frame_buffer_t * incoming_video_buffer
atomic_bool is_sending_video
client_info_t clients[MAX_CLIENTS]
Array of client_info_t structures (backing storage)
Important Notes
Encryption:
- All packets are automatically encrypted after the crypto handshake
- Use
threaded_send_packet() or receive_packet_secure() for encrypted I/O
- Crypto context is per-connection (client or server)
- Keys are automatically zeroed on
crypto_destroy()
Compression:
- Large packets (>100KB) are automatically compressed
- Compression is transparent - handled by packet I/O functions
- Use
av_send_*() functions for media packets with compression
Client Capabilities:
- Sent once after crypto handshake
- Includes terminal size, color support, palette preferences
- Server uses this to format output appropriately
Thread Safety:
Building Documentation
To build this documentation, you'll need Doxygen configured. See Build System for information on configuring the project with CMake, including documentation generation.
To build this documentation:
cmake --build build --target docs
The documentation will be generated in build/docs/html/index.html.
To open the documentation in your browser:
cmake --build build --target docs-open
For more information on the build system, including CMake configuration, build types, and platform-specific considerations, see Build System.
License
See the LICENSE.txt file for license information.
Links