added libevent and fixed c23

This commit is contained in:
plky 2026-01-16 15:31:50 -05:00
parent 30ee8939cd
commit 910653f5e8
7 changed files with 114 additions and 91 deletions

6
.gitmodules vendored
View File

@ -1,3 +1,9 @@
[submodule "extern/openssl"] [submodule "extern/openssl"]
path = extern/openssl path = extern/openssl
url = https://github.com/openssl/openssl.git url = https://github.com/openssl/openssl.git
[submodule "extern/libevent"]
path = extern/libevent
url = https://github.com/libevent/libevent.git
[submodule "extern/log.c"]
path = extern/log.c
url = https://github.com/rxi/log.c.git

View File

@ -4,12 +4,8 @@ project(voice-chat
VERSION 0.1.0 VERSION 0.1.0
LANGUAGES C) LANGUAGES C)
set(C_STANDARD 23) set(CMAKE_C_STANDARD 23)
set(C_STANDARD_REQUIRED True) set(CMAKE_C_STANDARD_REQUIRED True)
add_executable(${PROJECT_NAME} src/main.c)
set(EXTERN "${PROJECT_SOURCE_DIR}/extern")
# Pull all submodules if haven't already # Pull all submodules if haven't already
find_package(Git QUIET) find_package(Git QUIET)
@ -26,9 +22,24 @@ if(GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git")
endif() endif()
endif() endif()
# if(NOT EXISTS "${PROJECT_SOURCE_DIR}/extern/openssl/CMakeLists.txt") if(NOT EXISTS "${PROJECT_SOURCE_DIR}/extern/libevent/CMakeLists.txt")
# message(FATAL_ERROR "The submodules were not downloaded! GIT_SUBMODULE was turned off or failed. Please update submodules and try again.") message(FATAL_ERROR "The submodules were not downloaded! GIT_SUBMODULE was turned off or failed. Please update submodules and try again.")
# endif() endif()
if(NOT EXISTS "${PROJECT_SOURCE_DIR}/extern/openssl/Configure")
message(FATAL_ERROR "The submodules were not downloaded! GIT_SUBMODULE was turned off or failed. Please update submodules and try again.")
endif()
set(EXTERN "${PROJECT_SOURCE_DIR}/extern")
add_executable(${PROJECT_NAME}
src/main.c
"${EXTERN}/log.c/src/log.c"
)
target_include_directories(${PROJECT_NAME} PRIVATE
"${PROJECT_SOURCE_DIR}/src"
)
set(BUILD_DYNAMIC_LIBS ON CACHE BOOL "" FORCE) set(BUILD_DYNAMIC_LIBS ON CACHE BOOL "" FORCE)
set(BUILD_STATIC_LIBS ON CACHE BOOL "" FORCE) set(BUILD_STATIC_LIBS ON CACHE BOOL "" FORCE)
@ -45,3 +56,9 @@ target_link_directories(${PROJECT_NAME} PRIVATE "${EXTERN}/openssl")
target_link_libraries(${PROJECT_NAME} PRIVATE ssl crypto) target_link_libraries(${PROJECT_NAME} PRIVATE ssl crypto)
target_include_directories(${PROJECT_NAME} PRIVATE "${EXTERN}/openssl/include") target_include_directories(${PROJECT_NAME} PRIVATE "${EXTERN}/openssl/include")
# libevent
add_subdirectory("${EXTERN}/libevent")
target_include_directories(${PROJECT_NAME} PRIVATE "${EXTERN}/libevent/include")
# log.c
target_include_directories(${PROJECT_NAME} PRIVATE "${EXTERN}/log.c/src")

View File

@ -7,8 +7,12 @@
"generator": "Ninja", "generator": "Ninja",
"binaryDir": "${sourceDir}/build", "binaryDir": "${sourceDir}/build",
"cacheVariables": { "cacheVariables": {
"CMAKE_C_COMPILER": "clang",
"CMAKE_BUILD_TYPE": "DEBUG", "CMAKE_BUILD_TYPE": "DEBUG",
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON", "CMAKE_EXPORT_COMPILE_COMMANDS": true,
"EVENT__ENABLE_VERBOSE_DEBUG": true
} }
} }
], ],

1
extern/libevent vendored Submodule

@ -0,0 +1 @@
Subproject commit a994a52d5373d6284b27576efa617aff2baa7bd3

1
extern/log.c vendored Submodule

@ -0,0 +1 @@
Subproject commit f9ea34994bd58ed342d2245cd4110bb5c6790153

View File

@ -1,95 +1,89 @@
// beep.c #include <arpa/inet.h>
// Build (Linux/macOS): cc beep.c -lm -o beep #include <errno.h>
// Build (Windows MSVC): cl /O2 beep.c #include <netinet/in.h>
#include <sys/types.h>
#define MINIAUDIO_IMPLEMENTATION #include <sys/socket.h>
#include "miniaudio.h" #include <openssl/ssl3.h>
#include <netdb.h>
#include <math.h> #include <stdarg.h>
#include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "log.h"
void
die(const char *errstr, ...) {
va_list ap;
va_start(ap, errstr);
vfprintf(stderr, errstr, ap);
va_end(ap);
exit(1);
}
// Client connection
typedef struct { typedef struct {
double phase; int fd;
double phase_inc; } cconnection_t;
uint32_t frames_left;
ma_uint32 channels;
} beep_state;
static void data_callback(ma_device* dev, void* out, const void* in, ma_uint32 frameCount) void*
{ get_in_addr(struct sockaddr *addr) {
(void)in; if (addr->sa_family == AF_INET) {
beep_state* s = (beep_state*)dev->pUserData; return &((struct sockaddr_in*)addr)->sin_addr;
float* output = (float*)out;
ma_uint32 framesToWrite = frameCount;
if (s->frames_left < framesToWrite) framesToWrite = s->frames_left;
for (ma_uint32 i = 0; i < framesToWrite; i++) {
float sample = (float)sin(s->phase) * 0.2f; // volume
s->phase += s->phase_inc;
// keep phase bounded (optional)
if (s->phase >= (2.0 * M_PI)) s->phase -= (2.0 * M_PI);
for (ma_uint32 ch = 0; ch < s->channels; ch++) {
output[i * s->channels + ch] = sample;
}
} }
// If we ran out early, zero the rest (silence). return &((struct sockaddr_in6*)addr)->sin6_addr;
for (ma_uint32 i = framesToWrite; i < frameCount; i++) {
for (ma_uint32 ch = 0; ch < s->channels; ch++) {
output[i * s->channels + ch] = 0.0f;
}
} }
s->frames_left -= framesToWrite; // Returns error or nullptr
char*
connect_server(char *hostname, char *port, cconnection_t *connection) {
int rv;
struct addrinfo hints, *res, *p;
// Stop after the beep finishes. memset(&hints, 0, sizeof(hints));
if (s->frames_left == 0) { hints.ai_family = AF_UNSPEC;
ma_device_stop(dev); // safe to request stop hints.ai_socktype = SOCK_STREAM;
} hints.ai_flags = AI_PASSIVE;
if ((rv = getaddrinfo(hostname, port, &hints, &res)) != 0) {
die("error getting address info: %s\n", gai_strerror(rv));
} }
int main(void) int fd;
{ char ip_str[INET6_ADDRSTRLEN];
const double freq = 440.0; for (p = res; p != nullptr; p = p->ai_next) {
const ma_uint32 sampleRate = 48000; if ((fd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) {
const double durationSec = 1.0; close(fd);
continue;
beep_state s = {0};
s.phase = 0.0;
s.phase_inc = (2.0 * M_PI * freq) / (double)sampleRate;
s.frames_left = (uint32_t)(durationSec * (double)sampleRate);
ma_device_config cfg = ma_device_config_init(ma_device_type_playback);
cfg.playback.format = ma_format_f32;
cfg.playback.channels = 2;
cfg.sampleRate = sampleRate;
cfg.dataCallback = data_callback;
cfg.pUserData = &s;
ma_device dev;
if (ma_device_init(NULL, &cfg, &dev) != MA_SUCCESS) {
fprintf(stderr, "Failed to init audio device\n");
return 1;
} }
s.channels = dev.playback.channels; // in case backend adjusts inet_ntop(p->ai_family, get_in_addr(p->ai_addr), ip_str, sizeof(ip_str));
if (connect(fd, p->ai_addr, p->ai_addrlen) != 0) {
if (ma_device_start(&dev) != MA_SUCCESS) { log_warn("Connection to %s:%s unsuccessful. %s", ip_str, port, strerror(errno));
fprintf(stderr, "Failed to start audio device\n"); continue;
ma_device_uninit(&dev);
return 1;
} }
// Wait until callback stops the device. log_info("Connection to %s successful", ip_str);
while (ma_device_is_started(&dev)) { break;
ma_sleep(10);
} }
ma_device_uninit(&dev); if (p == nullptr) {
ssize_t err_size = 512;
char *err = malloc(512);
snprintf(err, err_size, "Failed to connect to %s:%s", hostname, port);
return err;
}
freeaddrinfo(res);
return nullptr;
}
int
main() {
if(nullptr == NULL) return 1;
return 0; return 0;
} }

View File

@ -1,4 +1,4 @@
// num types // types
#pragma once #pragma once
#include <stdint.h> #include <stdint.h>