From 64176055d0c0b6ec25d8e400ec4d297b85ea708a Mon Sep 17 00:00:00 2001 From: "Alexander \"Arav\" Andreev" Date: Thu, 21 Mar 2024 04:10:02 +0400 Subject: [PATCH] An initial commit. :) --- .gitignore | 2 ++ Makefile | 25 ++++++++++++++ src/audio.c | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/audio.h | 25 ++++++++++++++ src/crypto.h | 6 ++++ src/main.c | 20 +++++++++++ 6 files changed, 171 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 src/audio.c create mode 100644 src/audio.h create mode 100644 src/crypto.h create mode 100644 src/main.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b67a479 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/obj +tetatet \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..f1d6fd7 --- /dev/null +++ b/Makefile @@ -0,0 +1,25 @@ +TARGET = tetatet + +CC = cc + +DESTDIR := +DESTDIR = / +PREFIX := /usr/local + +SRC_DIR := src +OBJ_DIR := obj + +SRCs := $(wildcard $(SRC_DIR)/*.c) +OBJs := $(SRCs:$(SRC_DIR)/%.c=$(OBJ_DIR)/%.o) + +CFLAGS = --std=c99 -O3 -Wall -Werror -Wextra -pedantic +LDFLAGS += -lportaudio -lopus -lsodium + +$(TARGET): $(OBJs) + $(CC) $(CFLAGS) $(LDFLAGS) $^ -o $@ + +$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c | $(OBJ_DIR) + $(CC) $(CFLAGS) $(LDFLAGS) -c $< -o $@ + +$(OBJ_DIR): + mkdir -p $@ \ No newline at end of file diff --git a/src/audio.c b/src/audio.c new file mode 100644 index 0000000..1e5e763 --- /dev/null +++ b/src/audio.c @@ -0,0 +1,93 @@ +#include "audio.h" + +#include +#include +#include + +int audio_default_callback(const void *input, void *output, + unsigned long frameCount, const PaStreamCallbackTimeInfo *timeInfo, + PaStreamCallbackFlags statusFlags, void *userData) { + (void)timeInfo; + (void)statusFlags; + + audio_t *aud = (audio_t *)userData; + + int encLen = opus_encode_float(aud->opusEnc, (float *)input, frameCount, aud->opusBuf, aud->opusBufSz); + (void)encLen; + int frameSize = opus_decode_float(aud->opusDec, aud->opusBuf, aud->opusBufSz, (float *)output, frameCount, 0); + (void)frameSize; + + // printf("%i %i | %li %li\n", encLen, frameSize, frameCount, aud->opusBufSz); + + return paContinue; +} + +int audio_init_default(audio_t *aud, int channels, int sampleRate, int frameSize, PaStreamCallback callback) { + PaError paErr; + int opusErr; + + if ((paErr = Pa_Initialize()) != paNoError) { + fprintf(stderr, "Cannot initialise PortAudio: %s\n", Pa_GetErrorText(paErr)); + return -1; + } + + aud->opusBufSz = frameSize * channels; + aud->opusBuf = (uint8_t *)malloc(aud->opusBufSz * sizeof(uint8_t)); + + aud->opusEnc = opus_encoder_create(sampleRate, channels, OPUS_APPLICATION_VOIP, &opusErr); + if (opusErr != OPUS_OK) { + fprintf(stderr, "An Opus encoder cannot be created: %s\n", opus_strerror(opusErr)); + return -1; + } + + aud->opusDec = opus_decoder_create(sampleRate, channels, &opusErr); + if (opusErr != OPUS_OK) { + fprintf(stderr, "An Opus decoder cannot be created: %s\n", opus_strerror(opusErr)); + return -1; + } + + if ((paErr = Pa_OpenDefaultStream(&aud->stream, channels, channels, paFloat32, + sampleRate, frameSize, callback, aud)) != paNoError) { + fprintf(stderr, "Cannot open a PortAudio stream: %s\n", Pa_GetErrorText(paErr)); + return -1; + } + + if ((paErr = Pa_StartStream(aud->stream)) != paNoError) { + fprintf(stderr, "Cannot start a PortAudio stream: %s\n", Pa_GetErrorText(paErr)); + return -1; + } + + return 0; +} + +int audio_destroy(audio_t *aud) { + PaError paErr; + + if (aud->stream) { + if ((paErr = Pa_StopStream(aud->stream)) != paNoError) { + fprintf(stderr, "Cannot stop a PortAudio stream: %s\n", Pa_GetErrorText(paErr)); + return -1; + } + + if ((paErr = Pa_CloseStream(aud->stream)) != paNoError) { + fprintf(stderr, "Cannot close a PortAudio stream: %s\n", Pa_GetErrorText(paErr)); + return -1; + } + } + + if ((paErr = Pa_Terminate()) != paNoError) { + fprintf(stderr, "Cannot terminate PortAudio: %s\n", Pa_GetErrorText(paErr)); + return -1; + } + + if (aud->opusEnc) + opus_encoder_destroy(aud->opusEnc); + + if (aud->opusDec) + opus_decoder_destroy(aud->opusDec); + + if (aud->opusBuf) + free(aud->opusBuf); + + return 0; +} \ No newline at end of file diff --git a/src/audio.h b/src/audio.h new file mode 100644 index 0000000..ee0f19c --- /dev/null +++ b/src/audio.h @@ -0,0 +1,25 @@ +#ifndef _AUDIO_H_ +#define _AUDIO_H_ + +#include +#include + +#include +#include + +typedef struct audio_t { + PaStream *stream; + OpusEncoder *opusEnc; + OpusDecoder *opusDec; + uint8_t *opusBuf; + size_t opusBufSz; +} audio_t; + +int audio_default_callback(const void *input, void *output, + unsigned long frameCount, const PaStreamCallbackTimeInfo *timeInfo, + PaStreamCallbackFlags statusFlags, void *userData); + +int audio_init_default(audio_t *aud, int channels, int sampleRate, int frameSize, PaStreamCallback *callback); +int audio_destroy(audio_t *aud); + +#endif /* _AUDIO_H_ */ \ No newline at end of file diff --git a/src/crypto.h b/src/crypto.h new file mode 100644 index 0000000..d0ab3bf --- /dev/null +++ b/src/crypto.h @@ -0,0 +1,6 @@ +#ifndef _CRYPTO_H_ +#define _CRYPTO_H_ + + + +#endif /* _CRYPTO_H_ */ \ No newline at end of file diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..2724557 --- /dev/null +++ b/src/main.c @@ -0,0 +1,20 @@ +#include + +#include "audio.h" + +int main(int argc, char **argv) { + (void)argv; + (void)argc; + + audio_t aud; + + audio_init_default(&aud, 1, 48000, 480, audio_default_callback); + + printf("Listening... "); + getchar(); + printf("Done!\n"); + + audio_destroy(&aud); + + return 0; +} \ No newline at end of file