diff --git a/conf/rtl_433.example.conf b/conf/rtl_433.example.conf
index 4cfc7596..83306517 100644
--- a/conf/rtl_433.example.conf
+++ b/conf/rtl_433.example.conf
@@ -85,12 +85,32 @@ sample_rate   250k
 # see "decoder" section below.
 
 # as command line option:
-#   [-Y level=<dB level>] Manual detection level used to determine pulses (-1.0 to -30.0) (0=auto)
+#   [-Y auto | classic | minmax] FSK pulse detector mode.
+#pulse_detect auto
+
+# as command line option:
+#   [-Y level=<dB level>] Manual detection level used to determine pulses (-1.0 to -30.0) (0=auto).
 #pulse_detect level=0
 
 # as command line option:
-#   [-Y auto | classic | minmax] FSK pulse detector mode.
-#pulse_detect auto
+#   [-Y minlevel=<dB level>] Manual minimum detection level used to determine pulses (-1.0 to -99.0).
+#pulse_detect minlevel=-12
+
+# as command line option:
+#   [-Y minsnr=<dB level>] Minimum SNR to determine pulses (1.0 to 99.0).
+#pulse_detect minsnr=9
+
+# as command line option:
+#   [-Y autolevel] Set minlevel automatically based on average estimated noise.
+#pulse_detect autolevel
+
+# as command line option:
+#   [-Y squelch] Skip frames below estimated noise level to lower cpu load.
+#pulse_detect squelch
+
+# as command line option:
+#   [-Y ampest | magest] Choose amplitude or magnitude level estimator.
+#pulse_detect magest
 
 # as command line option:
 #   [-n <value>] Specify number of samples to take (each sample is 2 bytes: 1 each of I & Q)
@@ -111,21 +131,25 @@ analyze_pulses false
 #out_block_size
 
 # as command line option:
-#   [-M time[:<options>]|protocol|level|stats|bits] Add various metadata to every output line.
+#   [-M time[:<options>]|protocol|level|noise[:<secs>]|stats|bits] Add various metadata to every output line.
 # Use "time" to add current date and time meta data (preset for live inputs).
 # Use "time:rel" to add sample position meta data (preset for read-file and stdin).
 # Use "time:unix" to show the seconds since unix epoch as time meta data.
 # Use "time:iso" to show the time with ISO-8601 format (YYYY-MM-DD"T"hh:mm:ss).
 # Use "time:off" to remove time meta data.
 # Use "time:usec" to add microseconds to date time meta data.
+# Use "time:tz" to output time with timezone offset.
 # Use "time:utc" to output time in UTC.
 #   (this may also be accomplished by invocation with TZ environment variable set).
 #   "usec" and "utc" can be combined with other options, eg. "time:unix:utc:usec".
 # Use "protocol" / "noprotocol" to output the decoder protocol number meta data.
 # Use "level" to add Modulation, Frequency, RSSI, SNR, and Noise meta data.
+# Use "noise[:secs]" to report estimated noise level at intervals (default: 10 seconds).
 # Use "stats[:[<level>][:<interval>]]" to report statistics (default: 600 seconds).
 #   level 0: no report, 1: report successful devices, 2: report active devices, 3: report all
+# Use "bits" to add bit representation to code outputs (for debug).
 report_meta level
+report_meta noise
 report_meta stats
 report_meta time:usec
 report_meta protocol
@@ -172,6 +196,22 @@ signal_grabber none
 # default is "kv", multiple outputs can be used.
 output json
 
+# as command line option:
+#   [-K FILE | PATH | <tag> | <key>=<tag>] Add an expanded token or fixed tag to every output line.
+# If <tag> is "FILE" or "PATH" an expanded token will be added.
+# The <tag> can also be a GPSd URL, e.g.
+#   -K gpsd,lat,lon" (report lat and lon keys from local gpsd)
+#   -K loc=gpsd,lat,lon" (report lat and lon in loc object)
+#   -K gpsd" (full json TPV report, in default "gps" object)
+#   -K foo=gpsd://127.0.0.1:2947" (with key and address)
+#   -K bar=gpsd,nmea" (NMEA deault GPGGA report)
+#   -K rmc=gpsd,nmea,filter='$GPRMC'" (NMEA GPRMC report)
+# Also <tag> can be a generic tcp address, e.g.
+#   -K foo=tcp:localhost:4000" (read lines as TCP client)
+#   -K bar=tcp://127.0.0.1:3000,init='subscribe tags\\r\\n'"
+#   -K baz=tcp://127.0.0.1:5000,filter='a prefix to match'"
+#output_tag mytag
+
 # as command line option:
 #   [-C] native|si|customary Convert units in decoded output.
 # default is "native"
diff --git a/include/baseband.h b/include/baseband.h
index f19817d0..2a361ec8 100644
--- a/include/baseband.h
+++ b/include/baseband.h
@@ -22,15 +22,16 @@
     @param iq_buf input samples (I/Q samples in interleaved uint8)
     @param[out] y_buf output buffer
     @param len number of samples to process
+    @return the average level in dB
 */
-void envelope_detect(uint8_t const *iq_buf, uint16_t *y_buf, uint32_t len);
+float envelope_detect(uint8_t const *iq_buf, uint16_t *y_buf, uint32_t len);
 
 // for evaluation
-void envelope_detect_nolut(uint8_t const *iq_buf, uint16_t *y_buf, uint32_t len);
-void magnitude_est_cu8(uint8_t const *iq_buf, uint16_t *y_buf, uint32_t len);
-void magnitude_true_cu8(uint8_t const *iq_buf, uint16_t *y_buf, uint32_t len);
-void magnitude_est_cs16(int16_t const *iq_buf, uint16_t *y_buf, uint32_t len);
-void magnitude_true_cs16(int16_t const *iq_buf, uint16_t *y_buf, uint32_t len);
+float envelope_detect_nolut(uint8_t const *iq_buf, uint16_t *y_buf, uint32_t len);
+float magnitude_est_cu8(uint8_t const *iq_buf, uint16_t *y_buf, uint32_t len);
+float magnitude_true_cu8(uint8_t const *iq_buf, uint16_t *y_buf, uint32_t len);
+float magnitude_est_cs16(int16_t const *iq_buf, uint16_t *y_buf, uint32_t len);
+float magnitude_true_cs16(int16_t const *iq_buf, uint16_t *y_buf, uint32_t len);
 
 #define AMP_TO_DB(x) (10.0f * ((x) > 0 ? log10f(x) : 0) - 42.1442f)  // 10*log10f(16384.0f)
 #define MAG_TO_DB(x) (20.0f * ((x) > 0 ? log10f(x) : 0) - 84.2884f)  // 20*log10f(16384.0f)
diff --git a/include/optparse.h b/include/optparse.h
index d0b0e144..aab69f2f 100644
--- a/include/optparse.h
+++ b/include/optparse.h
@@ -106,7 +106,7 @@ uint32_t atouint32_metric(char const *str, char const *error_hint);
 ///
 /// @param str character string to parse
 /// @param error_hint prepended to error output
-/// @return parsed number value
+/// @return parsed number value in seconds
 int atoi_time(char const *str, char const *error_hint);
 
 /// Similar to strsep.
diff --git a/include/r_private.h b/include/r_private.h
index 8d23499f..ac834c70 100644
--- a/include/r_private.h
+++ b/include/r_private.h
@@ -17,7 +17,11 @@
 #include "compat_time.h"
 
 struct dm_state {
+    float auto_level;
+    float squelch_offset;
     float level_limit;
+    float noise_level;
+    float min_level_auto;
     float min_level;
     float min_snr;
     float low_pass;
diff --git a/include/rtl_433.h b/include/rtl_433.h
index e69b333f..d8aeb229 100644
--- a/include/rtl_433.h
+++ b/include/rtl_433.h
@@ -77,6 +77,7 @@ typedef struct r_cfg {
     int verbose_bits;
     conversion_mode_t conversion_mode;
     int report_meta;
+    int report_noise;
     int report_protocol;
     time_mode_t report_time;
     int report_time_hires;
diff --git a/src/baseband.c b/src/baseband.c
index 9d6327ef..0ec466af 100644
--- a/src/baseband.c
+++ b/src/baseband.c
@@ -32,32 +32,39 @@ static void calc_squares()
 
 // This will give a noisy envelope of OOK/ASK signals.
 // Subtract the bias (-128) and get an envelope estimation.
-void envelope_detect(uint8_t const *iq_buf, uint16_t *y_buf, uint32_t len)
+float envelope_detect(uint8_t const *iq_buf, uint16_t *y_buf, uint32_t len)
 {
     unsigned long i;
+    uint32_t sum = 0;
     for (i = 0; i < len; i++) {
         y_buf[i] = scaled_squares[iq_buf[2 * i ]] + scaled_squares[iq_buf[2 * i + 1]];
+        sum += y_buf[i];
     }
+    return len > 0 && sum >= len ? AMP_TO_DB((float)sum / len) : AMP_TO_DB(1);
 }
 
 /// This will give a noisy envelope of OOK/ASK signals.
 /// Subtracts the bias (-128) and calculates the norm (scaled by 16384).
 /// Using a LUT is slower for O1 and above.
-void envelope_detect_nolut(uint8_t const *iq_buf, uint16_t *y_buf, uint32_t len)
+float envelope_detect_nolut(uint8_t const *iq_buf, uint16_t *y_buf, uint32_t len)
 {
     unsigned long i;
+    uint32_t sum = 0;
     for (i = 0; i < len; i++) {
         int16_t x = 127 - iq_buf[2 * i];
         int16_t y = 127 - iq_buf[2 * i + 1];
         y_buf[i]  = x * x + y * y; // max 32768, fs 16384
+        sum += y_buf[i];
     }
+    return len > 0 && sum >= len ? AMP_TO_DB((float)sum / len) : AMP_TO_DB(1);
 }
 
 /// 122/128, 51/128 Magnitude Estimator for CU8 (SIMD has min/max).
 /// Note that magnitude emphasizes quiet signals / deemphasizes loud signals.
-void magnitude_est_cu8(uint8_t const *iq_buf, uint16_t *y_buf, uint32_t len)
+float magnitude_est_cu8(uint8_t const *iq_buf, uint16_t *y_buf, uint32_t len)
 {
     unsigned long i;
+    uint32_t sum = 0;
     for (i = 0; i < len; i++) {
         uint16_t x = abs(iq_buf[2 * i] - 128);
         uint16_t y = abs(iq_buf[2 * i + 1] - 128);
@@ -65,24 +72,30 @@ void magnitude_est_cu8(uint8_t const *iq_buf, uint16_t *y_buf, uint32_t len)
         uint16_t mx = x > y ? x : y;
         uint16_t mag_est = 122 * mx + 51 * mi;
         y_buf[i] = mag_est; // max 22144, fs 16384
+        sum += y_buf[i];
     }
+    return len > 0 && sum >= len ? MAG_TO_DB((float)sum / len) : MAG_TO_DB(1);
 }
 
 /// True Magnitude for CU8 (sqrt can SIMD but float is slow).
-void magnitude_true_cu8(uint8_t const *iq_buf, uint16_t *y_buf, uint32_t len)
+float magnitude_true_cu8(uint8_t const *iq_buf, uint16_t *y_buf, uint32_t len)
 {
     unsigned long i;
+    uint32_t sum = 0;
     for (i = 0; i < len; i++) {
         int16_t x = iq_buf[2 * i] - 128;
         int16_t y = iq_buf[2 * i + 1] - 128;
         y_buf[i]  = (uint16_t)(sqrt(x * x + y * y) * 128.0); // max 181, scaled 23170, fs 16384
+        sum += y_buf[i];
     }
+    return len > 0 && sum >= len ? MAG_TO_DB((float)sum / len) : MAG_TO_DB(1);
 }
 
 /// 122/128, 51/128 Magnitude Estimator for CS16 (SIMD has min/max).
-void magnitude_est_cs16(int16_t const *iq_buf, uint16_t *y_buf, uint32_t len)
+float magnitude_est_cs16(int16_t const *iq_buf, uint16_t *y_buf, uint32_t len)
 {
     unsigned long i;
+    uint32_t sum = 0;
     for (i = 0; i < len; i++) {
         uint32_t x = abs(iq_buf[2 * i]);
         uint32_t y = abs(iq_buf[2 * i + 1]);
@@ -90,18 +103,23 @@ void magnitude_est_cs16(int16_t const *iq_buf, uint16_t *y_buf, uint32_t len)
         uint32_t mx = x > y ? x : y;
         uint32_t mag_est = 122 * mx + 51 * mi;
         y_buf[i] = mag_est >> 8; // max 5668864, scaled 22144, fs 16384
+        sum += y_buf[i];
     }
+    return len > 0 && sum >= len ? MAG_TO_DB((float)sum / len) : MAG_TO_DB(1);
 }
 
 /// True Magnitude for CS16 (sqrt can SIMD but float is slow).
-void magnitude_true_cs16(int16_t const *iq_buf, uint16_t *y_buf, uint32_t len)
+float magnitude_true_cs16(int16_t const *iq_buf, uint16_t *y_buf, uint32_t len)
 {
     unsigned long i;
+    uint32_t sum = 0;
     for (i = 0; i < len; i++) {
         int32_t x = iq_buf[2 * i];
         int32_t y = iq_buf[2 * i + 1];
         y_buf[i]  = (int)sqrt(x * x + y * y) >> 1; // max 46341, scaled 23170, fs 16384
+        sum += y_buf[i];
     }
+    return len > 0 && sum >= len ? MAG_TO_DB((float)sum / len) : MAG_TO_DB(1);
 }
 
 
diff --git a/src/rtl_433.c b/src/rtl_433.c
index 00a6ad1e..92c54ae9 100644
--- a/src/rtl_433.c
+++ b/src/rtl_433.c
@@ -116,9 +116,13 @@ static void usage(int exit_code)
             "       Specify a negative number to disable a device decoding protocol (can be used multiple times)\n"
             "  [-G] Enable blacklisted device decoding protocols, for testing only.\n"
             "  [-X <spec> | help] Add a general purpose decoder (prepend -R 0 to disable all decoders)\n"
-            "  [-Y level=<dB level>] Manual detection level used to determine pulses (-1.0 to -30.0) (0=auto)\n"
-            "  [-n <value>] Specify number of samples to take (each sample is 2 bytes: 1 each of I & Q)\n"
             "  [-Y auto | classic | minmax] FSK pulse detector mode.\n"
+            "  [-Y level=<dB level>] Manual detection level used to determine pulses (-1.0 to -30.0) (0=auto).\n"
+            "  [-Y minlevel=<dB level>] Manual minimum detection level used to determine pulses (-1.0 to -99.0).\n"
+            "  [-Y minsnr=<dB level>] Minimum SNR to determine pulses (1.0 to 99.0).\n"
+            "  [-Y autolevel] Set minlevel automatically based on average estimated noise.\n"
+            "  [-Y squelch] Skip frames below estimated noise level to reduce cpu load.\n"
+            "  [-Y ampest | magest] Choose amplitude or magnitude level estimator.\n"
             "\t\t= Analyze/Debug options =\n"
             "  [-a] Analyze mode. Print a textual description of the signal.\n"
             "  [-A] Pulse Analyzer. Enable pulse analysis and decode attempt.\n"
@@ -134,9 +138,10 @@ static void usage(int exit_code)
             "  [-F kv | json | csv | mqtt | influx | syslog | null | help] Produce decoded output in given format.\n"
             "       Append output to file with :<filename> (e.g. -F csv:log.csv), defaults to stdout.\n"
             "       Specify host/port for syslog with e.g. -F syslog:127.0.0.1:1514\n"
-            "  [-M time[:<options>] | protocol | level | stats | bits | help] Add various meta data to each output.\n"
+            "  [-M time[:<options>] | protocol | level | noise[:secs] | stats | bits | help] Add various meta data to each output.\n"
             "  [-K FILE | PATH | <tag> | <key>=<tag>] Add an expanded token or fixed tag to every output line.\n"
             "  [-C native | si | customary] Convert units in decoded output.\n"
+            "  [-n <value>] Specify number of samples to take (each sample is an I/Q pair)\n"
             "  [-T <seconds>] Specify number of seconds to run, also 12:34 or 1h23m45s\n"
             "  [-E hop | quit] Hop/Quit after outputting successful event(s)\n"
             "  [-h] Output this usage help and exit\n"
@@ -253,7 +258,7 @@ static void help_meta(void)
 {
     term_help_printf(
             "\t\t= Meta information option =\n"
-            "  [-M time[:<options>]|protocol|level|stats|bits] Add various metadata to every output line.\n"
+            "  [-M time[:<options>]|protocol|level|noise[:<secs>]|stats|bits] Add various metadata to every output line.\n"
             "\tUse \"time\" to add current date and time meta data (preset for live inputs).\n"
             "\tUse \"time:rel\" to add sample position meta data (preset for read-file and stdin).\n"
             "\tUse \"time:unix\" to show the seconds since unix epoch as time meta data.\n"
@@ -266,6 +271,7 @@ static void help_meta(void)
             "\t\t\"usec\" and \"utc\" can be combined with other options, eg. \"time:unix:utc:usec\".\n"
             "\tUse \"protocol\" / \"noprotocol\" to output the decoder protocol number meta data.\n"
             "\tUse \"level\" to add Modulation, Frequency, RSSI, SNR, and Noise meta data.\n"
+            "\tUse \"noise[:secs]\" to report estimated noise level at intervals (default: 10 seconds).\n"
             "\tUse \"stats[:[<level>][:<interval>]]\" to report statistics (default: 600 seconds).\n"
             "\t  level 0: no report, 1: report successful devices, 2: report active devices, 3: report all\n"
             "\tUse \"bits\" to add bit representation to code outputs (for debug).\n");
@@ -325,6 +331,8 @@ static void sdr_callback(unsigned char *iq_buf, uint32_t len, void *ctx)
         cfg->exit_async = 1;
     }
 
+    // save last frame time to see if a new second started
+    time_t last_frame_sec = demod->now.tv_sec;
     get_time_now(&demod->now);
 
     n_samples = len / demod->sample_size;
@@ -349,18 +357,51 @@ static void sdr_callback(unsigned char *iq_buf, uint32_t len, void *ctx)
     }
 
     // AM demodulation
+    float avg_db;
     if (demod->sample_size == 2) { // CU8
         if (demod->use_mag_est) {
             //magnitude_true_cu8(iq_buf, demod->buf.temp, n_samples);
-            magnitude_est_cu8(iq_buf, demod->buf.temp, n_samples);
+            avg_db = magnitude_est_cu8(iq_buf, demod->buf.temp, n_samples);
         }
         else { // amp est
-            envelope_detect(iq_buf, demod->buf.temp, n_samples);
+            avg_db = envelope_detect(iq_buf, demod->buf.temp, n_samples);
         }
     } else { // CS16
         //magnitude_true_cs16((int16_t *)iq_buf, demod->buf.temp, n_samples);
-        magnitude_est_cs16((int16_t *)iq_buf, demod->buf.temp, n_samples);
+        avg_db = magnitude_est_cs16((int16_t *)iq_buf, demod->buf.temp, n_samples);
     }
+
+    //fprintf(stderr, "noise level: %.1f dB current: %.1f dB min level: %.1f dB\n", demod->noise_level, avg_db, demod->min_level_auto);
+    if (demod->min_level_auto == 0.0f) {
+        demod->min_level_auto = demod->min_level;
+    }
+    if (demod->noise_level == 0.0f) {
+        demod->noise_level = demod->min_level_auto - 3.0f;
+    }
+    int noise_only = avg_db < demod->noise_level + 3.0f; // or demod->min_level_auto?
+    // always process frames if loader, dumper, or analyzers are in use, otherwise skip silent frames
+    int process_frame = demod->squelch_offset <= 0 || !noise_only || demod->load_info.format || demod->analyze_pulses || demod->dumper.len || demod->samp_grab;
+    if (noise_only) {
+        demod->noise_level = (demod->noise_level * 7 + avg_db) / 8; // average over 8 frames
+        // If there is a significant change in noise level
+        if (fabsf(demod->min_level_auto - demod->noise_level - 3.0f) > 1.0f) {
+            // If auto_level is on and the noise level is well below min_level
+            if (demod->auto_level > 0 && demod->noise_level < demod->min_level - 3.0f) {
+                demod->min_level_auto = demod->noise_level + 3.0f;
+                fprintf(stderr, "Estimated noise level is %.1f dB, adjusting minimum detection level to %.1f dB\n", demod->noise_level, demod->min_level_auto);
+                pulse_detect_set_levels(demod->pulse_detect, demod->use_mag_est, demod->level_limit, demod->min_level_auto, demod->min_snr, demod->detect_verbosity);
+            }
+            else {
+                fprintf(stderr, "Estimated noise level is %.1f dB, minimum detection level is %.1f dB\n", demod->noise_level, demod->min_level);
+            }
+        }
+    }
+    // Report noise every report_noise seconds, but only for the first frame that second
+    if (cfg->report_noise && last_frame_sec != demod->now.tv_sec && demod->now.tv_sec % cfg->report_noise == 0) {
+        fprintf(stderr, "Current level %.1f dB, estimated noise %.1f dB\n", avg_db, demod->noise_level);
+    }
+
+    if (process_frame)
     baseband_low_pass_filter(demod->buf.temp, demod->am_buf, n_samples, &demod->lowpass_filter_state);
 
     // FM demodulation
@@ -373,7 +414,7 @@ static void sdr_callback(unsigned char *iq_buf, uint32_t len, void *ctx)
             fpdm = FSK_PULSE_DETECT_OLD;
     }
 
-    if (demod->enable_FM_demod) {
+    if (demod->enable_FM_demod && process_frame) {
         float low_pass = demod->low_pass != 0.0f ? demod->low_pass : fpdm ? 0.2f : 0.1f;
         if (demod->sample_size == 2) { // CU8
             baseband_demod_FM(iq_buf, demod->buf.fm, n_samples, cfg->samp_rate, low_pass, &demod->demod_FM_state);
@@ -405,7 +446,7 @@ static void sdr_callback(unsigned char *iq_buf, uint32_t len, void *ctx)
                 break;
             }
         }
-        while (package_type) {
+        while (package_type && process_frame) {
             int p_events = 0; // Sensor events successfully detected per package
             package_type = pulse_detect_package(demod->pulse_detect, demod->am_buf, demod->buf.fm, n_samples, cfg->samp_rate, cfg->input_pos, &demod->pulse_data, &demod->fsk_pulse_data, fpdm);
             if (package_type) {
@@ -964,6 +1005,8 @@ static void parse_conf_option(r_cfg_t *cfg, int opt, char *arg)
             cfg->report_protocol = 0;
         else if (!strcasecmp(arg, "level"))
             cfg->report_meta = 1;
+        else if (!strcasecmp(arg, "noise"))
+            cfg->report_noise = atoiv(arg_param(arg), 10); // atoi_time_default()
         else if (!strcasecmp(arg, "bits"))
             cfg->verbose_bits = 1;
         else if (!strcasecmp(arg, "description"))
@@ -976,7 +1019,7 @@ static void parse_conf_option(r_cfg_t *cfg, int opt, char *arg)
             // there also should be options to set wether to flush on report
             char *p = arg_param(arg);
             cfg->report_stats = atoiv(p, 1);
-            cfg->stats_interval = atoiv(arg_param(p), 600);
+            cfg->stats_interval = atoiv(arg_param(p), 600); // atoi_time_default()
             time(&cfg->stats_time);
             cfg->stats_time += cfg->stats_interval;
         }
@@ -1105,7 +1148,11 @@ static void parse_conf_option(r_cfg_t *cfg, int opt, char *arg)
             usage(1);
         char *p = arg;
         while (p && *p) {
-            if (!strncmp(p, "auto", 4))
+            if (!strncasecmp(p, "autolevel", 9))
+                cfg->demod->auto_level = atoiv(arg_param(arg), 1); // arg_float_default(p + 9, "-Y autolevel: ");
+            else if (!strncasecmp(p, "squelch", 7))
+                cfg->demod->squelch_offset = atoiv(arg_param(arg), 1); // arg_float_default(p + 7, "-Y squelch: ");
+            else if (!strncmp(p, "auto", 4))
                 cfg->fsk_pulse_detect_mode = FSK_PULSE_DETECT_AUTO;
             else if (!strncmp(p, "classic", 7))
                 cfg->fsk_pulse_detect_mode = FSK_PULSE_DETECT_OLD;
diff --git a/src/term_ctl.c b/src/term_ctl.c
index b83e5415..4774956d 100644
--- a/src/term_ctl.c
+++ b/src/term_ctl.c
@@ -377,7 +377,7 @@ int term_help_puts(void *ctx, char const *buf)
             state = 1;
             next_color = 5;
         }
-        else if ((state == 1 || state == 2) && *p == ']' && (p[1] == ' ' || p[1] == '\n' || p[1] == '\0')) {
+        else if ((state == 1 || state == 2) && *p == ']' && ((p[1] == ' ' && p[2] != '|') || p[1] == '\n' || p[1] == '\0')) {
             state = 0;
             set_color = 0;
         }