diff options
| author | Vasile Vilvoiu <vasi@vilvoiu.ro> | 2023-05-06 20:40:52 +0300 |
|---|---|---|
| committer | Vasile Vilvoiu <vasi@vilvoiu.ro> | 2023-05-06 20:40:52 +0300 |
| commit | f2f4792f824cd64e679cdc859fb008769541257b (patch) | |
| tree | d2ee924bd8945dbf4112afa365aaa822dfea34bc | |
| parent | 2ebb152342283a2237bc7ca2dd96baf3cac0d56e (diff) | |
Add support for waiting for input.
Introduce -S/--sleep_for_input command line argument.
Closes #17.
| -rw-r--r-- | man/specgram.1 | 11 | ||||
| -rw-r--r-- | man/specgram.1.html | 16 | ||||
| -rw-r--r-- | man/specgram.1.pdf | bin | 37623 -> 37897 bytes | |||
| -rw-r--r-- | src/configuration.cpp | 11 | ||||
| -rw-r--r-- | src/configuration.hpp | 2 | ||||
| -rw-r--r-- | src/specgram.cpp | 6 |
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>−d, --datatype</b>=<i>DATA_TYPE</i>] [<b>−p, --prescale</b>=<i>PRESCALE_FACTOR</i>] [<b>−b, ---block_size</b>=<i>BLOCK_SIZE</i>] [<b>−f, +--block_size</b>=<i>BLOCK_SIZE</i>] [<b>−S, +--sleep_for_input</b>=<i>SLEEP_MS</i>] [<b>−f, --fft_width</b>=<i>FFT_WIDTH</i>] [<b>−g, --fft_stride</b>=<i>FFT_STRIDE</i>] [<b>−n, --window_function</b>=<i>WIN_FUNC</i>] [<b>−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>−S</b>, +<b>−−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> −f</b>, <b>−−fft_width</b>=<i>FFT_WIDTH</i></p> diff --git a/man/specgram.1.pdf b/man/specgram.1.pdf Binary files differindex d6a0be4..1d9bae6 100644 --- a/man/specgram.1.pdf +++ b/man/specgram.1.pdf 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; } |
