kopia lustrzana https://github.com/Guenael/rtlsdr-wsprd
device index selector
rodzic
6634451e4a
commit
f76dd404ec
81
fano.c
81
fano.c
|
@ -83,21 +83,21 @@ int encode(
|
|||
/* Decode packet with the Fano algorithm.
|
||||
* Return 0 on success, -1 on timeout
|
||||
*/
|
||||
int fano(
|
||||
unsigned int *metric, // Final path metric (returned value)
|
||||
unsigned int *cycles, // Cycle count (returned value)
|
||||
unsigned int *maxnp, // Progress before timeout (returned value)
|
||||
unsigned char *data, // Decoded output data
|
||||
unsigned char *symbols, // Raw deinterleaved input symbols
|
||||
unsigned int nbits, // Number of output bits
|
||||
int mettab[2][256], // Metric table, [sent sym][rx symbol]
|
||||
int delta, // Threshold adjust parameter
|
||||
unsigned int maxcycles) { // Decoding timeout in cycles per bit
|
||||
struct node *nodes; // First node
|
||||
struct node *np; // Current node
|
||||
struct node *lastnode; // Last node
|
||||
struct node *tail; // First node of tail
|
||||
int t; // Threshold
|
||||
int fano( unsigned int *metric, // Final path metric (returned value)
|
||||
unsigned int *cycles, // Cycle count (returned value)
|
||||
unsigned int *maxnp, // Progress before timeout (returned value)
|
||||
unsigned char *data, // Decoded output data
|
||||
unsigned char *symbols, // Raw deinterleaved input symbols
|
||||
unsigned int nbits, // Number of output bits
|
||||
int mettab[2][256], // Metric table, [sent sym][rx symbol]
|
||||
int delta, // Threshold adjust parameter
|
||||
unsigned int maxcycles) { // Decoding timeout in cycles per bit
|
||||
|
||||
struct node *nodes; // First node
|
||||
struct node *np; // Current node
|
||||
struct node *lastnode; // Last node
|
||||
struct node *tail; // First node of tail
|
||||
int t; // Threshold
|
||||
int m0,m1;
|
||||
int ngamma;
|
||||
unsigned int lsym;
|
||||
|
@ -124,7 +124,7 @@ int fano(
|
|||
np = nodes;
|
||||
np->encstate = 0;
|
||||
|
||||
// Compute and sort branch metrics from root node */
|
||||
// Compute and sort branch metrics from root node */
|
||||
ENCODE(lsym,np->encstate); // 0-branch (LSB is 0)
|
||||
m0 = np->metrics[lsym];
|
||||
|
||||
|
@ -137,28 +137,25 @@ int fano(
|
|||
|
||||
m1 = np->metrics[3^lsym];
|
||||
if(m0 > m1) {
|
||||
np->tm[0] = m0; // 0-branch has better metric
|
||||
np->tm[0] = m0; // 0-branch has better metric
|
||||
np->tm[1] = m1;
|
||||
} else {
|
||||
np->tm[0] = m1; // 1-branch is better
|
||||
np->tm[0] = m1; // 1-branch is better
|
||||
np->tm[1] = m0;
|
||||
np->encstate++; // Set low bit
|
||||
np->encstate++; // Set low bit
|
||||
}
|
||||
np->i = 0; // Start with best branch
|
||||
np->i = 0; // Start with best branch
|
||||
maxcycles *= nbits;
|
||||
np->gamma = t = 0;
|
||||
|
||||
// Start the Fano decoder
|
||||
for(i=1; i <= maxcycles; i++) {
|
||||
if((int)(np-nodes) > (int)*maxnp) *maxnp=(int)(np-nodes);
|
||||
#ifdef debug
|
||||
printf("k=%ld, g=%ld, t=%d, m[%d]=%d, maxnp=%d, encstate=%lx\n",
|
||||
np-nodes,np->gamma,t,np->i,np->tm[np->i],*maxnp,np->encstate);
|
||||
#endif
|
||||
// Look forward */
|
||||
|
||||
// Look forward */
|
||||
ngamma = np->gamma + np->tm[np->i];
|
||||
if(ngamma >= t) {
|
||||
if(np->gamma < t + delta) { // Node is acceptable
|
||||
if(np->gamma < t + delta) { // Node is acceptable
|
||||
/* First time we've visited this node;
|
||||
* Tighten threshold.
|
||||
*
|
||||
|
@ -168,10 +165,11 @@ int fano(
|
|||
*/
|
||||
while(ngamma >= t + delta) t += delta;
|
||||
}
|
||||
np[1].gamma = ngamma; // Move forward
|
||||
// Move forward
|
||||
np[1].gamma = ngamma;
|
||||
np[1].encstate = np->encstate << 1;
|
||||
if( ++np == (lastnode+1) ) {
|
||||
break; // Done!
|
||||
break; // Done!
|
||||
}
|
||||
|
||||
/* Compute and sort metrics, starting with the
|
||||
|
@ -187,19 +185,22 @@ int fano(
|
|||
m0 = np->metrics[lsym];
|
||||
m1 = np->metrics[3^lsym];
|
||||
if(m0 > m1) {
|
||||
np->tm[0] = m0; // 0-branch is better
|
||||
np->tm[0] = m0; // 0-branch is better
|
||||
np->tm[1] = m1;
|
||||
} else {
|
||||
np->tm[0] = m1; // 1-branch is better
|
||||
np->tm[0] = m1; // 1-branch is better
|
||||
np->tm[1] = m0;
|
||||
np->encstate++; // Set low bit
|
||||
np->encstate++; // Set low bit
|
||||
}
|
||||
}
|
||||
np->i = 0; // Start with best branch
|
||||
np->i = 0;
|
||||
// Start with best branch
|
||||
continue;
|
||||
}
|
||||
|
||||
// Threshold violated, can't go forward
|
||||
for(;;) { // Look backward
|
||||
for(;;) {
|
||||
// Look backward
|
||||
if(np == nodes || np[-1].gamma < t) {
|
||||
/* Can't back up either.
|
||||
* Relax threshold and and look
|
||||
|
@ -212,19 +213,21 @@ int fano(
|
|||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Back up
|
||||
if(--np < tail && np->i != 1) {
|
||||
np->i++; // Search next best branch
|
||||
np->i++; // Search next best branch
|
||||
np->encstate ^= 1;
|
||||
break;
|
||||
} // else keep looking back
|
||||
} // else keep looking back
|
||||
}
|
||||
}
|
||||
*metric = np->gamma; // Return the final path metric
|
||||
*metric = np->gamma; // Return the final path metric
|
||||
|
||||
// Copy decoded data to user's buffer
|
||||
nbits >>= 3;
|
||||
np = &nodes[7];
|
||||
|
||||
while(nbits-- != 0) {
|
||||
*data++ = np->encstate;
|
||||
np += 8;
|
||||
|
@ -232,6 +235,8 @@ int fano(
|
|||
*cycles = i+1;
|
||||
|
||||
free(nodes);
|
||||
if(i >= maxcycles) return -1; // Decoder timed out
|
||||
return 0; // Successful completion
|
||||
if(i >= maxcycles)
|
||||
return -1; // Decoder timed out
|
||||
|
||||
return 0; // Successful completion
|
||||
}
|
||||
|
|
5
fano.h
5
fano.h
|
@ -9,8 +9,7 @@
|
|||
Minor modifications by Joe Taylor, K1JT
|
||||
*/
|
||||
|
||||
#ifndef FANO_H
|
||||
#define FANO_H
|
||||
#pragma once
|
||||
|
||||
int fano(unsigned int *metric, unsigned int *cycles, unsigned int *maxnp,
|
||||
unsigned char *data,unsigned char *symbols, unsigned int nbits,
|
||||
|
@ -35,5 +34,3 @@ _tmp = (encstate) & POLY2;\
|
|||
_tmp ^= _tmp >> 16;\
|
||||
(sym) |= Partab[(_tmp ^ (_tmp >> 8)) & 0xff];\
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -396,6 +396,7 @@ void initrx_options() {
|
|||
rx_options.shift = 0;
|
||||
rx_options.directsampling = 0;
|
||||
rx_options.maxloop = 0;
|
||||
rx_options.device = 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -412,7 +413,6 @@ void usage(void) {
|
|||
"\t-f dial frequency [(,k,M) Hz], check http://wsprnet.org/ for freq.\n"
|
||||
"\t-c your callsign (12 chars max)\n"
|
||||
"\t-l your locator grid (6 chars max)\n"
|
||||
"\t-n max iterations (default: 0 = infinite loop)\n"
|
||||
"Receiver extra options:\n"
|
||||
"\t-g gain [0-49] (default: 29)\n"
|
||||
"\t-a auto gain (default: off)\n"
|
||||
|
@ -420,6 +420,8 @@ void usage(void) {
|
|||
"\t-p crystal correction factor (ppm) (default: 0)\n"
|
||||
"\t-u upconverter (default: 0, example: 125M)\n"
|
||||
"\t-d direct dampling [0,1,2] (default: 0, 1 for I input, 2 for Q input)\n"
|
||||
"\t-n max iterations (default: 0 = infinite loop)\n"
|
||||
"\t-i device index (in case of multiple receivers, default: 0)\n"
|
||||
"Decoder extra options:\n"
|
||||
"\t-H use the hash table (could caught signal 11 on RPi)\n"
|
||||
"\t-Q quick mode, doesn't dig deep for weak signals\n"
|
||||
|
@ -434,7 +436,6 @@ int main(int argc, char** argv) {
|
|||
uint32_t opt;
|
||||
|
||||
int32_t rtl_result;
|
||||
uint32_t rtl_index = 0; // By default, use the first RTLSDR
|
||||
int32_t rtl_count;
|
||||
char rtl_vendor[256], rtl_product[256], rtl_serial[256];
|
||||
|
||||
|
@ -454,7 +455,7 @@ int main(int argc, char** argv) {
|
|||
if (argc <= 1)
|
||||
usage();
|
||||
|
||||
while ((opt = getopt(argc, argv, "f:c:l:n:g:a:o:p:u:d:H:Q:S")) != -1) {
|
||||
while ((opt = getopt(argc, argv, "f:c:l:g:a:o:p:u:d:n:i:H:Q:S")) != -1) {
|
||||
switch (opt) {
|
||||
case 'f': // Frequency
|
||||
rx_options.dialfreq = (uint32_t)atofs(optarg);
|
||||
|
@ -465,9 +466,6 @@ int main(int argc, char** argv) {
|
|||
case 'l': // Locator / Grid
|
||||
sprintf(dec_options.rloc, "%.6s", optarg);
|
||||
break;
|
||||
case 'n': // Stop after n iterations
|
||||
rx_options.maxloop = (uint32_t)atofs(optarg);
|
||||
break;
|
||||
case 'g': // Small signal amplifier gain
|
||||
rx_options.gain = atoi(optarg);
|
||||
if (rx_options.gain < 0) rx_options.gain = 0;
|
||||
|
@ -491,6 +489,12 @@ int main(int argc, char** argv) {
|
|||
case 'd': // Direct Sampling
|
||||
rx_options.directsampling = (uint32_t)atofs(optarg);
|
||||
break;
|
||||
case 'n': // Stop after n iterations
|
||||
rx_options.maxloop = (uint32_t)atofs(optarg);
|
||||
break;
|
||||
case 'i': // Select the device to use
|
||||
rx_options.device = (uint32_t)atofs(optarg);
|
||||
break;
|
||||
case 'H': // Decoder option, use a hastable
|
||||
dec_options.usehashtable = 1;
|
||||
break;
|
||||
|
@ -552,12 +556,12 @@ int main(int argc, char** argv) {
|
|||
rtlsdr_get_device_usb_strings(i, rtl_vendor, rtl_product, rtl_serial);
|
||||
fprintf(stderr, " %d: %s, %s, SN: %s\n", i, rtl_vendor, rtl_product, rtl_serial);
|
||||
}
|
||||
fprintf(stderr, "\nUsing device %d: %s\n", rtl_index, rtlsdr_get_device_name(rtl_index));
|
||||
fprintf(stderr, "\nUsing device %d: %s\n", rx_options.device, rtlsdr_get_device_name(rx_options.device));
|
||||
|
||||
|
||||
rtl_result = rtlsdr_open(&rtl_device, rtl_index);
|
||||
rtl_result = rtlsdr_open(&rtl_device, rx_options.device);
|
||||
if (rtl_result < 0) {
|
||||
fprintf(stderr, "ERROR: Failed to open rtlsdr device #%d.\n", rtl_index);
|
||||
fprintf(stderr, "ERROR: Failed to open rtlsdr device #%d.\n", rx_options.device);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
|
|
|
@ -64,6 +64,7 @@ struct receiver_options {
|
|||
int32_t upconverter;
|
||||
int32_t directsampling;
|
||||
int32_t maxloop;
|
||||
int32_t device;
|
||||
char date[7];
|
||||
char uttime[5];
|
||||
};
|
||||
|
|
Ładowanie…
Reference in New Issue