diff --git a/.vscode/settings.json b/.vscode/settings.json index 717ab41..cd0f264 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -19,7 +19,6 @@ "stdint.h": "c", "asoundlib.h": "c", "hilbert.h": "c", - "fm_modulator.h": "c", "bs412.h": "c", "gain_control.h": "c", "optimization.h": "c", diff --git a/CMakeLists.txt b/CMakeLists.txt index 689f005..8c181f3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,40 +1,33 @@ cmake_minimum_required(VERSION 3.10) -project(FMTools LANGUAGES C) +project(fm95 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 LIB_FILES "lib/*.c") file(GLOB FILTER_FILES "filter/*.c") -file(GLOB MODULATION_FILES "modulation/*.c") -file(GLOB DSP_FILES "dsp/*.c") -file(GLOB IO_FILES "io/*.c") +file(GLOB LIB_FILES "lib/*.c") file(GLOB INIH_FILES "inih/*.c") add_library(inih OBJECT ${INIH_FILES}) +target_include_directories(inih PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/inih) -# add_library(libfm OBJECT ${LIB_FILES}) add_library(libfmfilter OBJECT ${FILTER_FILES}) -add_library(libfmmodulation OBJECT ${MODULATION_FILES}) -add_library(libfmdsp OBJECT ${DSP_FILES}) -add_library(libfmio OBJECT ${IO_FILES}) +add_library(libfm OBJECT ${LIB_FILES}) + +target_include_directories(libfmfilter PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_SOURCE_DIR}/filter) +target_include_directories(libfm PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_SOURCE_DIR}/lib) -# Define DEBUG macro for Debug builds on libraries if(CMAKE_BUILD_TYPE STREQUAL "Debug") - # target_compile_definitions(libfm PRIVATE DEBUG=1) target_compile_definitions(libfmfilter PRIVATE DEBUG=1) - target_compile_definitions(libfmmodulation PRIVATE DEBUG=1) - target_compile_definitions(libfmdsp PRIVATE DEBUG=1) - target_compile_definitions(libfmio PRIVATE DEBUG=1) + target_compile_definitions(libfm PRIVATE DEBUG=1) endif() foreach(SRC_FILE ${SRC_FILES}) @@ -42,15 +35,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) - + if(EXEC_NAME STREQUAL "fm95") - target_link_libraries(${EXEC_NAME} PRIVATE libfmfilter libfmmodulation libfmdsp libfmio pulse pulse-simple m liquid inih pthread) + target_link_libraries(${EXEC_NAME} PRIVATE libfmfilter libfm pulse pulse-simple m liquid inih pthread) elseif(EXEC_NAME STREQUAL "chimer95") - target_link_libraries(${EXEC_NAME} PRIVATE libfmdsp inih m libfmio pulse pulse-simple liquid pthread) + target_link_libraries(${EXEC_NAME} PRIVATE libfm inih m libfm pulse pulse-simple liquid pthread) elseif(EXEC_NAME STREQUAL "sca95") - target_link_libraries(${EXEC_NAME} PRIVATE libfmmodulation inih m libfmio pulse pulse-simple libfmdsp liquid pthread) + target_link_libraries(${EXEC_NAME} PRIVATE inih m pulse pulse-simple libfm liquid pthread) elseif(EXEC_NAME STREQUAL "vban95") - target_link_libraries(${EXEC_NAME} PRIVATE libfmio pulse pulse-simple liquid pthread) + target_link_libraries(${EXEC_NAME} PRIVATE libfm pulse pulse-simple liquid pthread) else() message(FATAL_ERROR "How do I link this? ${EXEC_NAME}") endif() diff --git a/filter/bs412.h b/filter/bs412.h index 56d6ae3..8a9e5db 100644 --- a/filter/bs412.h +++ b/filter/bs412.h @@ -9,7 +9,7 @@ #include #include #ifdef BS412_DEBUG -#include "../lib/debug.h" +#include "debug.h" #endif typedef struct { diff --git a/dsp/delay.c b/filter/delay.c similarity index 100% rename from dsp/delay.c rename to filter/delay.c diff --git a/dsp/delay.h b/filter/delay.h similarity index 100% rename from dsp/delay.h rename to filter/delay.h diff --git a/filter/iir.h b/filter/iir.h index e157998..a3cd6de 100644 --- a/filter/iir.h +++ b/filter/iir.h @@ -1,7 +1,7 @@ #pragma once #include -#include "../lib/constants.h" +#include "constants.h" typedef struct { diff --git a/modulation/stereo_encoder.c b/filter/stereo_encoder.c similarity index 100% rename from modulation/stereo_encoder.c rename to filter/stereo_encoder.c diff --git a/modulation/stereo_encoder.h b/filter/stereo_encoder.h similarity index 90% rename from modulation/stereo_encoder.h rename to filter/stereo_encoder.h index ef8a54b..f63dda5 100644 --- a/modulation/stereo_encoder.h +++ b/filter/stereo_encoder.h @@ -1,10 +1,10 @@ #pragma once #include -#include "../dsp/oscillator.h" +#include "oscillator.h" #include #include -#include "../dsp/delay.h" +#include "delay.h" typedef struct { diff --git a/fm95.md b/fm95.md index 9179e81..7721dd7 100644 --- a/fm95.md +++ b/fm95.md @@ -43,10 +43,6 @@ Pre-amplification of the audio, before any filters, set to 1 by default, set to Set the deviation, you can use this to easily change to 50 KHz deviation if needed, by default 75 KHz, under the hood it just sets the master volume to x/75000. Expects unit in Hz -### tilt - -This is needed for most DACs, as they have output high pass filtering for DC, such filtering is not phase-linear, for example when DC is played, it will slowly go back to 0, such filtering is bad for square waves and some bass, use calibration 2 to test for tilt, you can use a oscilloscope with a receiver or a RF spectrometer as well as a SDR, if in tilt, you should see a perfect square wave, a signal abruptly jumping between 1 and -1 on a oscilloscope or a signal jumping between -75 and 75 khz on a RF spectrum, for the setting itself this is a simple float with values between 0 (off) and 1 - ### bs412_max This is usually not needed to set, but it sets the max gain for the BS412 compressor, so if it is the default 1, the BS412 compressor will never make the signal louder than it is on the input @@ -99,4 +95,4 @@ lpf cutoff, some run this at 15, because Big FMâ„¢ tells them to, but running th ### headroom -fm95 now computes the volumes for mono and stereo automatically, and headroom is to select how much headroom you want to leave for the mpx, takes a simple float, 100 percent to mute audio +fm95 now computes the volumes for mono and stereo automatically, and headroom is to select how much headroom you want to leave for the mpx, takes a simple float, 1 to mute audio. THIS IS NOT PERCENT diff --git a/lib/constants.h b/include/constants.h similarity index 100% rename from lib/constants.h rename to include/constants.h diff --git a/lib/debug.h b/include/debug.h similarity index 100% rename from lib/debug.h rename to include/debug.h diff --git a/lib/vban.h b/include/vban.h similarity index 100% rename from lib/vban.h rename to include/vban.h diff --git a/io/audio.c b/lib/audio.c similarity index 93% rename from io/audio.c rename to lib/audio.c index 39bc266..883197c 100644 --- a/io/audio.c +++ b/lib/audio.c @@ -17,7 +17,7 @@ int init_PulseInputDevice(PulseInputDevice* dev, const int sample_rate, const in dev->stream_name = strdup(stream_name); dev->device = strdup(device); - dev->direction = 1; + dev->input = 1; int error; dev->dev = pa_simple_new(NULL, app_name, PA_STREAM_RECORD, device, stream_name, &sample_spec, NULL, &new_buffer_attr, &error); @@ -35,10 +35,10 @@ int read_PulseInputDevice(PulseInputDevice* dev, void* buffer, size_t size) { void free_PulseDevice(PulseDevice* dev) { #ifdef PULSE_DEBUG - debug_printf("Freeing PulseDevice with app_name: %s, stream_name: %s, device: %s, direction: %d\n", dev->app_name, dev->stream_name, dev->device, dev->direction); + debug_printf("Freeing PulseDevice with app_name: %s, stream_name: %s, device: %s, input: %d\n", dev->app_name, dev->stream_name, dev->device, dev->input); #endif - if (!dev->direction) pa_simple_drain(dev->dev, NULL); + if (!dev->input) pa_simple_drain(dev->dev, NULL); if (dev->dev && dev->initialized) pa_simple_free(dev->dev); free(dev->app_name); free(dev->stream_name); @@ -62,7 +62,7 @@ int init_PulseOutputDevice(PulseOutputDevice* dev, const int sample_rate, const dev->stream_name = strdup(stream_name); dev->device = strdup(device); - dev->direction = 0; + dev->input = 0; int error; dev->dev = pa_simple_new(NULL, app_name, PA_STREAM_PLAYBACK, device, stream_name, &sample_spec, NULL, &new_buffer_attr, &error); diff --git a/io/audio.h b/lib/audio.h similarity index 94% rename from io/audio.h rename to lib/audio.h index 05cc76a..07e0e92 100644 --- a/io/audio.h +++ b/lib/audio.h @@ -10,7 +10,7 @@ #define PULSE_DEBUG #endif #ifdef PULSE_DEBUG -#include "../lib/debug.h" +#include "debug.h" #endif typedef struct @@ -22,7 +22,7 @@ typedef struct char* stream_name; char* device; bool initialized; - bool direction; // 0 = output, 1 - input + bool input; } PulseDevice; typedef PulseDevice PulseInputDevice; diff --git a/io/ipc.c b/lib/ipc.c similarity index 100% rename from io/ipc.c rename to lib/ipc.c diff --git a/io/ipc.h b/lib/ipc.h similarity index 100% rename from io/ipc.h rename to lib/ipc.h diff --git a/dsp/oscillator.c b/lib/oscillator.c similarity index 100% rename from dsp/oscillator.c rename to lib/oscillator.c diff --git a/dsp/oscillator.h b/lib/oscillator.h similarity index 94% rename from dsp/oscillator.h rename to lib/oscillator.h index 3c5a244..778c98d 100644 --- a/dsp/oscillator.h +++ b/lib/oscillator.h @@ -1,6 +1,6 @@ #pragma once -#include "../lib/constants.h" +#include "constants.h" #include typedef struct { diff --git a/modulation/fm_modulator.c b/modulation/fm_modulator.c deleted file mode 100644 index 5fbb3a7..0000000 --- a/modulation/fm_modulator.c +++ /dev/null @@ -1,15 +0,0 @@ -#include "fm_modulator.h" - -void init_fm_modulator(FMModulator *fm, float frequency, float deviation, float sample_rate) { - fm->frequency = frequency; - fm->deviation = deviation; - fm->sample_rate = sample_rate; - fm->osc_phase = 0.0f; -} - -float modulate_fm(FMModulator *fm, float sample) { - float inst_freq = fm->frequency+(sample*fm->deviation); - fm->osc_phase += (M_2PI * inst_freq) / fm->sample_rate; - fm->osc_phase -= (fm->osc_phase >= M_2PI) ? M_2PI : 0.0f; - return sinf(fm->osc_phase); -} \ No newline at end of file diff --git a/modulation/fm_modulator.h b/modulation/fm_modulator.h deleted file mode 100644 index 624b244..0000000 --- a/modulation/fm_modulator.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include "../dsp/oscillator.h" - -typedef struct -{ - float frequency; - float deviation; - float osc_phase; - float sample_rate; -} FMModulator; - -void init_fm_modulator(FMModulator *fm, float frequency, float deviation, float sample_rate); -float modulate_fm(FMModulator *fm, float sample); \ No newline at end of file diff --git a/src/chimer95.c b/src/chimer95.c index 5c14c3b..3869f74 100644 --- a/src/chimer95.c +++ b/src/chimer95.c @@ -4,14 +4,14 @@ #include #include #include -#include "../inih/ini.h" +#include "ini.h" #define DEFAULT_CONFIG_PATH "/etc/chimer95.conf" #define buffer_maxlength 2048 #define buffer_tlength_fragsize 2048 #define buffer_prebuf 0 -#include "../dsp/oscillator.h" +#include "oscillator.h" #define DEFAULT_FREQ 1000.0f #define DEFAULT_SAMPLE_RATE 8000 @@ -20,7 +20,7 @@ #define BUFFER_SIZE 1024 -#include "../io/audio.h" +#include "audio.h" #define DEFAULT_MASTER_VOLUME 0.5f #define DEFAULT_OFFSET 0 diff --git a/src/fm95.c b/src/fm95.c index eec4253..c8c8727 100644 --- a/src/fm95.c +++ b/src/fm95.c @@ -1,6 +1,6 @@ #include #include -#include "../inih/ini.h" +#include "ini.h" #include #define DEFAULT_INI_PATH "/etc/fm95/fm95.conf" @@ -8,16 +8,16 @@ #define buffer_maxlength 99960 #define buffer_tlength_fragsize 99960 -#include "../dsp/oscillator.h" -#include "../filter/iir.h" -#include "../modulation/stereo_encoder.h" -#include "../filter/bs412.h" -#include "../filter/gain_control.h" +#include "oscillator.h" +#include "iir.h" +#include "stereo_encoder.h" +#include "bs412.h" +#include "gain_control.h" #define BUFFER_SIZE 4998 // This defines how many samples to process at a time, because the loop here is this: get signal -> process signal -> output signal, and when we get signal we actually get BUFFER_SIZE of them -#include "../io/audio.h" -#include "../io/ipc.h" +#include "audio.h" +#include "ipc.h" static volatile sig_atomic_t to_run = 1; static volatile sig_atomic_t to_reload = 0; diff --git a/src/sca95.c b/src/sca95.c index 2c10322..96bc016 100644 --- a/src/sca95.c +++ b/src/sca95.c @@ -9,7 +9,7 @@ #define DEFAULT_DEVIATION 7000.0f #define DEFAULT_CLIPPER_THRESHOLD 1.0f -#include "../modulation/fm_modulator.h" +#include "oscillator.h" #define DEFAULT_SAMPLE_RATE 192000 @@ -18,7 +18,7 @@ #define BUFFER_SIZE 2048 -#include "../io/audio.h" +#include "audio.h" #define DEFAULT_AUDIO_VOLUME 1.0f // Audio volume, before clipper @@ -70,6 +70,27 @@ void show_help(char *name) { ); } +typedef struct { + float frequency; + float deviation; + float osc_phase; + float sample_rate; +} FMModulator; + +void init_fm_modulator(FMModulator *fm, float frequency, float deviation, float sample_rate) { + fm->frequency = frequency; + fm->deviation = deviation; + fm->sample_rate = sample_rate; + fm->osc_phase = 0.0f; +} + +float modulate_fm(FMModulator *fm, float sample) { + float inst_freq = fm->frequency+(sample*fm->deviation); + fm->osc_phase += (M_2PI * inst_freq) / fm->sample_rate; + fm->osc_phase -= (fm->osc_phase >= M_2PI) ? M_2PI : 0.0f; + return sinf(fm->osc_phase); +} + int run_sca95(const Sca95_Config config, Sca95_Runtime* runtime) { FMModulator sca_mod; init_fm_modulator(&sca_mod, config.freq, config.deviation, config.sample_rate); diff --git a/src/vban95.c b/src/vban95.c index db80b63..88b7542 100644 --- a/src/vban95.c +++ b/src/vban95.c @@ -10,9 +10,9 @@ #define buffer_tlength_fragsize 12288 #define buffer_prebuf 64 -#include "../io/audio.h" -#include "../lib/debug.h" -#include "../lib/vban.h" +#include "audio.h" +#include "debug.h" +#include "vban.h" #define BUF_SIZE 1500 #define MAX_AUDIO_DATA_SIZE (BUF_SIZE - sizeof(VBANHeader))