diff --git a/.vscode/settings.json b/.vscode/settings.json index 3608436..ef942fa 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -27,7 +27,10 @@ "getopt.h": "c", "audio.h": "c", "signal.h": "c", - "debug.h": "c" + "debug.h": "c", + "array": "c", + "string": "c", + "string_view": "c" }, "C_Cpp.errorSquiggles": "disabled" } \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index bfdd0c6..99ef69a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,6 +5,11 @@ project(FMTools LANGUAGES C) set(CMAKE_C_STANDARD 99) set(CMAKE_C_STANDARD_REQUIRED YES) +# Set default build type if not specified +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE Release) +endif() + file(GLOB SRC_FILES "src/*.c") file(GLOB DSP_FILES "dsp/*.c") @@ -19,6 +24,12 @@ add_library(libfmdsp OBJECT ${DSP_FILES}) add_library(libfmio OBJECT ${IO_FILES}) +# Define DEBUG macro for Debug builds on libraries +if(CMAKE_BUILD_TYPE STREQUAL "Debug") + target_compile_definitions(libfmdsp PRIVATE DEBUG=1) + target_compile_definitions(libfmio PRIVATE DEBUG=1) +endif() + set(FM_LIBS libfmio libfmdsp pulse pulse-simple m liquid) foreach(SRC_FILE ${SRC_FILES}) @@ -27,10 +38,15 @@ foreach(SRC_FILE ${SRC_FILES}) add_executable(${EXEC_NAME} ${SRC_FILE}) target_compile_options(${EXEC_NAME} PRIVATE -O2 -Wall -Wextra -Werror -Wno-unused-parameter) target_link_libraries(${EXEC_NAME} PRIVATE ${FM_LIBS}) + + # Define DEBUG macro for Debug builds + if(CMAKE_BUILD_TYPE STREQUAL "Debug") + target_compile_definitions(${EXEC_NAME} PRIVATE DEBUG=1) + endif() install(TARGETS ${EXEC_NAME} DESTINATION /usr/bin PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ WORLD_EXECUTE WORLD_READ) -endforeach() +endforeach() \ No newline at end of file diff --git a/dsp/bs412.c b/dsp/bs412.c index 540b001..caa40cf 100644 --- a/dsp/bs412.c +++ b/dsp/bs412.c @@ -13,6 +13,9 @@ void init_modulation_power_measure(MPXPowerMeasurement* mpx, int sample_rate) { mpx->sample_counter = 0; mpx->sample = 0; mpx->sample_rate = sample_rate; + #ifdef BS412_DEBUG + debug_printf("Initialized MPX power measurement with sample rate: %d\n", sample_rate); + #endif } float measure_mpx(MPXPowerMeasurement* mpx, float deviation) { diff --git a/dsp/bs412.h b/dsp/bs412.h index f99abb7..3ae166b 100644 --- a/dsp/bs412.h +++ b/dsp/bs412.h @@ -1,4 +1,9 @@ #pragma once + +#ifdef DEBUG +#define BS412_DEBUG +#endif + #include #ifdef BS412_DEBUG #include "../lib/debug.h" diff --git a/dsp/fm_modulator.c b/dsp/fm_modulator.c index 552145b..d430e76 100644 --- a/dsp/fm_modulator.c +++ b/dsp/fm_modulator.c @@ -19,9 +19,9 @@ void init_refrenced_fm_modulator(RefrencedFMModulator* fm, Oscillator* osc, floa fm->osc = osc; } -float refrenced_modulate_fm(RefrencedFMModulator* fm, float sample) { +float refrenced_modulate_fm(RefrencedFMModulator* fm, float sample, float phase_multiplier) { float inst_freq = sample * fm->deviation; - float phase = fm->osc->phase + ((M_2PI * inst_freq) / fm->osc->sample_rate); + float phase = (fm->osc->phase * phase_multiplier) + ((M_2PI * inst_freq) / fm->osc->sample_rate); if (phase >= M_2PI) { phase -= M_2PI; diff --git a/dsp/fm_modulator.h b/dsp/fm_modulator.h index a00d893..03b4c7c 100644 --- a/dsp/fm_modulator.h +++ b/dsp/fm_modulator.h @@ -19,4 +19,4 @@ typedef struct Oscillator* osc; } RefrencedFMModulator; void init_refrenced_fm_modulator(RefrencedFMModulator *fm, Oscillator *osc, float deviation); -float refrenced_modulate_fm(RefrencedFMModulator *fm, float sample); +float refrenced_modulate_fm(RefrencedFMModulator *fm, float sample, float phase_multiplier); diff --git a/io/audio.c b/io/audio.c index a16d506..dd4deec 100644 --- a/io/audio.c +++ b/io/audio.c @@ -1,6 +1,10 @@ #include "audio.h" int init_PulseInputDevice(PulseInputDevice* dev, int sample_rate, int channels, char* app_name, char *stream_name, char* device, pa_buffer_attr* buffer_attr) { + #ifdef PULSE_DEBUG + debug_printf("Initializing PulseInputDevice with app_name: %s, stream_name: %s, device: %s, sample_rate: %d, channels: %d\n", app_name, stream_name, device, sample_rate, channels); + #endif + if (dev->initialized) return -1; pa_sample_spec sample_spec = { .format = PA_SAMPLE_FLOAT32NE, @@ -33,6 +37,10 @@ int init_PulseInputDevice(PulseInputDevice* dev, int sample_rate, int channels, } int init_PulseInputDevicef(PulseInputDevice* dev, int sample_rate, int channels, char* app_name, char *stream_name, char* device, pa_buffer_attr* buffer_attr, enum pa_sample_format format) { + #ifdef PULSE_DEBUG + debug_printf("Initializing PulseInputDevice format with app_name: %s, stream_name: %s, device: %s, sample_rate: %d, channels: %d, format: %d\n", app_name, stream_name, device, sample_rate, channels, format); + #endif + if (dev->initialized) return -1; pa_sample_spec sample_spec = { .format = format, @@ -79,6 +87,10 @@ int read_PulseInputDevicef(PulseInputDevice* dev, void* buffer, size_t size) { } void free_PulseInputDevice(PulseInputDevice* dev) { + #ifdef PULSE_DEBUG + debug_printf("Freeing PulseInputDevice with app_name: %s, stream_name: %s, device: %s\n", dev->app_name, dev->stream_name, dev->device); + #endif + if (dev->dev && dev->initialized) pa_simple_free(dev->dev); free(dev->app_name); free(dev->stream_name); @@ -165,6 +177,10 @@ int write_PulseOutputDevicef(PulseOutputDevice* dev, void* buffer, size_t size) } void free_PulseOutputDevice(PulseOutputDevice* dev) { + #ifdef PULSE_DEBUG + debug_printf("Freeing PulseOutputDevice with app_name: %s, stream_name: %s, device: %s\n", dev->app_name, dev->stream_name, dev->device); + #endif + if (dev->dev && dev->initialized) pa_simple_free(dev->dev); free(dev->app_name); free(dev->stream_name); diff --git a/io/audio.h b/io/audio.h index d43f469..c56b44c 100644 --- a/io/audio.h +++ b/io/audio.h @@ -5,6 +5,13 @@ #include #include +#ifdef DEBUG +#define PULSE_DEBUG +#endif +#ifdef PULSE_DEBUG +#include "../lib/debug.h" +#endif + typedef struct { pa_simple* dev; diff --git a/lib/optimization.h b/lib/optimization.h index 5bd4772..e78121e 100644 --- a/lib/optimization.h +++ b/lib/optimization.h @@ -1,7 +1,13 @@ #pragma once #if defined(__ARM_NEON) || defined(__ARM_NEON__) + #ifdef DEBUG + #pragma message("Using ARM NEON optimizations") + #endif #include #define USE_NEON 1 #else + #ifdef DEBUG + #pragma message("ARM NEON optimizations not available") + #endif #define USE_NEON 0 #endif \ No newline at end of file diff --git a/specifications/vban95/VBANProtocol_Specifications.pdf b/specifications/vban95/VBANProtocol_Specifications.pdf new file mode 100644 index 0000000..1c6153d Binary files /dev/null and b/specifications/vban95/VBANProtocol_Specifications.pdf differ diff --git a/src/vban95.c b/src/vban95.c index 845601b..b0581d9 100644 --- a/src/vban95.c +++ b/src/vban95.c @@ -22,7 +22,7 @@ #define MAX_AUDIO_DATA_SIZE (BUF_SIZE - sizeof(VBANHeader)) #define MAX_BUFFER_PACKETS 128 -#define POLL_TIMEOUT_MS 100 +#define POLL_TIMEOUT_MS 75 typedef struct { char data[MAX_AUDIO_DATA_SIZE]; @@ -326,6 +326,11 @@ int main(int argc, char *argv[]) { } continue; } + + if (strncmp(data.packet_data.streamname, stream_name, sizeof(data.packet_data.streamname)) != 0) continue; + + char* audio_data = buffer + sizeof(VBANHeader); + size_t audio_data_size = recv_len - sizeof(VBANHeader); #if 0 if (vban_frame == 0) { vban_frame = data.packet_data.frame_num; @@ -340,8 +345,8 @@ int main(int argc, char *argv[]) { AudioPacket blank_packet; uint8_t fill_value = (data.packet_data.format_type == 0) ? 0 : 128; - memset(blank_packet.data, fill_value, recv_len - sizeof(VBANHeader)); - blank_packet.size = recv_len - sizeof(VBANHeader); + memset(blank_packet.data, fill_value, audio_data_size); + blank_packet.size = audio_data_size; VBANHeaderUnion temp; memset(blank_packet.data, 0, blank_packet.size); @@ -360,8 +365,6 @@ int main(int argc, char *argv[]) { } #endif - if (strncmp(data.packet_data.streamname, stream_name, sizeof(data.packet_data.streamname)) != 0) continue; - uint8_t actual_sr_idx = data.packet_data.protocol_sample_rate_idx & 0x1f; if(vban_last_sr != actual_sr_idx) { vban_last_sr = actual_sr_idx; @@ -409,12 +412,7 @@ int main(int argc, char *argv[]) { continue; } - char* audio_data = buffer + sizeof(VBANHeader); - size_t audio_data_size = recv_len - sizeof(VBANHeader); - - if (add_to_buffer(audio_buffer, audio_data, audio_data_size, &data.packet_data) > 0) { - process_audio_buffer(audio_buffer, &output); - } + if (add_to_buffer(audio_buffer, audio_data, audio_data_size, &data.packet_data) > 0) process_audio_buffer(audio_buffer, &output); } }