diff --git a/dcs/frames/ch06_down_sampling.py b/dcs/frames/ch06_down_sampling.py
new file mode 100644
index 0000000..acd0f2f
--- /dev/null
+++ b/dcs/frames/ch06_down_sampling.py
@@ -0,0 +1,321 @@
+#  SPDX-License-Identifier: MPL-2.0
+#    Copyright (c) 2022 Philipp Le <philipp@philipple.de>.
+#  This Source Code Form is subject to the terms of the Mozilla Public
+#  License, v. 2.0. If a copy of the MPL was not distributed with this
+#  file, You can obtain one at https://mozilla.org/MPL/2.0/.
+
+from __future__ import annotations
+
+from tkinter import ttk, LEFT, BOTH, BOTTOM
+from pydantic import confloat, conint
+from dcs.config import default_store, ConfigObject, ui_create, ConfigControlFrame
+import numpy as np
+import scipy.signal
+from scipy.interpolate import make_interp_spline
+from dcs.frames.base import BaseFrame, Window
+from dcs.frames.groups import Ch06Group
+from dcs.utils import swap_freq, abs_log_fft
+from typing import List, Tuple
+
+import matplotlib
+matplotlib.use('TkAgg')
+from matplotlib.figure import Figure
+from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk
+
+
+OVERSAMPLING_LEN = 512
+FFT_LEN = 2048
+
+
+@ui_create
+class Function(ConfigObject):
+    freq: confloat(ge=0, lt=OVERSAMPLING_LEN/2, multiple_of=(4.0/OVERSAMPLING_LEN)) = 1.0
+    amplitude: confloat(ge=0.0, lt=10.0, multiple_of=0.01) = 5.0
+    phase: confloat(ge=-180.0, le=180.0, multiple_of=0.1) = 0.0
+    offset: confloat(ge=-5.0, lt=5.0, multiple_of=0.01) = 0.0
+
+    def make_config_widget(self, parent: ttk.Widget) -> ConfigControlFrame:
+        frm = ConfigControlFrame(parent)
+
+        ttk.Label(frm, text='Frequency:').grid(row=0, column=0)
+        w = self.ui_create_freq(frm)
+        frm.add_widget(w)
+        w.grid(row=0, column=1)
+
+        ttk.Label(frm, text='Amplitude:').grid(row=1, column=0)
+        w = self.ui_create_amplitude(frm)
+        frm.add_widget(w)
+        w.grid(row=1, column=1)
+
+        ttk.Label(frm, text='Phase:').grid(row=2, column=0)
+        w = self.ui_create_phase(frm)
+        frm.add_widget(w)
+        w.grid(row=2, column=1)
+        ttk.Label(frm, text='°').grid(row=2, column=2)
+
+        ttk.Label(frm, text='Offset:').grid(row=3, column=0)
+        w = self.ui_create_offset(frm)
+        frm.add_widget(w)
+        w.grid(row=3, column=1)
+
+        return frm
+
+    def calc_signal(self, t: np.ndarray) -> np.ndarray:
+        phasor = self.amplitude * np.exp(1j * self.phase * np.pi / 180)
+        phi = np.exp(1j * 2 * np.pi * self.freq * t)
+        return np.real(self.offset + (phasor * phi))
+
+    def make_title(self):
+        return f'f={self.freq}, {self.amplitude}, {self.phase}°'
+
+
+@ui_create
+class ConfigCh06DownSampling(ConfigObject):
+    _KEY = 'ch06_down_sampling'
+
+    input_funcs: List[Function] = [
+        Function(freq=1.0, amplitude_dB=0.0, phase=0.0),
+        Function(freq=1.5, amplitude_dB=0.0, phase=90.0),
+    ]
+    sample_rate: confloat(ge=0, lt=OVERSAMPLING_LEN/2, multiple_of=(4.0/OVERSAMPLING_LEN)) = 16.0
+    decimation: conint(ge=0, lt=64) = 4
+    lp_cutoff_freq: confloat(ge=0, lt=OVERSAMPLING_LEN/2, multiple_of=(4.0/OVERSAMPLING_LEN)) = 4.0
+
+    def make_config_widget(self, parent: ttk.Widget) -> ConfigControlFrame:
+        frm = ConfigControlFrame(parent, borderwidth=1, relief='raised')
+
+        ttk.Label(frm, text='Input Functions:').pack()
+        w = self.ui_create_input_funcs_list(frm, lambda e: e.make_title())
+        frm.add_widget(w)
+        w.pack()
+
+        frm1 = ttk.Frame(frm, borderwidth=1, relief='raised')
+        frm1.pack()
+
+        ttk.Label(frm1, text='Sample Rate:').grid(row=0, column=0)
+        w = self.ui_create_sample_rate(frm1)
+        frm.add_widget(w)
+        w.grid(row=0, column=1)
+
+        ttk.Label(frm1, text='Decimation Factor:').grid(row=1, column=0)
+        w = self.ui_create_decimation(frm1)
+        frm.add_widget(w)
+        w.grid(row=1, column=1)
+
+        ttk.Label(frm1, text='Anti-Aliasing Low Pass Cut-off:').grid(row=2, column=0)
+        ttk.Label(frm1, text='(0 = disable):').grid(row=3, column=1)
+        w = self.ui_create_lp_cutoff_freq(frm1)
+        frm.add_widget(w)
+        w.grid(row=2, column=1)
+
+        return frm
+
+    def have_filter(self) -> bool:
+        return not (self.lp_cutoff_freq == 0)
+
+    def _decimate_vec(self, vec: np.ndarray) -> np.ndarray:
+        return np.array([vec[idx] for idx in range(0, len(vec), self.decimation)])
+
+    def calc_input_signal(self, t: np.ndarray) -> np.ndarray:
+        x = np.zeros((len(self.input_funcs), len(t)), dtype=np.float64)
+        for index, func in enumerate(self.input_funcs):
+            x[index, :] = func.calc_signal(t)
+        return np.sum(x, axis=0)
+
+    def calc_decimated_bypassed_signal(self, t: np.ndarray) -> Tuple[np.ndarray, np.ndarray]:
+        sig = self.calc_input_signal(t)
+        return self._decimate_vec(t), self._decimate_vec(sig)
+
+    def calc_filtered_signal(self, t: np.ndarray) -> np.ndarray:
+        inp = self.calc_input_signal(t)
+
+        if self.have_filter():
+            b, a = scipy.signal.cheby1(N=5, Wn=self.lp_cutoff_freq, rp=1, btype='low', fs=self.sample_rate)
+            zi = scipy.signal.lfilter_zi(b, a)
+            z, _ = scipy.signal.lfilter(b, a, inp, zi=zi*inp[0])
+            return z
+        else:
+            return inp
+
+    def calc_decimated_signal(self, t: np.ndarray) -> Tuple[np.ndarray, np.ndarray]:
+        sig = self.calc_filtered_signal(t)
+        return self._decimate_vec(t), self._decimate_vec(sig)
+
+
+class Ch06DownSamplingFrame(BaseFrame):
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+
+        self._config: ConfigCh06DownSampling = default_store().get_config(ConfigCh06DownSampling)
+
+        ctrl_frm = self._create_control()
+        ctrl_frm.pack(side=LEFT)
+
+        signal_frm = self._create_signal_tabs()
+        signal_frm.pack(expand=True, fill=BOTH)
+
+    def _create_control(self) -> ConfigControlFrame:
+        frm = self._config.make_config_widget(self)
+        frm.widgets_on_change(self._on_change)
+        return frm
+
+    def _on_change(self, _, __, ___):
+        default_store().save()
+        self.draw_td()
+        self.draw_fd()
+
+    def _create_signal_tabs(self) -> ttk.Widget:
+        tabs = ttk.Notebook(self)
+
+        td_frm = ttk.Frame(tabs)
+        tabs.add(td_frm, text='Time Domain')
+        self._td_fig = Figure(figsize=(12, 6), dpi=100)
+        self._td_canvas = FigureCanvasTkAgg(self._td_fig, td_frm)
+        self._td_canvas.get_tk_widget().pack(expand=True, fill=BOTH)
+        td_tb = NavigationToolbar2Tk(self._td_canvas, td_frm, pack_toolbar=False)
+        td_tb.pack(side=BOTTOM)
+
+        fd_frm = ttk.Frame(tabs)
+        tabs.add(fd_frm, text='Frequency Domain')
+        self._fd_fig = Figure(figsize=(12, 6), dpi=100)
+        self._fd_canvas = FigureCanvasTkAgg(self._fd_fig, fd_frm)
+        self._fd_canvas.get_tk_widget().pack(expand=True, fill=BOTH)
+        fd_tb = NavigationToolbar2Tk(self._fd_canvas, fd_frm, pack_toolbar=False)
+        fd_tb.pack(side=BOTTOM)
+
+        self.draw_td()
+        self.draw_fd()
+
+        return tabs
+
+    def draw_td(self):
+        self._td_fig.clear()
+
+        if self._config.have_filter():
+            ax_inp = self._td_fig.add_subplot(3, 1, 1)
+        else:
+            ax_inp = self._td_fig.add_subplot(2, 1, 1)
+        ax_inp.set_xlim(0.0, 1.1)
+        ax_inp.set_xlabel('time')
+        ax_inp.set_ylabel('value')
+        ax_inp.set_title('Input Signal')
+        if self._config.have_filter():
+            ax_flt = self._td_fig.add_subplot(3, 1, 2)
+            ax_flt.set_xlim(0.0, 1.1)
+            ax_flt.set_xlabel('time')
+            ax_flt.set_ylabel('value')
+            ax_flt.set_title('Signal After Anti-Aliasing Filter')
+            ax_dec = self._td_fig.add_subplot(3, 1, 3)
+        else:
+            ax_dec = self._td_fig.add_subplot(2, 1, 2)
+        ax_dec.set_xlim(0.0, 1.1)
+        ax_dec.set_xlabel('time')
+        ax_dec.set_ylabel('value')
+        ax_dec.set_title('Decimated Signal')
+
+        t = np.arange(0, 1.1, 1.0/self._config.sample_rate)
+        if len(t) > 3:
+            t_interp = np.linspace(np.min(t), np.max(t), OVERSAMPLING_LEN)
+        else:
+            t_interp = np.zeros((0,))
+
+        x_inp = self._config.calc_input_signal(t)
+        t_inp_dec, x_inp_dec = self._config.calc_decimated_bypassed_signal(t)
+        if len(t) > 3:
+            fn_inp_interp = make_interp_spline(t, x_inp)
+            x_inp_interp = fn_inp_interp(t_interp)
+        else:
+            x_inp_interp = np.zeros((0,))
+
+        if self._config.have_filter():
+            x_flt = self._config.calc_filtered_signal(t)
+            if len(t) > 3:
+                fn_flt_interp = make_interp_spline(t, x_flt)
+                x_flt_interp = fn_flt_interp(t_interp)
+            else:
+                x_flt_interp = np.zeros((0,))
+
+        t_dec, x_dec = self._config.calc_decimated_signal(t)
+        if len(t) > 3:
+            fn_dec_interp = make_interp_spline(t_dec, x_dec)
+            x_dec_interp = fn_dec_interp(t_interp)
+        else:
+            x_dec_interp = np.zeros((0,))
+
+        ax_inp.plot(t_inp_dec, x_inp_dec, label='Input Signal (Decimated)', marker='o', linestyle='none', color='red', linewidth=1)
+        ax_inp.plot(t, x_inp, label='Input Signal (Sampled)', marker='x', linestyle='none', color='blue', linewidth=1)
+        ax_inp.plot(t_interp, x_inp_interp, label='Input Signal (Interpolated)', linestyle='dashed', color='blue', linewidth=1)
+        ax_inp.legend()
+
+        if self._config.have_filter():
+            ax_flt.plot(t_dec, x_dec, label='Filtered Signal (Decimated)', marker='o', linestyle='none', color='red', linewidth=1)
+            ax_flt.plot(t, x_flt, label='Filtered Signal (Sampled)', marker='x', linestyle='none', color='green', linewidth=1)
+            ax_flt.plot(t_interp, x_flt_interp, label='Filtered Signal (Interpolated)', linestyle='dashed', color='green', linewidth=1)
+            ax_flt.legend()
+
+        ax_dec.plot(t_dec, x_dec, label='Decimated Signal (Sampled)', marker='x', linestyle='none', color='red', linewidth=1)
+        ax_dec.plot(t_interp, x_dec_interp, label='Decimated Signal (Interpolated)', linestyle='dashed', color='red', linewidth=1)
+        ax_dec.legend()
+
+        self._td_fig.tight_layout()
+        self._td_canvas.draw()
+
+    def draw_fd(self):
+        self._fd_fig.clear()
+
+        if self._config.have_filter():
+            ax_inp = self._fd_fig.add_subplot(3, 1, 1)
+        else:
+            ax_inp = self._fd_fig.add_subplot(2, 1, 1)
+        ax_inp.set_xlim(-self._config.sample_rate/2, self._config.sample_rate/2)
+        ax_inp.set_xlabel('frequency')
+        ax_inp.set_ylabel('value (dB)')
+        ax_inp.set_title('Input Signal')
+        if self._config.have_filter():
+            ax_flt = self._fd_fig.add_subplot(3, 1, 2)
+            ax_flt.set_xlim(-self._config.sample_rate/2, self._config.sample_rate/2)
+            ax_flt.set_xlabel('frequency')
+            ax_flt.set_ylabel('value (dB)')
+            ax_flt.set_title('Signal After Anti-Aliasing Filter')
+            ax_dec = self._fd_fig.add_subplot(3, 1, 3)
+        else:
+            ax_dec = self._fd_fig.add_subplot(2, 1, 2)
+        ax_dec.set_xlim(-self._config.sample_rate/(self._config.decimation * 2), self._config.sample_rate/(self._config.decimation * 2))
+        ax_dec.set_xlabel('frequency')
+        ax_dec.set_ylabel('value (dB)')
+        ax_dec.set_title('Decimated Signal')
+
+        t = np.arange(0, FFT_LEN, 1) / self._config.sample_rate
+        f = swap_freq(np.fft.fftfreq(t.shape[-1], 1.0/self._config.sample_rate))
+
+        x_inp = self._config.calc_input_signal(t)
+
+        if self._config.have_filter():
+            x_flt = self._config.calc_filtered_signal(t)
+
+        t_dec, x_dec = self._config.calc_decimated_signal(t)
+        f_dec = swap_freq(np.fft.fftfreq(t_dec.shape[-1], 1.0 * self._config.decimation / self._config.sample_rate))
+
+        ax_inp.plot(f, abs_log_fft(x_inp), label='Input Signal', linestyle='solid', color='blue', linewidth=1)
+        ax_inp.legend()
+
+        if self._config.have_filter():
+            ax_flt.plot(f, abs_log_fft(x_flt), label='Filtered Signal', linestyle='solid', color='green', linewidth=1)
+            ax_flt.legend()
+
+        ax_dec.plot(f_dec, abs_log_fft(x_dec), label='Decimated Signal', linestyle='solid', color='red', linewidth=1)
+        ax_dec.legend()
+
+        self._fd_fig.tight_layout()
+        self._fd_canvas.draw()
+
+
+class Ch06DownSamplingWindow(Window):
+    GROUP = Ch06Group
+    TITLE = 'Down Sampling'
+    FRAME = Ch06DownSamplingFrame
+
+
+if __name__ == '__main__':
+    Ch06DownSamplingWindow.main()
+
