diff --git a/src/codec2/mod.rs b/src/codec2/mod.rs
index 6a3b22d878c7423cff050723acff8efabe3530d3..f16ef03107c504ada4ded04aacd26f0acdcafb4e 100644
--- a/src/codec2/mod.rs
+++ b/src/codec2/mod.rs
@@ -1,8 +1,11 @@
-use std::collections::VecDeque;
+use std::{
+    collections::VecDeque,
+    ops::{AddAssign, Div, Sub},
+};
 
 const MODE_M_MAX: usize = 4;
 const M: i32 = 2;
-const N_SYM: i32 = 50;
+const N_SYM: i32 = 35;
 
 #[link(name = "fsk", kind = "static")]
 extern "C" {
@@ -88,11 +91,50 @@ struct InternalFsk {
 }
 
 #[repr(C)]
+#[derive(Debug, Copy, Clone)]
 pub struct Complex {
     pub real: libc::c_float,
     pub imag: libc::c_float,
 }
 
+impl Complex {
+    pub const fn zero() -> Self {
+        Self {
+            real: 0.0,
+            imag: 0.0,
+        }
+    }
+}
+
+impl Sub for Complex {
+    type Output = Complex;
+
+    fn sub(self, rhs: Self) -> Complex {
+        Complex {
+            real: self.real - rhs.real,
+            imag: self.imag - rhs.imag,
+        }
+    }
+}
+
+impl AddAssign for Complex {
+    fn add_assign(&mut self, rhs: Self) {
+        self.real += rhs.real;
+        self.imag += rhs.imag;
+    }
+}
+
+impl Div<f32> for Complex {
+    type Output = Complex;
+
+    fn div(self, rhs: f32) -> Complex {
+        Complex {
+            real: self.real / rhs,
+            imag: self.imag / rhs,
+        }
+    }
+}
+
 pub struct Fsk<I: Iterator<Item = Complex>> {
     internal: *mut InternalFsk,
     input_cache: Vec<Complex>,
@@ -102,9 +144,10 @@ pub struct Fsk<I: Iterator<Item = Complex>> {
 
 impl<I: Iterator<Item = Complex>> Fsk<I> {
     pub fn new(iq_iter: I) -> Self {
-        const FS: i32 = 9600 * 5;
+        const P: i32 = 10;
+        const FS: i32 = 9600 * P;
 
-        let internal = unsafe { fsk_create_hbr(FS, 9600, M, 5, N_SYM, -1, 0) };
+        let internal = unsafe { fsk_create_hbr(FS, 9600, M, P, N_SYM, -1, 0) };
 
         // Set upper/lower bound on the FSK peaks, from center
         // (Hz)
diff --git a/src/decoder/dc_bias.rs b/src/decoder/dc_bias.rs
new file mode 100644
index 0000000000000000000000000000000000000000..cd769ed794c504ad0f09c18c45a293d937f45d8e
--- /dev/null
+++ b/src/decoder/dc_bias.rs
@@ -0,0 +1,40 @@
+use crate::codec2::Complex;
+
+// 1 seconds @ 48KHz
+const AVERAGE_TIME: usize = 48_000;
+
+pub struct RemoveDcBias<I: Iterator<Item = Complex>> {
+    iter: I,
+    sum: Complex,
+    i: usize,
+    avg: Complex,
+}
+
+impl<I: Iterator<Item = Complex>> RemoveDcBias<I> {
+    pub fn new(iter: I) -> Self {
+        Self {
+            iter,
+            sum: Complex::zero(),
+            i: 0,
+            avg: Complex::zero(),
+        }
+    }
+}
+
+impl<I: Iterator<Item = Complex>> Iterator for RemoveDcBias<I> {
+    type Item = Complex;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        let val = self.iter.next()?;
+
+        self.sum += val;
+        self.i += 1;
+        if self.i == AVERAGE_TIME {
+            self.avg = self.sum / (self.i as f32);
+            self.i = 0;
+            self.sum = Complex::zero();
+        }
+
+        Some(val - self.avg)
+    }
+}
diff --git a/src/decoder/demod.rs b/src/decoder/demod.rs
index e9238915e38b7d538937ceb9044cd494ef22beb7..f7a6b4eb26d0674c164ffa3b05798a4bf2192252 100644
--- a/src/decoder/demod.rs
+++ b/src/decoder/demod.rs
@@ -8,7 +8,7 @@ use crate::MAX_PACKET_LEN;
 use super::packet::{PacketDecoder, Status};
 
 const SYNC_WORD: u32 = 0xABCDEF12;
-const MAX_BIT_FLIPS: u32 = 3;
+const MAX_BIT_FLIPS: u32 = 5;
 
 pub struct Demod<T: DecodeFrom, I: Iterator<Item = T>> {
     rolling_sync: u32,
@@ -49,8 +49,8 @@ impl<T: DecodeFrom, I: Iterator<Item = T>> Demod<T, I> {
                 }
             }
 
-            for i in to_remove {
-                self.decoders.swap_remove(i);
+            for i in to_remove.iter().rev() {
+                self.decoders.swap_remove(*i);
             }
 
             if self.sync_matches() {
diff --git a/src/decoder/mod.rs b/src/decoder/mod.rs
index 66c8ef58b5e9d533520249f57a508309f66ac2f6..3b77cc0b868802802bf1131a601fdd808f96e74d 100644
--- a/src/decoder/mod.rs
+++ b/src/decoder/mod.rs
@@ -11,8 +11,9 @@ use crate::{
     util::{append_internet_to_packet_route, print_packet},
 };
 
-use self::demod::Demod;
+use self::{dc_bias::RemoveDcBias, demod::Demod};
 
+mod dc_bias;
 mod demod;
 mod packet;
 
@@ -34,7 +35,9 @@ pub fn decode_forever(
             Complex { real, imag }
         });
 
-    let soft_bits = Fsk::new(iq);
+    let iq_no_dc = RemoveDcBias::new(iq);
+
+    let soft_bits = Fsk::new(iq_no_dc);
 
     let demod = Demod::new(soft_bits);