Skip to content

Commit 60040a9

Browse files
committed
Merge branch 'develop'
2 parents 628dd30 + 69258d4 commit 60040a9

27 files changed

+38779
-132
lines changed

CMakeLists.txt

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,11 @@ set(CMAKE_C_FLAGS
6868
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -O0 -ggdb")
6969
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -O3 -ffast-math -s -DNDEBUG")
7070

71+
# Fix for MacOS X broken libxml2 Homebrew installation in MacOS Catalina
72+
if(APPLE)
73+
set(XML2_INCLUDE_DIRS "/usr/local/opt/libxml2/include/libxml2")
74+
endif()
75+
7176
########################## pkg-config description #############################
7277
set(SIGUTILS_PC_FILE_PATH "${PROJECT_BINARY_DIR}/suscan.pc")
7378

@@ -86,16 +91,21 @@ install(
8691
############################ Suscan library build #############################
8792
set(RSRC_CONFIG_FILES
8893
${RSRCDIR}/autogains.xml
89-
${RSRCDIR}/palettes.xml)
94+
${RSRCDIR}/palettes.xml
95+
${RSRCDIR}/frequency_allocations.xml)
9096

9197
set(UTIL_HEADERS
98+
${UTILDIR}/compat.h
99+
${UTILDIR}/macos-barriers.h
100+
${UTILDIR}/macos-barriers.imp.h
92101
${UTILDIR}/confdb.h
93102
${UTILDIR}/cfg.h
94103
${UTILDIR}/object.h
95104
${UTILDIR}/util.h)
96105

97106
set(UTIL_SOURCES
98107
${UTILDIR}/cfg.c
108+
${UTILDIR}/compat.c
99109
${UTILDIR}/confdb.c
100110
${UTILDIR}/deserialize.c
101111
${UTILDIR}/object.c
@@ -114,7 +124,8 @@ set(INSPECTOR_LIB_SOURCES
114124
${INSPECTORDIR}/ask.c
115125
${INSPECTORDIR}/audio.c
116126
${INSPECTORDIR}/fsk.c
117-
${INSPECTORDIR}/psk.c)
127+
${INSPECTORDIR}/psk.c
128+
${INSPECTORDIR}/raw.c)
118129

119130
set(CODEC_LIB_HEADERS ${CODECLIBDIR}/codec.h)
120131

@@ -168,7 +179,15 @@ set(ANALYZER_LIB_SOURCES
168179
${ANALYZERDIR}/worker.c
169180
${ESTIMATOR_SOURCES}
170181
${SPECTSRC_SOURCES})
171-
182+
183+
link_directories(
184+
${PROJECT_BINARY_DIR}
185+
${SNDFILE_LIBRARY_DIRS}
186+
${FFTW3_LIBRARY_DIRS}
187+
${SOAPYSDR_LIBRARY_DIRS}
188+
${SIGUTILS_LIBRARY_DIRS}
189+
${XML2_LIBRARY_DIRS})
190+
172191
add_library(
173192
suscan SHARED
174193
${UTIL_HEADERS}
@@ -189,11 +208,29 @@ set_target_properties(suscan PROPERTIES COMPILE_FLAGS "${SIGUTILS_SPC_CFLAGS}")
189208
set_target_properties(suscan PROPERTIES LINK_FLAGS "${SIGUTILS_SPC_LDFLAGS}")
190209

191210
# Required dependencies
211+
if(APPLE)
212+
# Required to retrieve bundle path
213+
target_link_libraries(suscan "-framework CoreFoundation")
214+
endif()
215+
216+
target_link_libraries(suscan m ${SIGUTILS_LIBRARIES})
217+
192218
target_include_directories(suscan SYSTEM PUBLIC ${SNDFILE_INCLUDE_DIRS})
219+
target_link_libraries(suscan ${SNDFILE_LIBRARIES})
220+
221+
target_include_directories(suscan SYSTEM PUBLIC ${SNDFILE_INCLUDE_DIRS})
222+
target_link_libraries(suscan ${SNDFILE_LIBRARIES})
223+
193224
target_include_directories(suscan SYSTEM PUBLIC ${FFTW3_INCLUDE_DIRS})
225+
target_link_libraries(suscan ${FFTW3_LIBRARIES})
226+
194227
target_include_directories(suscan SYSTEM PUBLIC ${SOAPYSDR_INCLUDE_DIRS})
195-
target_include_directories(suscan SYSTEM PUBLIC ${SIGUTILS_INCLUDE_DIRS})
228+
target_link_libraries(suscan ${SOAPYSDR_LIBRARIES})
229+
196230
target_include_directories(suscan SYSTEM PUBLIC ${XML2_INCLUDE_DIRS})
231+
target_link_libraries(suscan ${XML2_LIBRARIES})
232+
233+
target_link_libraries(suscan ${CMAKE_THREAD_LIBS_INIT})
197234

198235
# Optional dependencies
199236
if(VOLK_FOUND)

analyzer/analyzer.c

Lines changed: 153 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,92 @@
3535
#include "mq.h"
3636
#include "msg.h"
3737

38+
/************************ Overridable request API ****************************/
39+
SUPRIVATE void
40+
suscan_inspector_overridable_request_destroy(
41+
struct suscan_inspector_overridable_request *self)
42+
{
43+
free(self);
44+
}
45+
46+
SUPRIVATE struct suscan_inspector_overridable_request *
47+
suscan_inspector_overridable_request_new(suscan_inspector_t *insp)
48+
{
49+
struct suscan_inspector_overridable_request *new = NULL;
50+
51+
SU_TRYCATCH(
52+
new = calloc(1, sizeof(struct suscan_inspector_overridable_request)),
53+
goto done);
54+
55+
new->insp = insp;
56+
57+
return new;
58+
59+
done:
60+
if (new != NULL)
61+
suscan_inspector_overridable_request_destroy(new);
62+
63+
return NULL;
64+
}
65+
66+
struct suscan_inspector_overridable_request *
67+
suscan_analyzer_acquire_overridable(
68+
suscan_analyzer_t *self,
69+
SUHANDLE handle)
70+
{
71+
struct suscan_inspector_overridable_request *req = NULL;
72+
struct suscan_inspector_overridable_request *own_req = NULL;
73+
suscan_inspector_t *insp = NULL;
74+
75+
/*
76+
* TODO: Maybe acquire scheduler mutex?
77+
*/
78+
79+
SU_TRYCATCH(suscan_analyzer_lock_inspector_list(self), goto done);
80+
SU_TRYCATCH(insp = suscan_analyzer_get_inspector(self, handle), goto done);
81+
SU_TRYCATCH(insp->state == SUSCAN_ASYNC_STATE_RUNNING, goto done);
82+
83+
if ((req = suscan_inspector_get_userdata(insp)) == NULL) {
84+
/* No userdata. Release mutex, create object and lock again. */
85+
suscan_analyzer_unlock_inspector_list(self);
86+
87+
SU_TRYCATCH(
88+
own_req = suscan_inspector_overridable_request_new(insp),
89+
goto done);
90+
91+
SU_TRYCATCH(suscan_analyzer_lock_inspector_list(self), goto done);
92+
93+
/* Many things may have happened here */
94+
SU_TRYCATCH(handle >= 0 && handle < self->inspector_count, goto done);
95+
SU_TRYCATCH(insp = suscan_analyzer_get_inspector(self, handle), goto done);
96+
SU_TRYCATCH(insp->state == SUSCAN_ASYNC_STATE_RUNNING, goto done);
97+
98+
req = own_req;
99+
own_req = NULL;
100+
101+
req->next = self->insp_overridable;
102+
self->insp_overridable = req;
103+
104+
suscan_inspector_set_userdata(insp, req);
105+
}
106+
107+
done:
108+
if (own_req != NULL)
109+
suscan_inspector_overridable_request_destroy(own_req);
110+
111+
return req;
112+
}
113+
114+
SUBOOL
115+
suscan_analyzer_release_overridable(
116+
suscan_analyzer_t *self,
117+
struct suscan_inspector_overridable_request *rq)
118+
{
119+
suscan_analyzer_unlock_inspector_list(self);
120+
121+
return SU_TRUE;
122+
}
123+
38124
/************************* Baseband filter API *******************************/
39125
SUPRIVATE struct suscan_analyzer_baseband_filter *
40126
suscan_analyzer_baseband_filter_new(
@@ -106,7 +192,17 @@ suscan_analyzer_unlock_loop(suscan_analyzer_t *analyzer)
106192
(void) pthread_mutex_unlock(&analyzer->loop_mutex);
107193
}
108194

195+
SUBOOL
196+
suscan_analyzer_lock_inspector_list(suscan_analyzer_t *analyzer)
197+
{
198+
return pthread_mutex_lock(&analyzer->inspector_list_mutex) != -1;
199+
}
109200

201+
void
202+
suscan_analyzer_unlock_inspector_list(suscan_analyzer_t *analyzer)
203+
{
204+
(void) pthread_mutex_unlock(&analyzer->inspector_list_mutex);
205+
}
110206

111207
/************************* Main analyzer thread *******************************/
112208
void
@@ -347,7 +443,17 @@ suscan_analyzer_thread(void *data)
347443
goto done);
348444

349445
self->interval_channels = new_params->channel_update_int;
350-
self->interval_psd = new_params->psd_update_int;
446+
447+
if (SU_ABS(self->interval_psd - new_params->psd_update_int) > 1e-6) {
448+
self->interval_psd = new_params->psd_update_int;
449+
self->det_num_psd = 0;
450+
#ifdef __linux__
451+
clock_gettime(CLOCK_MONOTONIC_COARSE, &self->last_psd);
452+
#else
453+
clock_gettime(CLOCK_MONOTONIC, &self->last_psd);
454+
#endif /* __linux__ */
455+
}
456+
351457
/* ^^^^^^^^^^^^^ Source parameters update end ^^^^^^^^^^^^^^^^^ */
352458

353459
SU_TRYCATCH(
@@ -456,9 +562,7 @@ suscan_analyzer_init_detector_params(
456562
*params = self->params.detector_params;
457563

458564
/* Populate members with source information */
459-
params->mode = self->params.mode == SUSCAN_ANALYZER_MODE_CHANNEL
460-
? SU_CHANNEL_DETECTOR_MODE_DISCOVERY
461-
: SU_CHANNEL_DETECTOR_MODE_SPECTRUM;
565+
params->mode = SU_CHANNEL_DETECTOR_MODE_SPECTRUM;
462566

463567
params->samp_rate = suscan_analyzer_get_samp_rate(self);
464568

@@ -628,7 +732,7 @@ suscan_analyzer_destroy(suscan_analyzer_t *analyzer)
628732
{
629733
uint32_t type;
630734
unsigned int i;
631-
735+
struct suscan_inspector_overridable_request *req;
632736
void *private;
633737

634738
/* Prevent source from entering in timeout loops */
@@ -690,10 +794,23 @@ suscan_analyzer_destroy(suscan_analyzer_t *analyzer)
690794
if (analyzer->loop_init)
691795
pthread_mutex_destroy(&analyzer->loop_mutex);
692796

797+
if (analyzer->inspector_list_init)
798+
pthread_mutex_destroy(&analyzer->inspector_list_mutex);
799+
693800
/* Free spectral tuner */
694801
if (analyzer->stuner != NULL)
695802
su_specttuner_destroy(analyzer->stuner);
696803

804+
/* Free all pending overridable requests */
805+
while (analyzer->insp_overridable != NULL) {
806+
req = analyzer->insp_overridable->next;
807+
808+
suscan_inspector_overridable_request_destroy(
809+
analyzer->insp_overridable);
810+
811+
analyzer->insp_overridable = req;
812+
}
813+
697814
/* Free read buffer */
698815
if (analyzer->read_buf != NULL)
699816
free(analyzer->read_buf);
@@ -798,7 +915,7 @@ suscan_analyzer_new(
798915

799916
/* Allocate read buffer */
800917

801-
new->read_size = params->detector_params.window_size;
918+
new->read_size = SUSCAN_ANALYZER_READ_SIZE; /* params->detector_params.window_size; */
802919

803920
if ((new->read_buf = malloc(
804921
new->read_size * sizeof(SUCOMPLEX))) == NULL) {
@@ -821,8 +938,15 @@ suscan_analyzer_new(
821938
/* Periodic updates */
822939
new->interval_channels = params->channel_update_int;
823940
new->interval_psd = params->psd_update_int;
824-
clock_gettime(CLOCK_MONOTONIC_RAW, &new->last_psd);
825-
clock_gettime(CLOCK_MONOTONIC_RAW, &new->last_channels);
941+
942+
#ifdef __linux__
943+
clock_gettime(CLOCK_MONOTONIC_COARSE, &new->last_psd);
944+
clock_gettime(CLOCK_MONOTONIC_COARSE, &new->last_channels);
945+
#else
946+
clock_gettime(CLOCK_MONOTONIC, &new->last_psd);
947+
clock_gettime(CLOCK_MONOTONIC, &new->last_channels);
948+
#endif
949+
826950

827951
/* Create channel detector */
828952
(void) pthread_mutex_init(&new->loop_mutex, NULL); /* Always succeeds */
@@ -852,7 +976,7 @@ suscan_analyzer_new(
852976
new->gain_req_mutex_init = SU_TRUE;
853977

854978
/* Create spectral tuner, with matching read size */
855-
st_params.window_size = new->read_size * 4;
979+
st_params.window_size = det_params.window_size;
856980
SU_TRYCATCH(new->stuner = su_specttuner_new(&st_params), goto fail);
857981

858982
/* Create inspector scheduler and barrier */
@@ -875,9 +999,29 @@ suscan_analyzer_new(
875999
*/
8761000
SU_TRYCATCH(pthread_mutex_init(&new->sched_lock, NULL) == 0, goto fail);
8771001

1002+
/*
1003+
* This mutex will protect access to the inspector list. It will allow
1004+
* resolving an inspector handle without blocking an entire callback
1005+
*/
1006+
1007+
SU_TRYCATCH(
1008+
pthread_mutex_init(&new->inspector_list_mutex, NULL) == 0,
1009+
goto fail);
1010+
new->inspector_list_init = SU_TRUE;
1011+
8781012
new->mq_out = mq;
8791013

8801014
SU_TRYCATCH(suscan_source_start_capture(new->source), goto fail);
1015+
1016+
if (new->read_size < new->source->mtu) {
1017+
new->read_size = new->source->mtu;
1018+
SUCOMPLEX *temp;
1019+
SU_TRYCATCH(
1020+
temp = realloc(new->read_buf, new->read_size * sizeof(SUCOMPLEX)),
1021+
goto fail);
1022+
new->read_buf = temp;
1023+
}
1024+
8811025
new->effective_samp_rate = suscan_analyzer_get_samp_rate(new);
8821026

8831027
/*

0 commit comments

Comments
 (0)