forked from charlie-foxtrot/RTLSDR-Airband
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathutil.cpp
190 lines (169 loc) · 4.44 KB
/
util.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
/*
* util.cpp
* Miscellaneous routines
*
* Copyright (c) 2015-2020 Tomasz Lemiech <[email protected]>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <unistd.h>
#include <stdint.h> // uint32_t
#include <syslog.h>
#include <iostream>
#include <cstdlib>
#include <cstdarg>
#include <cstring>
#include <cerrno>
#include <cmath>
#include <shout/shout.h>
#include <lame/lame.h>
#include "rtl_airband.h"
FILE *debugf;
void error() {
close_debug();
_exit(1);
}
int atomic_inc(volatile int *pv)
{
return __sync_fetch_and_add(pv, 1);
}
int atomic_dec(volatile int *pv)
{
return __sync_fetch_and_sub(pv, 1);
}
int atomic_get(volatile int *pv)
{
return __sync_fetch_and_add(pv, 0);
}
void log(int priority, const char *format, ...) {
va_list args;
va_start(args, format);
if(do_syslog)
vsyslog(priority, format, args);
else if(foreground)
vprintf(format, args);
va_end(args);
}
void init_debug (char *file) {
if(DEBUG) {
if(!file) return;
if((debugf = fopen(file, "a")) == NULL) {
std::cerr<<"Could not open debug file "<<file<<": "<<strerror(errno)<<"\n";
error();
}
}
}
void close_debug() {
if(DEBUG) {
if(!debugf) return;
fclose(debugf);
}
}
void tag_queue_put(device_t *dev, int freq, struct timeval tv) {
pthread_mutex_lock(&dev->tag_queue_lock);
dev->tq_head++; dev->tq_head %= TAG_QUEUE_LEN;
if(dev->tq_head == dev->tq_tail) {
log(LOG_WARNING, "tag_queue_put: queue overrun\n");
dev->tq_tail++;
}
dev->tag_queue[dev->tq_head].freq = freq;
memcpy(&dev->tag_queue[dev->tq_head].tv, &tv, sizeof(struct timeval));
pthread_mutex_unlock(&dev->tag_queue_lock);
}
void tag_queue_get(device_t *dev, struct freq_tag *tag) {
int i;
if(!tag) return;
pthread_mutex_lock(&dev->tag_queue_lock);
if(dev->tq_head == dev->tq_tail) { /* empty queue */
tag->freq = -1;
} else {
// read queue entry at pos tq_tail+1 without dequeueing it
i = dev->tq_tail+1; i %= TAG_QUEUE_LEN;
tag->freq = dev->tag_queue[i].freq;
memcpy(&tag->tv, &dev->tag_queue[i].tv, sizeof(struct timeval));
}
pthread_mutex_unlock(&dev->tag_queue_lock);
}
void tag_queue_advance(device_t *dev) {
pthread_mutex_lock(&dev->tag_queue_lock);
dev->tq_tail++; dev->tq_tail %= TAG_QUEUE_LEN;
pthread_mutex_unlock(&dev->tag_queue_lock);
}
void *xcalloc(size_t nmemb, size_t size, const char *file, const int line, const char *func) {
void *ptr = calloc(nmemb, size);
if(ptr == NULL) {
log(LOG_ERR, "%s:%d: %s(): calloc(%zu, %zu) failed: %s\n",
file, line, func, nmemb, size, strerror(errno));
error();
}
return ptr;
}
void *xrealloc(void *ptr, size_t size, const char *file, const int line, const char *func) {
ptr = realloc(ptr, size);
if(ptr == NULL) {
log(LOG_ERR, "%s:%d: %s(): realloc(%zu) failed: %s\n",
file, line, func, size, strerror(errno));
error();
}
return ptr;
}
static float sin_lut[257], cos_lut[257];
void sincosf_lut_init() {
for(uint32_t i = 0; i < 256; i++)
sincosf(2.0f * M_PI * (float)i / 256.0f, sin_lut + i, cos_lut + i);
sin_lut[256] = sin_lut[0];
cos_lut[256] = cos_lut[0];
}
// phi range must be (0..1), rescaled to 0x0-0xFFFFFF
void sincosf_lut(uint32_t phi, float *sine, float *cosine) {
float v1, v2, fract;
uint32_t idx;
// get LUT index
idx = phi >> 16;
// cast fixed point fraction to float
fract = (float)(phi & 0xffff) / 65536.0f;
// get two adjacent values from LUT and interpolate
v1 = sin_lut[idx];
v2 = sin_lut[idx+1];
*sine = v1 + (v2 - v1) * fract;
v1 = cos_lut[idx];
v2 = cos_lut[idx+1];
*cosine = v1 + (v2 - v1) * fract;
}
/* librtlsdr-keenerd, (c) Kyle Keen */
double atofs(char *s) {
char last;
int len;
double suff = 1.0;
len = strlen(s);
last = s[len-1];
s[len-1] = '\0';
switch (last) {
case 'g':
case 'G':
suff *= 1e3;
case 'm':
case 'M':
suff *= 1e3;
case 'k':
case 'K':
suff *= 1e3;
suff *= atof(s);
s[len-1] = last;
return suff;
}
s[len-1] = last;
return atof(s);
}
// vim: ts=4