diff --git a/grc/PicoSDR-WBFM.grc b/grc/PicoSDR-WBFM.grc
index c9d33cc..6be09c4 100644
--- a/grc/PicoSDR-WBFM.grc
+++ b/grc/PicoSDR-WBFM.grc
@@ -37,7 +37,7 @@ blocks:
   id: variable
   parameters:
     comment: ''
-    value: '94_600_000'
+    value: '88_200_000'
   states:
     bus_sink: false
     bus_source: false
@@ -49,7 +49,7 @@ blocks:
   id: variable
   parameters:
     comment: ''
-    value: '192_000'
+    value: '200_000'
   states:
     bus_sink: false
     bus_source: false
@@ -78,7 +78,7 @@ blocks:
   parameters:
     affinity: ''
     alias: ''
-    audio_decimation: '4'
+    audio_decimation: '8'
     comment: ''
     deemph_tau: 75e-6
     maxoutbuf: '0'
@@ -100,7 +100,7 @@ blocks:
     device_name: ''
     num_inputs: '2'
     ok_to_block: 'True'
-    samp_rate: samp_rate // 4
+    samp_rate: samp_rate // 8
   states:
     bus_sink: false
     bus_source: false
@@ -150,15 +150,15 @@ blocks:
     alias: ''
     beta: '6.76'
     comment: ''
-    cutoff_freq: samp_rate / 8
-    decim: '4'
+    cutoff_freq: samp_rate / 16
+    decim: '8'
     gain: '1'
     interp: '1'
     maxoutbuf: '0'
     minoutbuf: '0'
     samp_rate: samp_rate
     type: fir_filter_fff
-    width: samp_rate / 8
+    width: samp_rate / 16
     win: window.WIN_HAMMING
   states:
     bus_sink: false
@@ -677,7 +677,7 @@ blocks:
     name: '"FM Demodulation"'
     nconnections: '1'
     size: '512'
-    srate: samp_rate // (2 ** 3)
+    srate: samp_rate // 8
     stemplot: 'False'
     style1: '1'
     style10: '1'
@@ -856,4 +856,4 @@ connections:
 
 metadata:
   file_format: 1
-  grc_version: 3.10.9.2
+  grc_version: 3.10.11.0
diff --git a/src/main.c b/src/main.c
index b654e0f..8fcbf11 100644
--- a/src/main.c
+++ b/src/main.c
@@ -53,27 +53,28 @@ static uint32_t lo_sin[LO_WORDS] __attribute__((__aligned__(1 << LO_BITS_DEPTH))
 
 #define INIT_SAMPLE_RATE 100000
 #define INIT_FREQ 94600000
-#define INIT_GAIN 127
 
-#define NUM_GAINS 29
-static int gains[NUM_GAINS] = { 0,   9,	  14,  27,  37,	 77,  87,  125, 144, 157,
-				166, 197, 207, 229, 254, 280, 297, 328, 338, 364,
-				372, 386, 402, 421, 434, 439, 445, 480, 496 };
+#define BASE_GAIN (1 << 15)
+#define ATTN_BITS 8
+
 static int sample_rate = INIT_SAMPLE_RATE;
-static int max_amplitude = CLK_SYS_HZ / INIT_SAMPLE_RATE / 2;
-static int gain = INIT_GAIN;
+static int gain = BASE_GAIN / (CLK_SYS_HZ / INIT_SAMPLE_RATE / 2);
 static int frequency = INIT_FREQ;
 
 static queue_t iq_queue;
 static uint8_t iq_queue_buffer[IQ_QUEUE_LEN][IQ_BLOCK_LEN];
 static size_t iq_queue_pos = 0;
 
-static uint32_t rnd = 0;
+static uint32_t xorshift_seed;
 
-inline static __unused uint32_t rnd_next()
+static inline __unused uint32_t xorshift(void)
 {
-	rnd = rnd * 0x41c64e6d + 12345;
-	return rnd;
+	uint32_t x = xorshift_seed;
+	x ^= x << 13;
+	x ^= x >> 17;
+	x ^= x << 5;
+	xorshift_seed = x;
+	return x;
 }
 
 static void dma_channel_clear_chain_to(int ch)
@@ -187,6 +188,7 @@ static const uint32_t samp_insn = 16;
 static void init_adder()
 {
 	const uint16_t insn[] = {
+		/* y has weight of 2, x has weight of 1 */
 		pio_encode_out(pio_pc, 4), // 0000 +0
 		pio_encode_jmp_x_dec(0),   // 0001 +1
 		pio_encode_jmp_x_dec(0),   // 0010 +1
@@ -428,6 +430,11 @@ static void rf_rx_stop(void)
 	dma_ch_samp_sin = -1;
 }
 
+inline static void led_set(bool on)
+{
+	gpio_put(PICO_DEFAULT_LED_PIN, on);
+}
+
 inline static uint32_t pio_sm_get_blocking_unsafe(pio_hw_t *pio, int sm)
 {
 	while (pio->fstat & (1u << (PIO_FSTAT_RXEMPTY_LSB + sm)))
@@ -438,12 +445,18 @@ inline static uint32_t pio_sm_get_blocking_unsafe(pio_hw_t *pio, int sm)
 
 inline static int nextI()
 {
-	static int prevI = 0;
+	static int prevI2, prevI1, prevI;
 
-	int sI = 0;
-	sI -= 2 * pio_sm_get_blocking_unsafe(PIO, SM_COS);
-	sI -= pio_sm_get_blocking_unsafe(PIO, SM_COS);
+	int sI2 = pio_sm_get_blocking_unsafe(PIO, SM_COS);
 
+	int I2 = sI2 - prevI2;
+	prevI2 = sI2;
+
+	int sI1 = pio_sm_get_blocking_unsafe(PIO, SM_COS);
+	int I1 = sI1 - prevI1;
+	prevI1 = sI1;
+
+	int sI = I2 + I2 + I1;
 	int I = sI - prevI;
 	prevI = sI;
 
@@ -452,12 +465,18 @@ inline static int nextI()
 
 inline static int nextQ()
 {
-	static int prevQ = 0;
+	static int prevQ2, prevQ1, prevQ;
 
-	int sQ = 0;
-	sQ -= 2 * pio_sm_get_blocking_unsafe(PIO, SM_SIN);
-	sQ -= pio_sm_get_blocking_unsafe(PIO, SM_SIN);
+	int sQ2 = pio_sm_get_blocking_unsafe(PIO, SM_SIN);
 
+	int Q2 = sQ2 - prevQ2;
+	prevQ2 = sQ2;
+
+	int sQ1 = pio_sm_get_blocking_unsafe(PIO, SM_SIN);
+	int Q1 = sQ1 - prevQ1;
+	prevQ1 = sQ1;
+
+	int sQ = Q2 + Q2 + Q1;
 	int Q = sQ - prevQ;
 	prevQ = sQ;
 
@@ -492,28 +511,21 @@ static void rf_rx(void)
 			Q -= nextI();
 
 			I *= gain;
-			I /= max_amplitude;
+			I >>= ATTN_BITS;
 
-			if (I > 127)
-				I = 127;
-			else if (I < -128)
-				I = -128;
-
-			*blockptr++ = (uint8_t)I + 128;
+			*blockptr++ = I + 128;
 
 			Q *= gain;
-			Q /= max_amplitude;
+			Q >>= ATTN_BITS;
 
-			if (Q > 127)
-				Q = 127;
-			else if (Q < -128)
-				Q = -128;
-
-			*blockptr++ = (uint8_t)Q + 128;
+			*blockptr++ = Q + 128;
 		}
 
 		if (queue_try_add(&iq_queue, &block)) {
-			iq_queue_pos = (iq_queue_pos + 1) & (IQ_QUEUE_LEN - 1);
+			iq_queue_pos = (iq_queue_pos + 1) % IQ_QUEUE_LEN;
+			led_set(0);
+		} else {
+			led_set(1);
 		}
 	}
 }
@@ -527,16 +539,9 @@ static void run_command(uint8_t cmd, uint32_t arg)
 	} else if (0x02 == cmd) {
 		/* Set the rate at which IQ sample pairs are sent */
 		sample_rate = arg;
-		max_amplitude = CLK_SYS_HZ / sample_rate / 2;
+		gain = BASE_GAIN / (CLK_SYS_HZ / sample_rate / 2);
 		dma_timer_set_fraction(dma_t_samp, 1, CLK_SYS_HZ / (sample_rate * DECIMATE));
 		rx_lo_init(frequency + sample_rate, true);
-	} else if (0x04 == cmd) {
-		/* Set the tuner gain level */
-		gain = INIT_GAIN * pow(10.0, arg / 200.0);
-	} else if (0x0d == cmd) {
-		/* Set tuner gain by the tuner's gain index */
-		if (arg <= NUM_GAINS)
-			gain = INIT_GAIN * pow(10.0, gains[arg] / 200.0);
 	}
 }
 
@@ -587,7 +592,7 @@ static void do_rx()
 			fwrite(block, IQ_BLOCK_LEN, 1, stdout);
 			fflush(stdout);
 		} else {
-			int wait = rnd_next() & 0x1fff;
+			int wait = xorshift() >> (32 - 15);
 
 			for (int i = 0; i < wait; i++)
 				asm volatile("nop");
@@ -615,6 +620,10 @@ int main()
 	gpio_set_dir(PSU_PIN, GPIO_OUT);
 	gpio_put(PSU_PIN, 1);
 
+	gpio_init(PICO_DEFAULT_LED_PIN);
+	gpio_set_dir(PICO_DEFAULT_LED_PIN, GPIO_OUT);
+	gpio_put(PICO_DEFAULT_LED_PIN, 0);
+
 	/* Prioritize DMA over CPU. */
 	bus_ctrl_hw->priority |= BUSCTRL_BUS_PRIORITY_DMA_W_BITS | BUSCTRL_BUS_PRIORITY_DMA_R_BITS;
 
@@ -633,7 +642,7 @@ int main()
 		if (check_command() > 0) {
 			static const uint32_t header[3] = { __builtin_bswap32(0x52544c30),
 							    __builtin_bswap32(5),
-							    __builtin_bswap32(NUM_GAINS) };
+							    __builtin_bswap32(29) };
 			fwrite(header, sizeof header, 1, stdout);
 			fflush(stdout);