mirror of
https://github.com/radio95-rnt/fm95.git
synced 2026-02-27 11:33:54 +01:00
part 2?
This commit is contained in:
@@ -18,12 +18,17 @@ file(GLOB MODULATION_FILES "modulation/*.c")
|
|||||||
file(GLOB DSP_FILES "dsp/*.c")
|
file(GLOB DSP_FILES "dsp/*.c")
|
||||||
file(GLOB IO_FILES "io/*.c")
|
file(GLOB IO_FILES "io/*.c")
|
||||||
|
|
||||||
|
file(GLOB INIH_FILES "inih/*.c")
|
||||||
|
|
||||||
|
add_library(inih OBJECT ${INIH_FILES})
|
||||||
|
|
||||||
# add_library(libfm OBJECT ${LIB_FILES})
|
# add_library(libfm OBJECT ${LIB_FILES})
|
||||||
add_library(libfmfilter OBJECT ${FILTER_FILES})
|
add_library(libfmfilter OBJECT ${FILTER_FILES})
|
||||||
add_library(libfmmodulation OBJECT ${MODULATION_FILES})
|
add_library(libfmmodulation OBJECT ${MODULATION_FILES})
|
||||||
add_library(libfmdsp OBJECT ${DSP_FILES})
|
add_library(libfmdsp OBJECT ${DSP_FILES})
|
||||||
add_library(libfmio OBJECT ${IO_FILES})
|
add_library(libfmio OBJECT ${IO_FILES})
|
||||||
|
|
||||||
|
|
||||||
# Define DEBUG macro for Debug builds on libraries
|
# Define DEBUG macro for Debug builds on libraries
|
||||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||||
# target_compile_definitions(libfm PRIVATE DEBUG=1)
|
# target_compile_definitions(libfm PRIVATE DEBUG=1)
|
||||||
@@ -33,7 +38,7 @@ if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
|||||||
target_compile_definitions(libfmio PRIVATE DEBUG=1)
|
target_compile_definitions(libfmio PRIVATE DEBUG=1)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(FM_LIBS libfmfilter libfmmodulation libfmio libfmdsp pulse pulse-simple m liquid)
|
set(FM_LIBS inih libfmfilter libfmmodulation libfmio libfmdsp pulse pulse-simple m liquid)
|
||||||
|
|
||||||
foreach(SRC_FILE ${SRC_FILES})
|
foreach(SRC_FILE ${SRC_FILES})
|
||||||
get_filename_component(EXEC_NAME ${SRC_FILE} NAME_WE)
|
get_filename_component(EXEC_NAME ${SRC_FILE} NAME_WE)
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ and one output:
|
|||||||
|
|
||||||
## How to compile?
|
## How to compile?
|
||||||
|
|
||||||
|
Note that you're required also to load submodules, if you don't know what that means then ask ChatGPT
|
||||||
|
|
||||||
To compile you need `cmake`, `liquid-dsp` and `libpulse-dev`, if you have those then do these commands:
|
To compile you need `cmake`, `liquid-dsp` and `libpulse-dev`, if you have those then do these commands:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|||||||
131
fm95.md
Normal file
131
fm95.md
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
# FM95 Configuration File
|
||||||
|
|
||||||
|
This document describes the configuration file format for the FM95 FM transmitter software.
|
||||||
|
|
||||||
|
## File Format
|
||||||
|
|
||||||
|
The configuration file uses standard INI format with sections and key-value pairs. Comments can be added using the `#` or `;` character at the beginning of a line.
|
||||||
|
|
||||||
|
## Configuration Sections
|
||||||
|
|
||||||
|
### [fm95] - Main Settings
|
||||||
|
|
||||||
|
This section contains the core FM95 transmission parameters.
|
||||||
|
|
||||||
|
#### Audio Processing
|
||||||
|
|
||||||
|
- **`stereo`** (0 or 1, default: 0)
|
||||||
|
Enable stereo transmission. Set to 1 for stereo, 0 for mono.
|
||||||
|
|
||||||
|
- **`audio_volume`** (float)
|
||||||
|
Audio input volume multiplier. 1.0 = unity gain, values > 1.0 may cause distortion.
|
||||||
|
|
||||||
|
- **`master_volume`** (float)
|
||||||
|
Master output volume control. Affects overall transmission level.
|
||||||
|
|
||||||
|
- **`clipper_threshold`** (float)
|
||||||
|
Audio clipper threshold to prevent overmodulation. Lower values = more aggressive clipping.
|
||||||
|
|
||||||
|
- **`preemphasis`** (float, microseconds)
|
||||||
|
Pre-emphasis time constant in microseconds. Common values: 50 (Europe), 75 (North America).
|
||||||
|
|
||||||
|
#### Stereo Processing
|
||||||
|
|
||||||
|
- **`polar_stereo`** (0 or 1, default: 0)
|
||||||
|
Enable polar stereo encoding.
|
||||||
|
|
||||||
|
#### RDS (Radio Data System)
|
||||||
|
|
||||||
|
- **`rds_streams`** (integer, range: 1-4)
|
||||||
|
Number of RDS data streams to process simultaneously. More streams allow richer RDS data but require more processing power.
|
||||||
|
|
||||||
|
#### MPX (Multiplex) Settings
|
||||||
|
|
||||||
|
- **`mpx_power`** (float)
|
||||||
|
MPX signal power level. For BS412.
|
||||||
|
|
||||||
|
- **`mpx_deviation`** (float, Hz)
|
||||||
|
Maximum frequency deviation for MPX signals. Standard value is 75000 Hz for FM broadcast.
|
||||||
|
|
||||||
|
#### Calibration
|
||||||
|
|
||||||
|
- **`calibration`** (0-2, default: 0)
|
||||||
|
Enable calibration mode for testing and adjustment. (2 enables 40 hz square wave instead of the 400 hz sine)
|
||||||
|
|
||||||
|
#### Frequency Deviation
|
||||||
|
|
||||||
|
- **`deviation`** (float, Hz)
|
||||||
|
Maximum frequency deviation. Standard FM broadcast uses 75000 Hz. This setting affects the master_volume automatically.
|
||||||
|
|
||||||
|
### [devices] - Audio Device Configuration
|
||||||
|
|
||||||
|
This section specifies the audio devices to use for input and output.
|
||||||
|
|
||||||
|
- **`input`** (string, max 63 chars)
|
||||||
|
Primary audio input device
|
||||||
|
|
||||||
|
- **`output`** (string, max 63 chars)
|
||||||
|
MPX input
|
||||||
|
|
||||||
|
- **`mpx`** (string, max 63 chars)
|
||||||
|
MPX (multiplex) input device for subcarrier input
|
||||||
|
|
||||||
|
- **`rds`** (string, max 63 chars)
|
||||||
|
RDS signal input
|
||||||
|
|
||||||
|
## Example Configuration
|
||||||
|
|
||||||
|
```ini
|
||||||
|
# FM95 Configuration File
|
||||||
|
# Lines starting with # are comments
|
||||||
|
|
||||||
|
[fm95]
|
||||||
|
# Enable stereo transmission
|
||||||
|
stereo=1
|
||||||
|
|
||||||
|
# Audio levels (1.0 = unity gain)
|
||||||
|
audio_volume=0.8
|
||||||
|
master_volume=1.0
|
||||||
|
|
||||||
|
# Prevent overmodulation
|
||||||
|
clipper_threshold=0.9
|
||||||
|
|
||||||
|
# Pre-emphasis for Europe (50µs) or North America (75µs)
|
||||||
|
preemphasis=50
|
||||||
|
|
||||||
|
# Enhanced stereo processing
|
||||||
|
polar_stereo=1
|
||||||
|
|
||||||
|
# RDS configuration
|
||||||
|
rds_streams=2
|
||||||
|
|
||||||
|
# MPX settings
|
||||||
|
mpx_power=0.1
|
||||||
|
mpx_deviation=75000
|
||||||
|
|
||||||
|
# Standard FM deviation
|
||||||
|
deviation=75000
|
||||||
|
|
||||||
|
# Enable calibration mode for testing
|
||||||
|
calibration=0
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Important Notes
|
||||||
|
|
||||||
|
1. **RDS Streams**: Maximum of 4 RDS streams are supported. Exceeding this limit will cause an error.
|
||||||
|
|
||||||
|
2. **String Length**: Device names are limited to 63 characters maximum.
|
||||||
|
|
||||||
|
3. **Deviation Interaction**: The `deviation` setting automatically adjusts `master_volume` using the formula: `master_volume *= (deviation / 75000.0)`. Set deviation last if you want to override master_volume.
|
||||||
|
|
||||||
|
4. **Audio Levels**: Keep audio levels reasonable to prevent distortion. Start with conservative values and adjust as needed.
|
||||||
|
|
||||||
|
5. **Preemphasis**: Use 50µs for European broadcast standards, 75µs for North American standards.
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
- **No audio**: Check device names with system audio tools
|
||||||
|
- **Distorted audio**: Reduce audio_volume and clipper_threshold
|
||||||
|
- **Poor stereo separation**: Enable polar_stereo and adjust mpx_power
|
||||||
|
- **RDS not working**: Verify rds device and ensure rds_streams ≤ 4
|
||||||
189
src/fm95.c
189
src/fm95.c
@@ -1,6 +1,9 @@
|
|||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
#include <liquid/liquid.h>
|
#include <liquid/liquid.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include "../inih/ini.h"
|
||||||
|
|
||||||
|
#define DEFAULT_INI_PATH "/etc/fm95.conf"
|
||||||
|
|
||||||
#define LPF_ORDER 17
|
#define LPF_ORDER 17
|
||||||
|
|
||||||
@@ -64,6 +67,9 @@ typedef struct
|
|||||||
float audio_volume;
|
float audio_volume;
|
||||||
|
|
||||||
uint32_t sample_rate;
|
uint32_t sample_rate;
|
||||||
|
|
||||||
|
// ini dont edit
|
||||||
|
char ini_config_path[64];
|
||||||
} FM95_Config;
|
} FM95_Config;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
@@ -78,6 +84,10 @@ typedef struct {
|
|||||||
char mpx[64];
|
char mpx[64];
|
||||||
char rds[64];
|
char rds[64];
|
||||||
} FM95_DeviceNames;
|
} FM95_DeviceNames;
|
||||||
|
typedef struct {
|
||||||
|
FM95_Config* config;
|
||||||
|
FM95_DeviceNames* devices;
|
||||||
|
} FM95_SetupContext;
|
||||||
|
|
||||||
static void stop(int signum) {
|
static void stop(int signum) {
|
||||||
(void)signum;
|
(void)signum;
|
||||||
@@ -88,36 +98,9 @@ static void stop(int signum) {
|
|||||||
void show_help(char *name) {
|
void show_help(char *name) {
|
||||||
printf(
|
printf(
|
||||||
"Usage: \t%s\n"
|
"Usage: \t%s\n"
|
||||||
"\t-s,--stereo\tForce Stereo [default: %d]\n"
|
"\t-c,--config\tOverride the default config path (%s)\n",
|
||||||
"\t-i,--input\tOverride input device [default: %s]\n"
|
name,
|
||||||
"\t-o,--output\tOverride output device [default: %s]\n"
|
DEFAULT_INI_PATH
|
||||||
"\t-M,--mpx\tOverride MPX input device [default: %s]\n"
|
|
||||||
"\t-r,--rds\tOverride RDS95 input device [default: %s]\n"
|
|
||||||
"\t-R,--rds_strs\tSpecifies the number of the RDS streams provided by RDS95 [default: %d]\n"
|
|
||||||
"\t-c,--clipper\tOverride the clipper threshold [default: %.2f]\n"
|
|
||||||
"\t-O,--polar\tForce Polar Stereo (does not take effect with -s0%s)\n"
|
|
||||||
"\t-e,--preemp\tOverride preemphasis [default: %.2f µs]\n"
|
|
||||||
"\t-V,--calibrate\tEnable Calibration mode [default: off, option 2 enables a 60 hz square wave instead of the 400 hz sine wave]\n"
|
|
||||||
"\t-p,--power\tSet the MPX power [default: %.1f]\n"
|
|
||||||
"\t-P,--mpx_dev\tSet the MPX deviation [default: %.1f]\n"
|
|
||||||
"\t-A,--master_vol\tSet master volume [default: %.3f]\n"
|
|
||||||
"\t-v,--audio_vol\tSet audio volume [default: %.3f]\n"
|
|
||||||
"\t-D,--deviation\tSet audio volume, but with the deviation (100%% being 75000) [default: %.1f]\n"
|
|
||||||
,name
|
|
||||||
,DEFAULT_STEREO
|
|
||||||
,INPUT_DEVICE
|
|
||||||
,OUTPUT_DEVICE
|
|
||||||
,MPX_DEVICE
|
|
||||||
,RDS_DEVICE
|
|
||||||
,DEFAULT_RDS_STREAMS
|
|
||||||
,DEFAULT_CLIPPER_THRESHOLD
|
|
||||||
,(DEFAULT_STEREO_POLAR == 1) ? ", default" : ""
|
|
||||||
,DEFAULT_PREEMPHASIS_TAU/0.000001
|
|
||||||
,DEFAULT_MPX_POWER
|
|
||||||
,DEFAULT_MPX_DEVIATION
|
|
||||||
,DEFAULT_MASTER_VOLUME
|
|
||||||
,DEFAULT_AUDIO_VOLUME
|
|
||||||
,DEFAULT_DEVIATION
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -268,84 +251,20 @@ int run_fm95(const FM95_Config config, FM95_Runtime* runtime) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int parse_arguments(int argc, char **argv, FM95_Config* config, FM95_DeviceNames* dv) {
|
int parse_arguments(int argc, char **argv, FM95_Config* config) {
|
||||||
int opt;
|
int opt;
|
||||||
const char *short_opt = "s::i:o:M:r:R:c:O::e:V::p:P:A:v:D:h";
|
const char *short_opt = "c:h";
|
||||||
struct option long_opt[] =
|
struct option long_opt[] =
|
||||||
{
|
{
|
||||||
{"stereo", optional_argument, NULL, 's'},
|
{"config", required_argument, NULL, 'c'},
|
||||||
{"input", required_argument, NULL, 'i'},
|
|
||||||
{"output", required_argument, NULL, 'o'},
|
|
||||||
{"mpx", required_argument, NULL, 'M'},
|
|
||||||
{"rds", required_argument, NULL, 'r'},
|
|
||||||
{"rds_strs", required_argument, NULL, 'R'},
|
|
||||||
{"clipper", required_argument, NULL, 'c'},
|
|
||||||
{"polar", optional_argument, NULL, 'O'},
|
|
||||||
{"preemp", required_argument, NULL, 'e'},
|
|
||||||
{"calibrate", optional_argument, NULL, 'V'},
|
|
||||||
{"power", required_argument, NULL, 'p'},
|
|
||||||
{"mpx_dev", required_argument, NULL, 'P'},
|
|
||||||
{"master_vol", required_argument, NULL, 'A'},
|
|
||||||
{"audio_vol", required_argument, NULL, 'v'},
|
|
||||||
{"deviation", required_argument, NULL, 'D'},
|
|
||||||
|
|
||||||
{"help", no_argument, NULL, 'h'},
|
{"help", no_argument, NULL, 'h'},
|
||||||
{0, 0, 0, 0}
|
{0, 0, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
while((opt = getopt_long(argc, argv, short_opt, long_opt, NULL)) != -1) {
|
while((opt = getopt_long(argc, argv, short_opt, long_opt, NULL)) != -1) {
|
||||||
switch(opt) {
|
switch(opt) {
|
||||||
case 's': // Stereo
|
case 'c':
|
||||||
if(optarg) config->stereo = atoi(optarg);
|
memcpy(config->ini_config_path, optarg, 63);
|
||||||
else config->stereo = 1;
|
|
||||||
break;
|
|
||||||
case 'i': // Input Device
|
|
||||||
memcpy(dv->input, optarg, 63);
|
|
||||||
break;
|
|
||||||
case 'o': // Output Device
|
|
||||||
memcpy(dv->output, optarg, 63);
|
|
||||||
break;;
|
|
||||||
case 'M': //MPX in
|
|
||||||
memcpy(dv->mpx, optarg, 63);
|
|
||||||
break;
|
|
||||||
case 'r': // RDS in
|
|
||||||
memcpy(dv->rds, optarg, 63);
|
|
||||||
break;
|
|
||||||
case 'R': // RDS Streams
|
|
||||||
config->rds_streams = atoi(optarg);
|
|
||||||
if(config->rds_streams > 4) {
|
|
||||||
printf("RDS Streams more than 4? Nuh uh\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'c': //Clipper
|
|
||||||
config->clipper_threshold = strtof(optarg, NULL);
|
|
||||||
break;
|
|
||||||
case 'O': //Polar
|
|
||||||
if(optarg) config->polar_stereo = atoi(optarg);
|
|
||||||
else config->polar_stereo = 1;
|
|
||||||
break;
|
|
||||||
case 'e': // Preemp
|
|
||||||
config->preemphasis = strtof(optarg, NULL)*1.0e-6f;
|
|
||||||
break;
|
|
||||||
case 'V': // Calibration
|
|
||||||
if(optarg) config->calibration = atoi(optarg);
|
|
||||||
else config->calibration = 1;
|
|
||||||
break;
|
|
||||||
case 'p': // Power
|
|
||||||
config->mpx_power = strtof(optarg, NULL);
|
|
||||||
break;
|
|
||||||
case 'P': // MPX deviation
|
|
||||||
config->mpx_deviation = strtof(optarg, NULL);
|
|
||||||
break;
|
|
||||||
case 'A': // Master vol
|
|
||||||
config->master_volume = strtof(optarg, NULL);
|
|
||||||
break;
|
|
||||||
case 'v': // Audio Volume
|
|
||||||
config->audio_volume = strtof(optarg, NULL);
|
|
||||||
break;
|
|
||||||
case 'D': // Deviation
|
|
||||||
config->master_volume *= (strtof(optarg, NULL)/75000.0f);
|
|
||||||
break;
|
break;
|
||||||
case 'h':
|
case 'h':
|
||||||
show_help(argv[0]);
|
show_help(argv[0]);
|
||||||
@@ -356,6 +275,66 @@ int parse_arguments(int argc, char **argv, FM95_Config* config, FM95_DeviceNames
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int config_handler(void* user, const char* section, const char* name, const char* value) {
|
||||||
|
FM95_SetupContext* ctx = (FM95_SetupContext*)user;
|
||||||
|
FM95_Config* pconfig = ctx->config;
|
||||||
|
FM95_DeviceNames* dv = ctx->devices;
|
||||||
|
|
||||||
|
#define MATCH(s, n) strcmp(section, s) == 0 && strcmp(name, n) == 0
|
||||||
|
|
||||||
|
if (MATCH("fm95", "stereo")) {
|
||||||
|
pconfig->stereo = atoi(value);
|
||||||
|
} else if (MATCH("devices", "input")) {
|
||||||
|
strncpy(dv->input, value, 63);
|
||||||
|
dv->input[63] = '\0';
|
||||||
|
} else if (MATCH("devices", "output")) {
|
||||||
|
strncpy(dv->output, value, 63);
|
||||||
|
dv->output[63] = '\0';
|
||||||
|
} else if (MATCH("devices", "mpx")) {
|
||||||
|
strncpy(dv->mpx, value, 63);
|
||||||
|
dv->mpx[63] = '\0';
|
||||||
|
} else if (MATCH("devices", "rds")) {
|
||||||
|
strncpy(dv->rds, value, 63);
|
||||||
|
dv->rds[63] = '\0';
|
||||||
|
} else if (MATCH("fm95", "rds_streams")) {
|
||||||
|
pconfig->rds_streams = atoi(value);
|
||||||
|
if(pconfig->rds_streams > 4) {
|
||||||
|
printf("RDS Streams more than 4? Nuh uh\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
} else if (MATCH("fm95", "clipper_threshold")) {
|
||||||
|
pconfig->clipper_threshold = strtof(value, NULL);
|
||||||
|
} else if (MATCH("fm95", "polar_stereo")) {
|
||||||
|
pconfig->polar_stereo = atoi(value);
|
||||||
|
} else if (MATCH("fm95", "preemphasis")) {
|
||||||
|
pconfig->preemphasis = strtof(value, NULL) * 1.0e-6f;
|
||||||
|
} else if (MATCH("fm95", "calibration")) {
|
||||||
|
pconfig->calibration = atoi(value);
|
||||||
|
} else if (MATCH("fm95", "mpx_power")) {
|
||||||
|
pconfig->mpx_power = strtof(value, NULL);
|
||||||
|
} else if (MATCH("fm95", "mpx_deviation")) {
|
||||||
|
pconfig->mpx_deviation = strtof(value, NULL);
|
||||||
|
} else if (MATCH("fm95", "master_volume")) {
|
||||||
|
pconfig->master_volume = strtof(value, NULL);
|
||||||
|
} else if (MATCH("fm95", "audio_volume")) {
|
||||||
|
pconfig->audio_volume = strtof(value, NULL);
|
||||||
|
} else if (MATCH("fm95", "deviation")) {
|
||||||
|
pconfig->master_volume *= (strtof(value, NULL) / 75000.0f);
|
||||||
|
} else {
|
||||||
|
return 0; // Unknown section/name
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int parse_config(FM95_Config* config, FM95_DeviceNames* dv) {
|
||||||
|
FM95_SetupContext ctx = {
|
||||||
|
.config = config,
|
||||||
|
.devices = dv
|
||||||
|
};
|
||||||
|
return ini_parse(config->ini_config_path, &config_handler, &ctx);
|
||||||
|
}
|
||||||
|
|
||||||
int setup_audio(FM95_Runtime* runtime, const FM95_DeviceNames dv_names, const FM95_Config config, bool mpx_on, bool rds_on) {
|
int setup_audio(FM95_Runtime* runtime, const FM95_DeviceNames dv_names, const FM95_Config config, bool mpx_on, bool rds_on) {
|
||||||
pa_buffer_attr input_buffer_atr = {
|
pa_buffer_attr input_buffer_atr = {
|
||||||
.maxlength = buffer_maxlength,
|
.maxlength = buffer_maxlength,
|
||||||
@@ -428,7 +407,9 @@ int main(int argc, char **argv) {
|
|||||||
.master_volume = DEFAULT_MASTER_VOLUME,
|
.master_volume = DEFAULT_MASTER_VOLUME,
|
||||||
.audio_volume = DEFAULT_AUDIO_VOLUME,
|
.audio_volume = DEFAULT_AUDIO_VOLUME,
|
||||||
|
|
||||||
.sample_rate = DEFAULT_SAMPLE_RATE
|
.sample_rate = DEFAULT_SAMPLE_RATE,
|
||||||
|
|
||||||
|
.ini_config_path = DEFAULT_INI_PATH
|
||||||
};
|
};
|
||||||
|
|
||||||
FM95_DeviceNames dv_names = {
|
FM95_DeviceNames dv_names = {
|
||||||
@@ -439,9 +420,15 @@ int main(int argc, char **argv) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
int err;
|
int err;
|
||||||
err = parse_arguments(argc, argv, &config, &dv_names);
|
err = parse_arguments(argc, argv, &config);
|
||||||
if(err != 0) return err;
|
if(err != 0) return err;
|
||||||
|
|
||||||
|
err = parse_config(&config, &dv_names);
|
||||||
|
if(err != 0) {
|
||||||
|
printf("Could not parse the config file. (error code as return code)\n");
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
FM95_Runtime runtime;
|
FM95_Runtime runtime;
|
||||||
memset(&runtime, 0, sizeof(runtime));
|
memset(&runtime, 0, sizeof(runtime));
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user