diff --git a/config.example.toml b/config.example.toml
index 4b1e964c480dfd761de57729da313f9897525a21..e90621d7851eefb5993d738f4c1ab4878b76544a 100644
--- a/config.example.toml
+++ b/config.example.toml
@@ -1,6 +1,7 @@
 # rtl_fm parameters
 frequency = 430_500_000 # center frequency, Hz
-device_id = 0 # ID of your RTL-SDR; 0 is default
+device_id = "0" # ID of your RTL-SDR; 0 is default
+# gain = 30.0 # dB. Uses AGC when not specified
 
 # if set to true:
 #  - expects 48k samples/second, 16-bit LE IQ.
diff --git a/src/config.rs b/src/config.rs
index 15d9372f32d44780689b7e3647fe76d81ad28f21..fae5464da07773a2e844fb2d5450ab5fcd22bfd9 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -4,6 +4,10 @@ use anyhow::{bail, Context};
 use serde::Deserialize;
 use serde_with::{serde_as, DurationSeconds};
 
+fn default_device_id() -> String {
+    "0".to_string()
+}
+
 #[serde_as]
 #[derive(Deserialize, Clone)]
 pub struct BeaconConfig {
@@ -31,8 +35,9 @@ pub struct FelinetConfig {
 #[derive(Deserialize, Clone)]
 pub struct Config {
     pub frequency: u32,
-    #[serde(default)]
-    pub device_id: u32,
+    #[serde(default = "default_device_id")]
+    pub device_id: String,
+    pub gain: Option<f32>,
     #[serde(default)]
     pub use_stdin: bool,
     pub max_deviation: i32,
diff --git a/src/decoder/mod.rs b/src/decoder/mod.rs
index 57ebe6c58a09bfcdaaf444fc20e21d35685ba99f..3457fae0e778b1b112b960b71f046c98e56cdbc6 100644
--- a/src/decoder/mod.rs
+++ b/src/decoder/mod.rs
@@ -27,7 +27,7 @@ pub fn decode_forever(felinet_send: mpsc::Sender<SemiPacketIn>, config: &Config,
 
         Box::new(stdin.bytes().map(|x| x.expect("Could not read from stdin")))
     } else {
-        let rtl = RtlSdr::new(config.frequency, config.device_id).unwrap();
+        let rtl = RtlSdr::new(config.frequency, &config.device_id, config.gain).unwrap();
         Box::new(rtl)
     };
 
diff --git a/src/decoder/rtl.rs b/src/decoder/rtl.rs
index 2285b05c8d229e51f27afd4f6deaa0d17b37f7e9..7e7bb077994ed76cf9f0dec7e43a6d572b8497c8 100644
--- a/src/decoder/rtl.rs
+++ b/src/decoder/rtl.rs
@@ -11,14 +11,19 @@ pub struct RtlSdr {
 }
 
 impl RtlSdr {
-    pub fn new(freq: u32, device_id: u32) -> anyhow::Result<Self> {
+    pub fn new(freq: u32, device_id: &str, gain: Option<f32>) -> anyhow::Result<Self> {
         let freq = format!("{freq}");
-        let device_id = format!("{device_id}");
+        let mut args = vec![
+            "rtl_fm", "-f", &freq, "-M", "raw", "-F9", "-p", "0", "-d", device_id, "-s", "48000",
+        ];
+        let mut gain_s = String::new();
+        if let Some(g) = gain {
+            args.push("-g");
+            gain_s.push_str(&format!("{:.2}", g));
+            args.push(&gain_s);
+        }
         let mut process = Popen::create(
-            &[
-                "rtl_fm", "-f", &freq, "-M", "raw", "-F9", "-p", "0", "-d", &device_id, "-s",
-                "48000",
-            ],
+            &args,
             PopenConfig {
                 stdout: Redirection::Pipe,
                 stderr: Redirection::Pipe,