Skip to content

Commit 34ab4ac

Browse files
committed
rtl_fm: no-copy architecture
1 parent e23b92c commit 34ab4ac

File tree

1 file changed

+41
-5
lines changed

1 file changed

+41
-5
lines changed

src/rtl_fm.c

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,11 @@ static int *atan_lut = NULL;
9595
static int atan_lut_size = 131072; /* 512 KB */
9696
static int atan_lut_coef = 8;
9797

98+
// rewrite as dynamic and thread-safe for multi demod/dongle
99+
#define SHARED_SIZE 4
100+
int16_t shared_samples[SHARED_SIZE][MAXIMUM_BUF_LENGTH];
101+
int ss_busy[SHARED_SIZE] = {0};
102+
98103
struct dongle_state
99104
{
100105
int exit_flag;
@@ -104,7 +109,7 @@ struct dongle_state
104109
uint32_t freq;
105110
uint32_t rate;
106111
int gain;
107-
int16_t buf16[MAXIMUM_BUF_LENGTH];
112+
int16_t *buf16;
108113
uint32_t buf_len;
109114
int ppm_error;
110115
int offset_tuning;
@@ -128,7 +133,7 @@ struct demod_state
128133
{
129134
int exit_flag;
130135
pthread_t thread;
131-
int16_t lowpassed[MAXIMUM_BUF_LENGTH];
136+
int16_t *lowpassed;
132137
int lp_len;
133138
int16_t lp_i_hist[10][6];
134139
int16_t lp_q_hist[10][6];
@@ -166,7 +171,7 @@ struct output_state
166171
pthread_t thread;
167172
FILE *file;
168173
char *filename;
169-
int16_t result[MAXIMUM_BUF_LENGTH];
174+
int16_t *result;
170175
int result_len;
171176
int rate;
172177
int wav_format;
@@ -870,6 +875,31 @@ void full_demod(struct demod_state *d)
870875
}
871876
}
872877

878+
int16_t* mark_shared_buffer(void)
879+
{
880+
int i = 0;
881+
while (1) {
882+
i = (i+1) % SHARED_SIZE;
883+
if (ss_busy[i] == 0) {
884+
ss_busy[i] = 1;
885+
return shared_samples[i];
886+
}
887+
}
888+
return NULL;
889+
}
890+
891+
int unmark_shared_buffer(int16_t *buf)
892+
{
893+
int i;
894+
for (i=0; i<SHARED_SIZE; i++) {
895+
if (shared_samples[i] == buf) {
896+
ss_busy[i] = 0;
897+
return 0;
898+
}
899+
}
900+
return 1;
901+
}
902+
873903
static void rtlsdr_callback(unsigned char *buf, uint32_t len, void *ctx)
874904
{
875905
int i;
@@ -890,10 +920,11 @@ static void rtlsdr_callback(unsigned char *buf, uint32_t len, void *ctx)
890920
for (i=0; i<(int)len; i++) {
891921
s->buf16[i] = (int16_t)buf[i] - 127;}
892922
pthread_rwlock_wrlock(&d->rw);
893-
memcpy(d->lowpassed, s->buf16, 2*len);
923+
d->lowpassed = s->buf16;
894924
d->lp_len = len;
895925
pthread_rwlock_unlock(&d->rw);
896926
safe_cond_signal(&d->ready, &d->ready_m);
927+
s->buf16 = mark_shared_buffer();
897928
}
898929

899930
static void *dongle_thread_fn(void *arg)
@@ -921,7 +952,7 @@ static void *demod_thread_fn(void *arg)
921952
continue;
922953
}
923954
pthread_rwlock_wrlock(&o->rw);
924-
memcpy(o->result, d->lowpassed, 2*d->lp_len);
955+
o->result = d->lowpassed;
925956
o->result_len = d->lp_len;
926957
pthread_rwlock_unlock(&o->rw);
927958
safe_cond_signal(&o->ready, &o->ready_m);
@@ -964,6 +995,7 @@ static void *output_thread_fn(void *arg)
964995
safe_cond_wait(&s->ready, &s->ready_m);
965996
pthread_rwlock_rdlock(&s->rw);
966997
fwrite(s->result, 2, s->result_len, s->file);
998+
unmark_shared_buffer(s->result);
967999
pthread_rwlock_unlock(&s->rw);
9681000
continue;
9691001
}
@@ -979,6 +1011,7 @@ static void *output_thread_fn(void *arg)
9791011
if (r != ETIMEDOUT) {
9801012
pthread_rwlock_rdlock(&s->rw);
9811013
fwrite(s->result, 2, s->result_len, s->file);
1014+
unmark_shared_buffer(s->result);
9821015
samples += s->result_len;
9831016
pthread_rwlock_unlock(&s->rw);
9841017
continue;
@@ -1100,6 +1133,7 @@ void dongle_init(struct dongle_state *s)
11001133
s->direct_sampling = 0;
11011134
s->offset_tuning = 0;
11021135
s->demod_target = &demod;
1136+
s->buf16 = mark_shared_buffer();
11031137
}
11041138

11051139
void demod_init(struct demod_state *s)
@@ -1129,6 +1163,7 @@ void demod_init(struct demod_state *s)
11291163
pthread_cond_init(&s->ready, NULL);
11301164
pthread_mutex_init(&s->ready_m, NULL);
11311165
s->output_target = &output;
1166+
s->lowpassed = NULL;
11321167
}
11331168

11341169
void demod_cleanup(struct demod_state *s)
@@ -1144,6 +1179,7 @@ void output_init(struct output_state *s)
11441179
pthread_rwlock_init(&s->rw, NULL);
11451180
pthread_cond_init(&s->ready, NULL);
11461181
pthread_mutex_init(&s->ready_m, NULL);
1182+
s->result = NULL;
11471183
}
11481184

11491185
void output_cleanup(struct output_state *s)

0 commit comments

Comments
 (0)