summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVasile Vilvoiu <vasi@vilvoiu.ro>2023-05-06 20:40:52 +0300
committerVasile Vilvoiu <vasi@vilvoiu.ro>2023-05-06 20:40:52 +0300
commitf2f4792f824cd64e679cdc859fb008769541257b (patch)
treed2ee924bd8945dbf4112afa365aaa822dfea34bc
parent2ebb152342283a2237bc7ca2dd96baf3cac0d56e (diff)
Add support for waiting for input.
Introduce -S/--sleep_for_input command line argument. Closes #17.
-rw-r--r--man/specgram.111
-rw-r--r--man/specgram.1.html16
-rw-r--r--man/specgram.1.pdfbin37623 -> 37897 bytes
-rw-r--r--src/configuration.cpp11
-rw-r--r--src/configuration.hpp2
-rw-r--r--src/specgram.cpp6
6 files changed, 43 insertions, 3 deletions
diff --git a/man/specgram.1 b/man/specgram.1
index 0cbf166..4d679d8 100644
--- a/man/specgram.1
+++ b/man/specgram.1
@@ -1,4 +1,4 @@
-.TH SPECGRAM 1 "2021-10-20"
+.TH SPECGRAM 1 "2023-05-06"
.SH NAME
specgram \- create spectrograms from raw files or standard input
@@ -14,6 +14,7 @@ specgram \- create spectrograms from raw files or standard input
[\fB\-d, --datatype\fR=\fIDATA_TYPE\fR]
[\fB\-p, --prescale\fR=\fIPRESCALE_FACTOR\fR]
[\fB\-b, --block_size\fR=\fIBLOCK_SIZE\fR]
+[\fB\-S, --sleep_for_input\fR=\fISLEEP_MS\fR]
[\fB\-f, --fft_width\fR=\fIFFT_WIDTH\fR]
[\fB\-g, --fft_stride\fR=\fIFFT_STRIDE\fR]
[\fB\-n, --window_function\fR=\fIWIN_FUNC\fR]
@@ -121,6 +122,14 @@ The larger this value, the larger the latency of the live spectrogram.
Default is 256.
.TP
+.BR \-S ", " \-\-sleep_for_input =\fISLEEP_MS\fR
+Duration in milliseconds to sleep for when input is not available.
+Set this to a reasonable value when input is sparse.
+Leave unset when input is constant and low latency is desired.
+
+Default is 0 (i.e. program busywaits).
+
+.TP
\fBFFT OPTIONS\fR
.TP
diff --git a/man/specgram.1.html b/man/specgram.1.html
index 367fa10..5ac4677 100644
--- a/man/specgram.1.html
+++ b/man/specgram.1.html
@@ -1,5 +1,5 @@
<!-- Creator : groff version 1.22.4 -->
-<!-- CreationDate: Wed Oct 20 18:28:19 2021 -->
+<!-- CreationDate: Sat May 6 17:36:19 2023 -->
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
@@ -55,7 +55,8 @@ input</p>
--rate</b>=<i>RATE</i>] [<b>&minus;d,
--datatype</b>=<i>DATA_TYPE</i>] [<b>&minus;p,
--prescale</b>=<i>PRESCALE_FACTOR</i>] [<b>&minus;b,
---block_size</b>=<i>BLOCK_SIZE</i>] [<b>&minus;f,
+--block_size</b>=<i>BLOCK_SIZE</i>] [<b>&minus;S,
+--sleep_for_input</b>=<i>SLEEP_MS</i>] [<b>&minus;f,
--fft_width</b>=<i>FFT_WIDTH</i>] [<b>&minus;g,
--fft_stride</b>=<i>FFT_STRIDE</i>] [<b>&minus;n,
--window_function</b>=<i>WIN_FUNC</i>] [<b>&minus;m,
@@ -227,6 +228,17 @@ spectrogram.</p>
<p style="margin-left:22%; margin-top: 1em">Default is
256.</p>
+<p style="margin-left:11%;"><b>&minus;S</b>,
+<b>&minus;&minus;sleep_for_input</b>=<i>SLEEP_MS</i></p>
+
+<p style="margin-left:22%;">Duration in milliseconds to
+sleep for when input is not available. Set this to a
+reasonable value when input is sparse. Leave unset when
+input is constant and low latency is desired.</p>
+
+<p style="margin-left:22%; margin-top: 1em">Default is 0
+(i.e. program busywaits).</p>
+
<p style="margin-left:11%;"><b>FFT OPTIONS <br>
&minus;f</b>,
<b>&minus;&minus;fft_width</b>=<i>FFT_WIDTH</i></p>
diff --git a/man/specgram.1.pdf b/man/specgram.1.pdf
index d6a0be4..1d9bae6 100644
--- a/man/specgram.1.pdf
+++ b/man/specgram.1.pdf
Binary files differ
diff --git a/src/configuration.cpp b/src/configuration.cpp
index 7fdcdb5..88f3355 100644
--- a/src/configuration.cpp
+++ b/src/configuration.cpp
@@ -26,6 +26,7 @@ Configuration::Configuration()
this->datatype_ = DataType::kSignedInt16;
this->has_complex_input_ = false;
this->prescale_factor_ = 1.0f;
+ this->sleep_for_input_ = 0;
this->fft_width_ = 1024;
this->fft_stride_ = 1024;
@@ -169,6 +170,8 @@ Configuration::Build(int argc, const char **argv)
prescale(input_opts, "float", "Prescaling factor (default: 1.0)", {'p', "prescale"});
args::ValueFlag<int>
block_size(input_opts, "integer", "Block size when reading input, in data types (default: 256)", {'b', "block_size"});
+ args::ValueFlag<int>
+ sleep_for_input(input_opts, "integer", "Duration in milliseconds to sleep for when input is not available (default: 0, busywaits)", {'S', "sleep_for_input"});
args::Group fft_opts(parser, "FFT options:", args::Group::Validators::DontCare);
args::ValueFlag<int>
@@ -269,6 +272,14 @@ Configuration::Build(int argc, const char **argv)
conf.block_size_ = args::get(block_size);
}
}
+ if (sleep_for_input) {
+ if (args::get(sleep_for_input) < 0) {
+ std::cerr << "'sleep_for_input' must be zero or positive." << std::endl;
+ return std::make_tuple(conf, 1, true);
+ } else {
+ conf.sleep_for_input_ = args::get(sleep_for_input);
+ }
+ }
if (rate) {
if (args::get(rate) <= 0) {
std::cerr << "'rate' must be positive." << std::endl;
diff --git a/src/configuration.hpp b/src/configuration.hpp
index dec0e0c..42776ad 100644
--- a/src/configuration.hpp
+++ b/src/configuration.hpp
@@ -32,6 +32,7 @@ private:
DataType datatype_; /* input data type (does not cover complex/real discrimination) */
bool has_complex_input_; /* true if input is complex */
double prescale_factor_; /* value to scale input with before applying other transformations */
+ std::size_t sleep_for_input_; /* number of milliseconds to sleep when input is not ready */
std::size_t fft_width_; /* size of FFT window, in values */
std::size_t fft_stride_; /* stride of FFT window, in values */
@@ -110,6 +111,7 @@ public:
auto GetDataType() const { return datatype_; }
auto HasComplexInput() const { return has_complex_input_; }
auto GetPrescaleFactor() const { return prescale_factor_; }
+ auto GetSleepForInput() const { return sleep_for_input_; }
/* FFT getters */
auto GetFFTWidth() const { return fft_width_; }
diff --git a/src/specgram.cpp b/src/specgram.cpp
index 0cd9635..5e5e30c 100644
--- a/src/specgram.cpp
+++ b/src/specgram.cpp
@@ -21,6 +21,8 @@
#include <random>
#include <cstdio>
#include <cassert>
+#include <thread>
+#include <chrono>
/* main loop exit condition */
volatile bool main_loop_running = true;
@@ -237,6 +239,10 @@ main(int argc, char** argv)
auto block = reader->GetBlock();
if (!block) {
/* block not finished yet */
+ if (auto sleep = conf.GetSleepForInput()) {
+ /* sleep for a bit so we don't busywait on sparse input */
+ std::this_thread::sleep_for(std::chrono::duration<size_t, std::milli>(sleep));
+ }
continue;
}