device index selector

pull/17/head
Guenael 2017-06-23 00:32:08 -04:00
rodzic 6634451e4a
commit f76dd404ec
4 zmienionych plików z 58 dodań i 51 usunięć

81
fano.c
Wyświetl plik

@ -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
Wyświetl plik

@ -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

Wyświetl plik

@ -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;
}

Wyświetl plik

@ -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];
};