diff --git a/firmware/application/apps/capture_app.cpp b/firmware/application/apps/capture_app.cpp
index e5b9a36c643ed00cc2509f7c75a86c5b03d07263..0719255602ad4001ef8bea27661bf2cb4179bc26 100644
--- a/firmware/application/apps/capture_app.cpp
+++ b/firmware/application/apps/capture_app.cpp
@@ -35,6 +35,7 @@ CaptureAppView::CaptureAppView(NavigationView& nav) {
 	baseband::run_image(portapack::spi_flash::image_tag_capture);
 
 	add_children({
+		&labels,
 		&rssi,
 		&channel,
 		&field_frequency,
@@ -42,6 +43,7 @@ CaptureAppView::CaptureAppView(NavigationView& nav) {
 		&field_rf_amp,
 		&field_lna,
 		&field_vga,
+		&option_bandwidth,
 		&record_view,
 		&waterfall,
 	});
@@ -65,6 +67,16 @@ CaptureAppView::CaptureAppView(NavigationView& nav) {
 		receiver_model.set_frequency_step(v);
 		this->field_frequency.set_step(v);
 	};
+	
+	option_bandwidth.on_change = [this](size_t, uint32_t divider) {
+		sampling_rate = 4000000 / divider;
+		
+		waterfall.on_hide();
+		set_target_frequency(target_frequency());
+		record_view.set_sampling_rate(sampling_rate);
+		radio::set_baseband_rate(sampling_rate);
+		waterfall.on_show();
+	};
 
 	radio::enable({
 		tuning_frequency(),
@@ -75,8 +87,9 @@ CaptureAppView::CaptureAppView(NavigationView& nav) {
 		static_cast<int8_t>(receiver_model.lna()),
 		static_cast<int8_t>(receiver_model.vga()),
 	});
+	
+	option_bandwidth.set_selected_index(4);		// 500k
 
-	record_view.set_sampling_rate(sampling_rate / 8);
 	record_view.on_error = [&nav](std::string message) {
 		nav.display_modal("Error", message);
 	};
diff --git a/firmware/application/apps/capture_app.hpp b/firmware/application/apps/capture_app.hpp
index 7764c76b506a886b1163c5ffa08228e6e5410ea1..cadcb0fcc76d875cebe48c8e9efe701a9712390e 100644
--- a/firmware/application/apps/capture_app.hpp
+++ b/firmware/application/apps/capture_app.hpp
@@ -47,9 +47,9 @@ public:
 	std::string title() const override { return "Capture"; };
 
 private:
-	static constexpr ui::Dim header_height = 2 * 16;
+	static constexpr ui::Dim header_height = 3 * 16;
 
-	static constexpr uint32_t sampling_rate = 4000000;
+	uint32_t sampling_rate = 0;
 	static constexpr uint32_t baseband_bandwidth = 2500000;
 
 	void on_target_frequency_changed(rf::Frequency f);
@@ -59,6 +59,10 @@ private:
 
 	rf::Frequency tuning_frequency() const;
 
+	Labels labels {
+		{ { 0 * 8, 1 * 16 }, "Rate:", Color::light_grey() },
+	};
+	
 	RSSI rssi {
 		{ 24 * 8, 0, 6 * 8, 4 },
 	};
@@ -87,8 +91,20 @@ private:
 		{ 21 * 8, 0 * 16 }
 	};
 
+	OptionsField option_bandwidth {
+		{ 5 * 8, 1 * 16 },
+		4,
+		{
+			{ " 25k", 20 },
+			{ " 50k", 10 },
+			{ "100k", 5 },
+			{ "250k", 2 },
+			{ "500k", 1 }
+		}
+	};
+	
 	RecordView record_view {
-		{ 0 * 8, 1 * 16, 30 * 8, 1 * 16 },
+		{ 0 * 8, 2 * 16, 30 * 8, 1 * 16 },
 		u"BBD_????", RecordView::FileType::RawS16, 16384, 3
 	};
 
diff --git a/firmware/application/apps/replay_app.cpp b/firmware/application/apps/replay_app.cpp
index 43475f4cd5ccc0a897fcb216a5db90d0fad7f1b6..be34e619de7ba3ed0b14746db3bffdd37df1fbbf 100644
--- a/firmware/application/apps/replay_app.cpp
+++ b/firmware/application/apps/replay_app.cpp
@@ -51,30 +51,40 @@ void ReplayAppView::on_file_changed(std::filesystem::path new_file_path) {
 	
 	file_path = new_file_path;
 	
-	auto file_size = data_file.size();
-	auto duration = (file_size * 1000) / (2 * 2 * sampling_rate / 8);
-	
-	progressbar.set_max(file_size);
-	text_filename.set(file_path.filename().string().substr(0, 19));
-	text_duration.set(to_string_time_ms(duration));
-	
 	// Get original record frequency if available
 	std::filesystem::path info_file_path = file_path;
 	info_file_path.replace_extension(u".TXT");
 	
+	sample_rate = 500000;
+	
 	auto info_open_error = info_file.open("/" + info_file_path.string());
 	if (!info_open_error.is_valid()) {
 		memset(file_data, 0, 257);
 		auto read_size = info_file.read(file_data, 256);
 		if (!read_size.is_error()) {
-			auto pos = strstr(file_data, "center_frequency=");
-			if (pos) {
-				pos += 17;
-				field_frequency.set_value(strtoll(pos, nullptr, 10));
+			auto pos1 = strstr(file_data, "center_frequency=");
+			if (pos1) {
+				pos1 += 17;
+				field_frequency.set_value(strtoll(pos1, nullptr, 10));
+			}
+			
+			auto pos2 = strstr(file_data, "sample_rate=");
+			if (pos2) {
+				pos2 += 12;
+				sample_rate = strtoll(pos2, nullptr, 10);
 			}
 		}
 	}
 	
+	text_sample_rate.set(unit_auto_scale(sample_rate, 3, 0) + "Hz");
+	
+	auto file_size = data_file.size();
+	auto duration = (file_size * 1000) / (2 * 2 * sample_rate);
+	
+	progressbar.set_max(file_size);
+	text_filename.set(file_path.filename().string().substr(0, 12));
+	text_duration.set(to_string_time_ms(duration));
+	
 	button_play.focus();
 }
 
@@ -117,6 +127,8 @@ void ReplayAppView::start() {
 
 	if( reader ) {
 		button_play.set_bitmap(&bitmap_stop);
+		baseband::set_sample_rate(sample_rate * 8);
+		
 		replay_thread = std::make_unique<ReplayThread>(
 			std::move(reader),
 			read_size, buffer_count,
@@ -130,7 +142,7 @@ void ReplayAppView::start() {
 	
 	radio::enable({
 		receiver_model.tuning_frequency(),
-		sampling_rate,
+		sample_rate * 8 ,
 		baseband_bandwidth,
 		rf::Direction::Transmit,
 		receiver_model.rf_amp(),
@@ -172,6 +184,7 @@ ReplayAppView::ReplayAppView(
 		&labels,
 		&button_open,
 		&text_filename,
+		&text_sample_rate,
 		&text_duration,
 		&progressbar,
 		&field_frequency,
diff --git a/firmware/application/apps/replay_app.hpp b/firmware/application/apps/replay_app.hpp
index 30801f8bbca0ac178bcee54d99ea739d56ccd42a..9a25ffcf4abac8db17d4591bd78919283bd002fe 100644
--- a/firmware/application/apps/replay_app.hpp
+++ b/firmware/application/apps/replay_app.hpp
@@ -50,7 +50,7 @@ private:
 	
 	static constexpr ui::Dim header_height = 3 * 16;
 	
-	static constexpr uint32_t sampling_rate = 4000000;
+	uint32_t sample_rate = 0;
 	static constexpr uint32_t baseband_bandwidth = 2500000;
 	const size_t read_size { 16384 };
 	const size_t buffer_count { 3 };
@@ -76,7 +76,6 @@ private:
 
 	Labels labels {
 		{ { 10 * 8, 2 * 16 }, "LNA:   A:", Color::light_grey() }
-		//{ { 10 * 8, 2 * 16 }, "500ksps", Color::light_grey() }
 	};
 	
 	Button button_open {
@@ -85,9 +84,14 @@ private:
 	};
 	
 	Text text_filename {
-		{ 11 * 8, 0 * 16, 19 * 8, 16 },
+		{ 11 * 8, 0 * 16, 12 * 8, 16 },
 		"-"
 	};
+	Text text_sample_rate {
+		{ 24 * 8, 0 * 16, 6 * 8, 16 },
+		"-"
+	};
+	
 	Text text_duration {
 		{ 11 * 8, 1 * 16, 6 * 8, 16 },
 		"-"
diff --git a/firmware/application/apps/ui_about.hpp b/firmware/application/apps/ui_about.hpp
index 3e138c0056b9b62fb614a0d92285fad7775c192e..fd8a1cbc609cf38135bdfd41b77ae8a21367cce8 100644
--- a/firmware/application/apps/ui_about.hpp
+++ b/firmware/application/apps/ui_about.hpp
@@ -97,7 +97,7 @@ private:
 		{ 1 * 8, 	" Windyoona         Channels",		0 },
 		{ 1 * 8, 	"   F4GEV             Pyr3x",		0 },
 		{ 1 * 8,    "  HB3YOE",							24 },
-		{ 12 * 8,	            "MMXVII",				-1 }
+		{ 11 * 8,	            "MMXVIII",				-1 }
 	};
 	
 	CreditsWidget credits_display {
diff --git a/firmware/application/apps/ui_setup.cpp b/firmware/application/apps/ui_setup.cpp
index 31a86d48cc7ace3980b9dcf719bc8e4fa18520ca..c358db48f012c01c431919a287369f6c31cd13a6 100644
--- a/firmware/application/apps/ui_setup.cpp
+++ b/firmware/application/apps/ui_setup.cpp
@@ -135,9 +135,9 @@ SetRadioView::SetRadioView(
 
 	form_init(model);
 
-	check_bias.set_value(receiver_model.antenna_bias());
+	check_bias.set_value(portapack::get_antenna_bias());
 	check_bias.on_select = [this](Checkbox&, bool v) {
-		receiver_model.set_antenna_bias(v);
+		portapack::set_antenna_bias(v);
 		StatusRefreshMessage message { };
 		EventDispatcher::send_message(message);
 	};
diff --git a/firmware/application/baseband_api.cpp b/firmware/application/baseband_api.cpp
index 499c98871f30d95c6a0c20ffd52d30372432eb3e..ef03ac9d5fdbd001f347d7b47bdb78f9c2b9395a 100644
--- a/firmware/application/baseband_api.cpp
+++ b/firmware/application/baseband_api.cpp
@@ -296,6 +296,11 @@ void spectrum_streaming_stop() {
 	send_message(&message);
 }
 
+void set_sample_rate(const uint32_t sample_rate) {
+	SamplerateConfigMessage message { sample_rate };
+	send_message(&message);
+}
+
 void capture_start(CaptureConfig* const config) {
 	CaptureConfigMessage message { config };
 	send_message(&message);
diff --git a/firmware/application/baseband_api.hpp b/firmware/application/baseband_api.hpp
index 3f06b4d65ea58bd32b156a8fd1b44e77e5db6959..22f6ead6eeb73ffe9fae53195c6e7188321e9191 100644
--- a/firmware/application/baseband_api.hpp
+++ b/firmware/application/baseband_api.hpp
@@ -87,6 +87,7 @@ void shutdown();
 void spectrum_streaming_start();
 void spectrum_streaming_stop();
 
+void set_sample_rate(const uint32_t sample_rate);
 void capture_start(CaptureConfig* const config);
 void capture_stop();
 void replay_start(ReplayConfig* const config);
diff --git a/firmware/application/portapack.cpp b/firmware/application/portapack.cpp
index 98d97129493e0bcd5f73aec0f671fb11af70d815..a3cf5f1859437277bde5a7af9a477db3ec0e9346 100644
--- a/firmware/application/portapack.cpp
+++ b/firmware/application/portapack.cpp
@@ -77,12 +77,20 @@ WM8731 audio_codec_wm8731 { i2c0, 0x1a };
 AK4951 audio_codec_ak4951 { i2c0, 0x12 };
 
 ReceiverModel receiver_model;
+TransmitterModel transmitter_model;
 
 TemperatureLogger temperature_logger;
 
-TransmitterModel transmitter_model;
+bool antenna_bias { false };
+uint8_t bl_tick_counter { 0 };
 
-uint8_t bl_tick_counter = 0;
+void set_antenna_bias(const bool v) {
+	antenna_bias = v;
+}
+
+bool get_antenna_bias() {
+	return antenna_bias;
+}
 
 class Power {
 public:
diff --git a/firmware/application/portapack.hpp b/firmware/application/portapack.hpp
index c105cdfb36349e65ff939da668c0e5366423b48d..359b14468a76bc16f9d8a41e4e2c49c4ce9c13d0 100644
--- a/firmware/application/portapack.hpp
+++ b/firmware/application/portapack.hpp
@@ -52,9 +52,13 @@ extern ReceiverModel receiver_model;
 extern TransmitterModel transmitter_model;
 
 extern uint8_t bl_tick_counter;
+extern bool antenna_bias;
 
 extern TemperatureLogger temperature_logger;
 
+void set_antenna_bias(const bool v);
+bool get_antenna_bias();
+
 bool init();
 void shutdown();
 
diff --git a/firmware/application/receiver_model.cpp b/firmware/application/receiver_model.cpp
index 9b68bbe6fa743c465612a8e7ed4dabbbca813aa2..c8b49967917e49e085654abe250b8395e8df5e7a 100644
--- a/firmware/application/receiver_model.cpp
+++ b/firmware/application/receiver_model.cpp
@@ -25,6 +25,7 @@
 
 #include "portapack_persistent_memory.hpp"
 #include "hackrf_gpio.hpp"
+#include "portapack.hpp"
 using namespace hackrf::one;
 using namespace portapack;
 
@@ -72,12 +73,7 @@ void ReceiverModel::set_frequency_step(rf::Frequency f) {
 	frequency_step_ = f;
 }
 
-bool ReceiverModel::antenna_bias() const {
-	return antenna_bias_;
-}
-
-void ReceiverModel::set_antenna_bias(bool enabled) {
-	antenna_bias_ = enabled;
+void ReceiverModel::set_antenna_bias() {
 	update_antenna_bias();
 }
 
@@ -180,7 +176,7 @@ void ReceiverModel::enable() {
 
 void ReceiverModel::disable() {
 	enabled_ = false;
-	update_antenna_bias();
+	radio::set_antenna_bias(false);
 
 	// TODO: Responsibility for enabling/disabling the radio is muddy.
 	// Some happens in ReceiverModel, some inside radio namespace.
@@ -201,7 +197,8 @@ void ReceiverModel::update_tuning_frequency() {
 }
 
 void ReceiverModel::update_antenna_bias() {
-	radio::set_antenna_bias(antenna_bias_ && enabled_);
+	if (enabled_)
+		radio::set_antenna_bias(portapack::get_antenna_bias());
 }
 
 void ReceiverModel::update_rf_amp() {
diff --git a/firmware/application/receiver_model.hpp b/firmware/application/receiver_model.hpp
index c3d993d145919f853e05304c004054c7b4c222b7..139f0d67e6554e148892925affcb2a486b8df02c 100644
--- a/firmware/application/receiver_model.hpp
+++ b/firmware/application/receiver_model.hpp
@@ -45,9 +45,8 @@ public:
 	rf::Frequency frequency_step() const;
 	void set_frequency_step(rf::Frequency f);
 
-	bool antenna_bias() const;
-	void set_antenna_bias(bool enabled);
-
+	void set_antenna_bias();
+	
 	bool rf_amp() const;
 	void set_rf_amp(bool enabled);
 
@@ -91,7 +90,6 @@ private:
 	rf::Frequency frequency_step_ { 25000 };
 	bool enabled_ { false };
 	bool rf_amp_ { false };
-	bool antenna_bias_ { false };
 	int32_t lna_gain_db_ { 32 };
 	uint32_t baseband_bandwidth_ { max2837::filter::bandwidth_minimum };
 	int32_t vga_gain_db_ { 32 };
diff --git a/firmware/application/transmitter_model.cpp b/firmware/application/transmitter_model.cpp
index 16dab39a112504e23888e2c906f8bdbe8d4f486b..1d5d402bd95176473902f6eb20f3d5eb9f9b5ca8 100644
--- a/firmware/application/transmitter_model.cpp
+++ b/firmware/application/transmitter_model.cpp
@@ -26,6 +26,7 @@
 
 #include "portapack_persistent_memory.hpp"
 #include "hackrf_gpio.hpp"
+#include "portapack.hpp"
 using namespace hackrf::one;
 using namespace portapack;
 
@@ -43,6 +44,10 @@ void TransmitterModel::set_tuning_frequency(rf::Frequency f) {
 	update_tuning_frequency();
 }
 
+void TransmitterModel::set_antenna_bias() {
+	update_antenna_bias();
+}
+
 bool TransmitterModel::rf_amp() const {
 	return rf_amp_;
 }
@@ -114,6 +119,7 @@ void TransmitterModel::enable() {
 	enabled_ = true;
 	radio::set_direction(rf::Direction::Transmit);
 	update_tuning_frequency();
+	update_antenna_bias();
 	update_rf_amp();
 	update_lna();
 	update_vga();
@@ -132,6 +138,7 @@ void TransmitterModel::enable() {
 
 void TransmitterModel::disable() {
 	enabled_ = false;
+	radio::set_antenna_bias(false);
 
 	// TODO: Responsibility for enabling/disabling the radio is muddy.
 	// Some happens in ReceiverModel, some inside radio namespace.
@@ -145,6 +152,11 @@ void TransmitterModel::update_tuning_frequency() {
 	radio::set_tuning_frequency(persistent_memory::tuned_frequency());
 }
 
+void TransmitterModel::update_antenna_bias() {
+	if (enabled_)
+		radio::set_antenna_bias(portapack::get_antenna_bias());
+}
+
 void TransmitterModel::update_rf_amp() {
 	radio::set_rf_amp(rf_amp_);
 }
diff --git a/firmware/application/transmitter_model.hpp b/firmware/application/transmitter_model.hpp
index 91176732992ffaf219111f0bce3c47935b2acc15..ef343218f82990bfcd285b6584ef049260bead46 100644
--- a/firmware/application/transmitter_model.hpp
+++ b/firmware/application/transmitter_model.hpp
@@ -38,6 +38,8 @@ public:
 	rf::Frequency tuning_frequency() const;
 	void set_tuning_frequency(rf::Frequency f);
 
+	void set_antenna_bias();
+	
 	bool rf_amp() const;
 	void set_rf_amp(bool enabled);
 
@@ -74,6 +76,7 @@ private:
 	SignalToken signal_token_tick_second { };
 
 	void update_tuning_frequency();
+	void update_antenna_bias();
 	void update_rf_amp();
 	void update_lna();
 	void update_baseband_bandwidth();
diff --git a/firmware/application/ui_navigation.cpp b/firmware/application/ui_navigation.cpp
index c2ff7fdd0a9628b08836ada3d87edaa890142124..a166558fd67e13683a50d6bc38c42492058dbb2d 100644
--- a/firmware/application/ui_navigation.cpp
+++ b/firmware/application/ui_navigation.cpp
@@ -77,6 +77,7 @@
 #include "png_writer.hpp"
 
 using portapack::receiver_model;
+using portapack::transmitter_model;
 
 namespace ui {
 
@@ -145,7 +146,7 @@ SystemStatusView::SystemStatusView(
 }
 
 void SystemStatusView::refresh() {
-	if (receiver_model.antenna_bias()) {
+	if (portapack::get_antenna_bias()) {
 		button_bias_tee.set_bitmap(&bitmap_icon_biast_on);
 		button_bias_tee.set_foreground(ui::Color::yellow());
 	} else {
@@ -171,28 +172,26 @@ void SystemStatusView::on_stealth() {
 	bool mode = not portapack::persistent_memory::stealth_mode();
 	
 	portapack::persistent_memory::set_stealth_mode(mode);
-	
-	if (mode)
-		button_stealth.set_foreground(ui::Color::green());
-	else
-		button_stealth.set_foreground(ui::Color::light_grey());
+
+	button_stealth.set_foreground(mode ? ui::Color::green() : ui::Color::light_grey());
 	
 	button_stealth.set_dirty();
 }
 
 void SystemStatusView::on_bias_tee() {
-	bool antenna_bias = receiver_model.antenna_bias();
-	
-	if (!antenna_bias) {
+	if (!portapack::antenna_bias) {
 		nav_.display_modal("Bias voltage", "Enable DC voltage on\nantenna connector ?", YESNO, [this](bool v) {
 				if (v) {
-					receiver_model.set_antenna_bias(true);
+					portapack::set_antenna_bias(true);
+					receiver_model.set_antenna_bias();
+					transmitter_model.set_antenna_bias();
 					refresh();
 				}
 			});
-	
 	} else {
-		receiver_model.set_antenna_bias(false);
+		portapack::set_antenna_bias(false);
+		receiver_model.set_antenna_bias();
+		transmitter_model.set_antenna_bias();
 		refresh();
 	}
 }
diff --git a/firmware/application/ui_record_view.cpp b/firmware/application/ui_record_view.cpp
index aa8cea1c5afd700116163972743f3640a2f7f29b..be8c818e44823c82c4cafe600d2b1024180ce0ca 100644
--- a/firmware/application/ui_record_view.cpp
+++ b/firmware/application/ui_record_view.cpp
@@ -27,8 +27,8 @@ using namespace portapack;
 #include "io_file.hpp"
 #include "io_wave.hpp"
 
+#include "baseband_api.hpp"
 #include "rtc_time.hpp"
-
 #include "string_format.hpp"
 #include "utility.hpp"
 
@@ -36,7 +36,7 @@ using namespace portapack;
 
 namespace ui {
 
-void RecordView::toggle_pitch_rssi() {
+/*void RecordView::toggle_pitch_rssi() {
 	pitch_rssi_enabled = !pitch_rssi_enabled;
 	
 	// Send to RSSI widget
@@ -51,7 +51,7 @@ void RecordView::toggle_pitch_rssi() {
 	} else {
 		button_pitch_rssi.set_foreground(Color::green());
 	}
-}
+}*/
 
 RecordView::RecordView(
 	const Rect parent_rect,
@@ -67,18 +67,18 @@ RecordView::RecordView(
 {
 	add_children({
 		&rect_background,
-		&button_pitch_rssi,
+		//&button_pitch_rssi,
 		&button_record,
 		&text_record_filename,
 		&text_record_dropped,
 		&text_time_available,
 	});
-
+	
 	rect_background.set_parent_rect({ { 0, 0 }, size() });
 	
-	button_pitch_rssi.on_select = [this](ImageButton&) {
+	/*button_pitch_rssi.on_select = [this](ImageButton&) {
 		this->toggle_pitch_rssi();
-	};
+	};*/
 
 	button_record.on_select = [this](ImageButton&) {
 		this->toggle();
@@ -100,7 +100,9 @@ void RecordView::focus() {
 void RecordView::set_sampling_rate(const size_t new_sampling_rate) {
 	if( new_sampling_rate != sampling_rate ) {
 		stop();
+		
 		sampling_rate = new_sampling_rate;
+		baseband::set_sample_rate(sampling_rate);
 
 		button_record.hidden(sampling_rate == 0);
 		text_record_filename.hidden(sampling_rate == 0);
@@ -214,7 +216,7 @@ Optional<File::Error> RecordView::write_metadata_file(const std::filesystem::pat
 	if( create_error.is_valid() ) {
 		return create_error;
 	} else {
-		const auto error_line1 = file.write_line("sample_rate=" + to_string_dec_uint(sampling_rate));
+		const auto error_line1 = file.write_line("sample_rate=" + to_string_dec_uint(sampling_rate / 8));
 		if( error_line1.is_valid() ) {
 			return error_line1;
 		}
@@ -237,13 +239,13 @@ void RecordView::update_status_display() {
 		text_record_dropped.set(s);
 	}
 	
-	if (pitch_rssi_enabled) {
+	/*if (pitch_rssi_enabled) {
 		button_pitch_rssi.invert_colors();
-	}
+	}*/
 
 	if( sampling_rate ) {
 		const auto space_info = std::filesystem::space(u"");
-		const uint32_t bytes_per_second = file_type == FileType::WAV ? (sampling_rate * 2) : (sampling_rate * 4);
+		const uint32_t bytes_per_second = file_type == FileType::WAV ? (sampling_rate * 2) : (sampling_rate / 8 * 4);
 		const uint32_t available_seconds = space_info.free / bytes_per_second;
 		const uint32_t seconds = available_seconds % 60;
 		const uint32_t available_minutes = available_seconds / 60;
diff --git a/firmware/application/ui_record_view.hpp b/firmware/application/ui_record_view.hpp
index 726035704f076ce0245fe14719e789168404e6be..d1911d1dfe38ba5df84736fec21d5afbe94aee12 100644
--- a/firmware/application/ui_record_view.hpp
+++ b/firmware/application/ui_record_view.hpp
@@ -64,7 +64,7 @@ public:
 
 private:
 	void toggle();
-	void toggle_pitch_rssi();
+	//void toggle_pitch_rssi();
 	Optional<File::Error> write_metadata_file(const std::filesystem::path& filename);
 
 	void on_tick_second();
@@ -73,7 +73,7 @@ private:
 	void handle_capture_thread_done(const File::Error error);
 	void handle_error(const File::Error error);
 
-	bool pitch_rssi_enabled = false;
+	//bool pitch_rssi_enabled = false;
 	const std::filesystem::path filename_stem_pattern;
 	const FileType file_type;
 	const size_t write_size;
@@ -85,15 +85,16 @@ private:
 		Color::black()
 	};
 	
-	ImageButton button_pitch_rssi {
+	/*ImageButton button_pitch_rssi {
 		{ 2, 0 * 16, 3 * 8, 1 * 16 },
 		&bitmap_rssipwm,
 		Color::orange(),
 		Color::black()
-	};
+	};*/
 
 	ImageButton button_record {
-		{ 4 * 8, 0 * 16, 2 * 8, 1 * 16 },
+		//{ 4 * 8, 0 * 16, 2 * 8, 1 * 16 },
+		{ 0 * 8, 0 * 16, 2 * 8, 1 * 16 },
 		&bitmap_record,
 		Color::red(),
 		Color::black()
diff --git a/firmware/baseband/proc_capture.cpp b/firmware/baseband/proc_capture.cpp
index 04edf70a7540b32db8fa16850251590871666bd2..1d50cd7ced8053ea3e32b01f5d164c36af314e04 100644
--- a/firmware/baseband/proc_capture.cpp
+++ b/firmware/baseband/proc_capture.cpp
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2016 Jared Boone, ShareBrained Technology, Inc.
+ * Copyright (C) 2018 Furrtek
  *
  * This file is part of PortaPack.
  *
@@ -28,23 +29,9 @@
 #include "utility.hpp"
 
 CaptureProcessor::CaptureProcessor() {
-	const auto& decim_0_filter = taps_200k_decim_0;
-	constexpr size_t decim_0_input_fs = baseband_fs;
-	constexpr size_t decim_0_output_fs = decim_0_input_fs / decim_0.decimation_factor;
-
-	const auto& decim_1_filter = taps_200k_decim_1;
-	constexpr size_t decim_1_input_fs = decim_0_output_fs;
-	constexpr size_t decim_1_output_fs = decim_1_input_fs / decim_1.decimation_factor;
-
-	decim_0.configure(decim_0_filter.taps, 33554432);
-	decim_1.configure(decim_1_filter.taps, 131072);
-
-	channel_filter_pass_f = decim_1_filter.pass_frequency_normalized * decim_1_input_fs;	// 162760.416666667
-	channel_filter_stop_f = decim_1_filter.stop_frequency_normalized * decim_1_input_fs;	// 337239.583333333
-
-	spectrum_interval_samples = decim_1_output_fs / spectrum_rate_hz;
-	spectrum_samples = 0;
-
+	decim_0.configure(taps_200k_decim_0.taps, 33554432);
+	decim_1.configure(taps_200k_decim_1.taps, 131072);
+	
 	channel_spectrum.set_decimation_factor(1);
 }
 
@@ -76,6 +63,10 @@ void CaptureProcessor::on_message(const Message* const message) {
 		channel_spectrum.on_message(message);
 		break;
 
+	case Message::ID::SamplerateConfig:
+		samplerate_config(*reinterpret_cast<const SamplerateConfigMessage*>(message));
+		break;
+	
 	case Message::ID::CaptureConfig:
 		capture_config(*reinterpret_cast<const CaptureConfigMessage*>(message));
 		break;
@@ -85,6 +76,22 @@ void CaptureProcessor::on_message(const Message* const message) {
 	}
 }
 
+void CaptureProcessor::samplerate_config(const SamplerateConfigMessage& message) {
+	baseband_fs = message.sample_rate;
+	baseband_thread.set_sampling_rate(baseband_fs);
+	
+	size_t decim_0_output_fs = baseband_fs / decim_0.decimation_factor;
+
+	size_t decim_1_input_fs = decim_0_output_fs;
+	size_t decim_1_output_fs = decim_1_input_fs / decim_1.decimation_factor;
+
+	channel_filter_pass_f = taps_200k_decim_1.pass_frequency_normalized * decim_1_input_fs;	// 162760.416666667
+	channel_filter_stop_f = taps_200k_decim_1.stop_frequency_normalized * decim_1_input_fs;	// 337239.583333333
+
+	spectrum_interval_samples = decim_1_output_fs / spectrum_rate_hz;
+	spectrum_samples = 0;
+}
+
 void CaptureProcessor::capture_config(const CaptureConfigMessage& message) {
 	if( message.config ) {
 		stream = std::make_unique<StreamInput>(message.config);
diff --git a/firmware/baseband/proc_capture.hpp b/firmware/baseband/proc_capture.hpp
index db0a2945ac1d5c1fda15919f45d52084bc04cded..9dd02d9b9ac8fc689c963e9a0a9568d4e2b9c976 100644
--- a/firmware/baseband/proc_capture.hpp
+++ b/firmware/baseband/proc_capture.hpp
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2016 Jared Boone, ShareBrained Technology, Inc.
+ * Copyright (C) 2018 Furrtek
  *
  * This file is part of PortaPack.
  *
@@ -45,7 +46,7 @@ public:
 
 private:
 	// TODO: Repeated value needs to be transmitted from application side.
-	static constexpr size_t baseband_fs = 4000000;
+	size_t baseband_fs = 0;
 	static constexpr auto spectrum_rate_hz = 50.0f;
 
 	BasebandThread baseband_thread { baseband_fs, this, NORMALPRIO + 20, baseband::Direction::Receive };
@@ -68,6 +69,7 @@ private:
 	size_t spectrum_interval_samples = 0;
 	size_t spectrum_samples = 0;
 
+	void samplerate_config(const SamplerateConfigMessage& message);
 	void capture_config(const CaptureConfigMessage& message);
 };
 
diff --git a/firmware/baseband/proc_replay.cpp b/firmware/baseband/proc_replay.cpp
index 3b8593b1dd37a4cbfac00c657f4e8af3ae4cc63b..edb934698adbe2a48f5fda1d99ca61df5e160434 100644
--- a/firmware/baseband/proc_replay.cpp
+++ b/firmware/baseband/proc_replay.cpp
@@ -32,7 +32,6 @@ ReplayProcessor::ReplayProcessor() {
 	channel_filter_pass_f = taps_200k_decim_1.pass_frequency_normalized * 1000000;	// 162760.416666667
 	channel_filter_stop_f = taps_200k_decim_1.stop_frequency_normalized * 1000000;	// 337239.583333333
 	
-	spectrum_interval_samples = baseband_fs / spectrum_rate_hz;
 	spectrum_samples = 0;
 
 	channel_spectrum.set_decimation_factor(1);
@@ -86,6 +85,10 @@ void ReplayProcessor::on_message(const Message* const message) {
 		channel_spectrum.on_message(message);
 		break;
 
+	case Message::ID::SamplerateConfig:
+		samplerate_config(*reinterpret_cast<const SamplerateConfigMessage*>(message));
+		break;
+	
 	case Message::ID::ReplayConfig:
 		configured = false;
 		bytes_read = 0;
@@ -102,8 +105,15 @@ void ReplayProcessor::on_message(const Message* const message) {
 	}
 }
 
+void ReplayProcessor::samplerate_config(const SamplerateConfigMessage& message) {
+	baseband_fs = message.sample_rate;
+	baseband_thread.set_sampling_rate(baseband_fs);
+	spectrum_interval_samples = baseband_fs / spectrum_rate_hz;
+}
+
 void ReplayProcessor::replay_config(const ReplayConfigMessage& message) {
 	if( message.config ) {
+		
 		stream = std::make_unique<StreamOutput>(message.config);
 		
 		// Tell application that the buffers and FIFO pointers are ready, prefill
diff --git a/firmware/baseband/proc_replay.hpp b/firmware/baseband/proc_replay.hpp
index 1ab220f7f4e3541248026355b936a225e1534bfd..9edb82f7331fd6c797c73ab6bb7c3e6106cd5e41 100644
--- a/firmware/baseband/proc_replay.hpp
+++ b/firmware/baseband/proc_replay.hpp
@@ -42,7 +42,7 @@ public:
 	void on_message(const Message* const message) override;
 
 private:
-	static constexpr size_t baseband_fs = 4000000;
+	size_t baseband_fs = 0;
 	static constexpr auto spectrum_rate_hz = 50.0f;
 
 	BasebandThread baseband_thread { baseband_fs, this, NORMALPRIO + 20, baseband::Direction::Transmit };
@@ -66,6 +66,7 @@ private:
 	bool configured { false };
 	uint32_t bytes_read { 0 };
 
+	void samplerate_config(const SamplerateConfigMessage& message);
 	void replay_config(const ReplayConfigMessage& message);
 	
 	TXProgressMessage txprogress_message { };
diff --git a/firmware/common/message.hpp b/firmware/common/message.hpp
index cf84823483b5072d17943ceaa434403a3f830641..be1d7e21294393bbbc40e95901aac6edfe18a3b2 100644
--- a/firmware/common/message.hpp
+++ b/firmware/common/message.hpp
@@ -75,6 +75,7 @@ public:
 		ReplayThreadDone = 21,
 		AFSKRxConfigure = 22,
 		StatusRefresh = 23,
+		SamplerateConfig = 24,
 
 		TXProgress = 30,
 		Retune = 31,
@@ -751,6 +752,18 @@ public:
 	uint32_t range = 0;
 };
 
+class SamplerateConfigMessage : public Message {
+public:
+	constexpr SamplerateConfigMessage(
+		const uint32_t sample_rate
+	) : Message { ID::SamplerateConfig },
+		sample_rate(sample_rate)
+	{
+	}
+	
+	const uint32_t sample_rate = 0;
+};
+
 class AudioLevelReportMessage : public Message {
 public:
 	constexpr AudioLevelReportMessage(
diff --git a/firmware/portapack-h1-havoc.bin b/firmware/portapack-h1-havoc.bin
index 927e2613b1234b7e402f31dacb52c796cd382f4a..8b44f7ca9e0784d9c2c29e4654ad4fa26e1ad71f 100644
Binary files a/firmware/portapack-h1-havoc.bin and b/firmware/portapack-h1-havoc.bin differ