diff --git a/include/hsdaoh.h b/include/hsdaoh.h index 49a5038..71244a4 100644 --- a/include/hsdaoh.h +++ b/include/hsdaoh.h @@ -84,7 +84,7 @@ HSDAOH_API int hsdaoh_get_device_usb_strings(uint32_t index, */ HSDAOH_API int hsdaoh_get_index_by_serial(const char *serial); -HSDAOH_API int hsdaoh_open(hsdaoh_dev_t **dev, uint32_t index); +HSDAOH_API int hsdaoh_open(hsdaoh_dev_t **dev, uint32_t index, bool out_signed); HSDAOH_API int hsdaoh_close(hsdaoh_dev_t *dev); diff --git a/include/hsdaoh_private.h b/include/hsdaoh_private.h index cbdccf1..8017f77 100644 --- a/include/hsdaoh_private.h +++ b/include/hsdaoh_private.h @@ -44,6 +44,7 @@ struct hsdaoh_dev { unsigned int width, height, fps; bool output_float; + bool output_signed; iqconverter_float_t *cnv_f; /* status */ diff --git a/src/format_convert.c b/src/format_convert.c index 623f29b..4ab578b 100644 --- a/src/format_convert.c +++ b/src/format_convert.c @@ -69,10 +69,15 @@ void hsdaoh_unpack_pio_12bit(hsdaoh_dev_t *dev, hsdaoh_data_info_t *data_info) unsigned int j = 0; for (unsigned int i = 0; i < inlen; i += 3) { - out[j++] = (in[i+2] & 0xf000) >> 4 | (in[i+1] & 0xf000) >> 8 | (in[i] >> 12); - out[j++] = in[i ] & 0x0fff; - out[j++] = in[i+1] & 0x0fff; - out[j++] = in[i+2] & 0x0fff; + uint16_t sample1 = (in[i+2] & 0xf000) >> 4 | (in[i+1] & 0xf000) >> 8 | (in[i] >> 12); + uint16_t sample2 = in[i ] & 0x0fff; + uint16_t sample3 = in[i+1] & 0x0fff; + uint16_t sample4 = in[i+2] & 0x0fff; + + out[j++] = dev->output_signed ? (int16_t)((sample1 - 2048) << 4) : sample1; + out[j++] = dev->output_signed ? (int16_t)((sample2 - 2048) << 4) : sample2; + out[j++] = dev->output_signed ? (int16_t)((sample3 - 2048) << 4) : sample3; + out[j++] = dev->output_signed ? (int16_t)((sample4 - 2048) << 4) : sample4; } if (dev->output_float) { @@ -107,8 +112,11 @@ void hsdaoh_unpack_pio_12bit_dual(hsdaoh_dev_t *dev, hsdaoh_data_info_t *data_in } for (i = 0; i < j; i++) { - out16_1[i] = (out[i] >> 12) & 0x0fff; - out16_2[i] = out[i] & 0x0fff; + uint16_t sample1 = (out[i] >> 12) & 0x0fff; + uint16_t sample2 = out[i] & 0x0fff; + + out16_1[i] = dev->output_signed ? (int16_t)((sample1 - 2048) << 4) : sample1; + out16_2[i] = dev->output_signed ? (int16_t)((sample2 - 2048) << 4) : sample2; } if (dev->output_float) { @@ -238,10 +246,16 @@ void hsdaoh_unpack_fpga_12bit_dual(hsdaoh_dev_t *dev, hsdaoh_data_info_t *data_i /* extract packed 2x12 bit samples */ for (int i = 0; i < inlen; i += 3) { uint16_t lsbs = in[i+2]; - out16_1[j] = ((in[i+0] & 0xff00) >> 4) | ((lsbs >> 0) & 0xf); - out16_2[j++] = ((in[i+0] & 0x00ff) << 4) | ((lsbs >> 4) & 0xf); - out16_1[j] = ((in[i+1] & 0xff00) >> 4) | ((lsbs >> 8) & 0xf); - out16_2[j++] = ((in[i+1] & 0x00ff) << 4) | ((lsbs >> 12) & 0xf); + + uint16_t sample1 = ((in[i+0] & 0xff00) >> 4) | ((lsbs >> 0) & 0xf); + uint16_t sample2 = ((in[i+0] & 0x00ff) << 4) | ((lsbs >> 4) & 0xf); + uint16_t sample3 = ((in[i+1] & 0xff00) >> 4) | ((lsbs >> 8) & 0xf); + uint16_t sample4 = ((in[i+1] & 0x00ff) << 4) | ((lsbs >> 12) & 0xf); + + out16_1[j] = dev->output_signed ? (int16_t)((sample1 - 2048) << 4) : sample1; + out16_2[j++] = dev->output_signed ? (int16_t)((sample2 - 2048) << 4) : sample2; + out16_1[j] = dev->output_signed ? (int16_t)((sample3 - 2048) << 4) : sample3; + out16_2[j++] = dev->output_signed ? (int16_t)((sample4 - 2048) << 4) : sample4; } if (dev->output_float) { diff --git a/src/hsdaoh_file.c b/src/hsdaoh_file.c index 8519731..8be3e6a 100644 --- a/src/hsdaoh_file.c +++ b/src/hsdaoh_file.c @@ -53,6 +53,7 @@ void usage(void) "Usage:\n" "\t[-d device_index (default: 0)]\n" "\t[-b maximum number of buffers (default: 16)]\n" + "\t[-s save 16-bit streams as signed integer]\n" "\t[-0 to -3 filename of steam 0 to stream 3 (a '-' dumps samples to stdout)]\n" "\tfilename (of stream 0) (a '-' dumps samples to stdout)\n\n"); exit(1); @@ -121,8 +122,9 @@ int main(int argc, char **argv) unsigned int num_bufs = 0; bool fname0_used = false; bool have_file = false; + bool set_signed = false; - while ((opt = getopt(argc, argv, "0:1:2:3:d:b:")) != -1) { + while ((opt = getopt(argc, argv, "0:1:2:3:d:b:s:")) != -1) { switch (opt) { case 'd': dev_index = (uint32_t)atoi(optarg); @@ -130,6 +132,9 @@ int main(int argc, char **argv) case 'b': num_bufs = (unsigned int)atoi(optarg); break; + case 's': + set_signed = true; + break; case '0': fname0_used = true; have_file = true; @@ -165,7 +170,7 @@ int main(int argc, char **argv) if (dev_index < 0) exit(1); - r = hsdaoh_open(&dev, (uint32_t)dev_index); + r = hsdaoh_open(&dev, (uint32_t)dev_index, set_signed); if (r < 0) { fprintf(stderr, "Failed to open hsdaoh device #%d.\n", dev_index); exit(1); diff --git a/src/hsdaoh_tcp.c b/src/hsdaoh_tcp.c index 9f6dfdc..c38b21a 100644 --- a/src/hsdaoh_tcp.c +++ b/src/hsdaoh_tcp.c @@ -325,6 +325,7 @@ int main(int argc, char **argv) fd_set readfds; u_long blockmode = 1; dongle_info_t dongle_info; + int set_signed = 0; #ifdef _WIN32 WSADATA wsd; @@ -333,7 +334,7 @@ int main(int argc, char **argv) struct sigaction sigact, sigign; #endif - while ((opt = getopt(argc, argv, "a:p:b:n:d")) != -1) { + while ((opt = getopt(argc, argv, "a:p:b:n:d:s")) != -1) { switch (opt) { case 'd': dev_index = (uint32_t)atoi(optarg); @@ -350,6 +351,9 @@ int main(int argc, char **argv) case 'n': llbuf_num = atoi(optarg); break; + case 's': + set_signed = 1; + break; default: usage(); break; @@ -363,7 +367,7 @@ int main(int argc, char **argv) exit(1); } - hsdaoh_open(&dev, (uint32_t)dev_index); + hsdaoh_open(&dev, (uint32_t)dev_index, set_signed); if (NULL == dev) { fprintf(stderr, "Failed to open hsdaoh device #%d.\n", dev_index); exit(1); diff --git a/src/hsdaoh_test.c b/src/hsdaoh_test.c index bdd789f..67a791d 100644 --- a/src/hsdaoh_test.c +++ b/src/hsdaoh_test.c @@ -274,7 +274,7 @@ int main(int argc, char **argv) if (dev_index < 0) exit(1); - r = hsdaoh_open(&dev, (uint32_t)dev_index); + r = hsdaoh_open(&dev, (uint32_t)dev_index, 0); if (r < 0) { fprintf(stderr, "Failed to open hsdaoh device #%d.\n", dev_index); exit(1); diff --git a/src/libhsdaoh.c b/src/libhsdaoh.c index f54b837..42890c9 100644 --- a/src/libhsdaoh.c +++ b/src/libhsdaoh.c @@ -405,7 +405,7 @@ int _hsdaoh_open_uvc_device(hsdaoh_dev_t *dev) return (int)r; } -int hsdaoh_open(hsdaoh_dev_t **out_dev, uint32_t index) +int hsdaoh_open(hsdaoh_dev_t **out_dev, uint32_t index, bool out_signed) { int r; int i; @@ -423,6 +423,10 @@ int hsdaoh_open(hsdaoh_dev_t **out_dev, uint32_t index) memset(dev, 0, sizeof(hsdaoh_dev_t)); + if (out_signed) { + dev->output_signed = 1; + } + r = libusb_init(&dev->ctx); if(r < 0){ free(dev);