diff --git a/source/ManchesterDecoder.cpp b/source/ManchesterDecoder.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..80c0be8de94b37f88780b216839805190b2fe06b
--- /dev/null
+++ b/source/ManchesterDecoder.cpp
@@ -0,0 +1,32 @@
+/**
+ * @file
+ *
+ * @brief Implementation of class ManchesterDecoder
+ *
+ * @author Joshua Saxby <Joshua2.Saxby@live.uwe.ac.uk>
+ * @date 2020
+ *
+ * Student Number 18018052
+ *
+ * @copyright Copyright (C) Joshua Saxby 2020
+ *
+ * @copyright
+ * 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 http://mozilla.org/MPL/2.0/.
+ */
+
+#include <cstdint> // uint8_t
+
+#include "ManchesterDecoder.hpp"
+
+
+// SAXBOPHONE.COM is my domain, so I'm using the reverse form as my namespace
+namespace com_saxbophone {
+    ManchesterDecoder::ManchesterDecoder()
+        {}
+
+    bool ManchesterDecoder::input(bool state) {}
+
+    bool ManchesterDecoder::get_next_byte(uint8_t& destination) {}
+};
diff --git a/source/ManchesterDecoder.hpp b/source/ManchesterDecoder.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..09a1b8ce60c9069102f6ad41d181888ba008a584
--- /dev/null
+++ b/source/ManchesterDecoder.hpp
@@ -0,0 +1,62 @@
+#ifndef COM_SAXBOPHONE_MANCHESTER_DECODER_HPP
+#define COM_SAXBOPHONE_MANCHESTER_DECODER_HPP
+
+/**
+ * @file
+ *
+ * @brief A simple class that performs Manchester Decoding of input line states.
+ *
+ * @details HI/LOW states are sent into the decoder with the input() method and
+ * decoded bytes are returned with the get_next_byte() method.
+ * Bytes are decoded in big-endian order, from a Manchester-encoded signal
+ * that conforms to that used in IEEE 802.3, that is, the clock cycles HI-LOW
+ * and output is Clock XOR Data. Thus, a HI-LOW transition indicates binary zero,
+ * whereas a LOW-HI transition indicates binary one.
+ *
+ * @author Joshua Saxby <Joshua2.Saxby@live.uwe.ac.uk>
+ * @date 2020
+ *
+ * Student Number 18018052
+ *
+ * @copyright Copyright (C) Joshua Saxby 2020
+ *
+ * @copyright
+ * 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 http://mozilla.org/MPL/2.0/.
+ */
+
+#include <cstdint> // uint8_t
+
+#include "CircularQueueBuffer.hpp"
+
+
+// SAXBOPHONE.COM is my domain, so I'm using the reverse form as my namespace
+namespace com_saxbophone {
+    class ManchesterDecoder {
+    public:
+        /**
+         * @brief Default constructor
+         */
+        ManchesterDecoder();
+
+        /**
+         * @brief Read in another state from the line to be decoded.
+         * @returns true if the state has been accepted
+         * @returns false if the state has not been accepted (buffer full)
+         */
+        bool input(bool state);
+
+        /**
+         * @brief Decodes the next byte from input (if available) and if there
+         * is a byte available, stores it in `destination`.
+         * @param destination[out] the byte to write the next decoded byte to
+         * @returns true if there was a byte available and it was stored
+         * @returns false if no bytes are available yet (destination is ignored)
+         */
+        bool get_next_byte(uint8_t& destination);
+    private:
+    };
+};
+
+#endif // include guard
diff --git a/source/ManchesterEncoder.cpp b/source/ManchesterEncoder.cpp
index b9d526386b974ccbe1ccf321125d881da9eec9dc..ad6681cd0835e8b94f3e4ce785275ebfb67577a9 100644
--- a/source/ManchesterEncoder.cpp
+++ b/source/ManchesterEncoder.cpp
@@ -59,7 +59,7 @@ namespace com_saxbophone {
 
     bool ManchesterEncoder::extract_bit(uint8_t byte, uint8_t bit_index) const {
         // NOTE: this is a big-endian extraction
-        uint8_t mask = 0x80 >> bit_index;
+        uint8_t mask = 0x80u >> bit_index;
         return (byte & mask); // no need to shift down, anything non-zero is true
     }
 };
diff --git a/tests/manchester_encoder_test.cpp b/tests/manchester_encoder_decoder_test.cpp
similarity index 71%
rename from tests/manchester_encoder_test.cpp
rename to tests/manchester_encoder_decoder_test.cpp
index 3ae4e962f27058696d669efc1a58262ba3e5cf4a..3b99a1de93f6cabbd62c7f3feb7d23c762ea9a4f 100644
--- a/tests/manchester_encoder_test.cpp
+++ b/tests/manchester_encoder_decoder_test.cpp
@@ -5,14 +5,13 @@
 #include <cstdint>
 #include <iostream>
 
+#include "../source/ManchesterDecoder.hpp"
 #include "../source/ManchesterEncoder.hpp"
 
 
 int main() {
     using namespace com_saxbophone;
 
-    ManchesterEncoder encoder;
-
     struct TestCase {
         uint8_t input; // byte being sent into the encoder
         bool output[16]; // sequence of HIGH/LOW states to be used as output
@@ -29,19 +28,27 @@ int main() {
     // test each test case
     for (TestCase t : test_cases) {
         ManchesterEncoder encoder;
+        ManchesterDecoder decoder;
+        std::cout << "Input:   \t" << std::hex << +t.input << std::endl;
         encoder.input(t.input);
         std::cout << "Expected:\t";
         for (size_t i = 0; i < 16; i++) {
-            // assert(encoder.get_next_state() == t.output[i]);
             std::cout << t.output[i];
         }
         std::cout << std::endl;
         std::cout << "Actual:  \t";
         for (size_t i = 0; i < 16; i++) {
             // assert(encoder.get_next_state() == t.output[i]);
-            std::cout << encoder.get_next_state();
+            bool state = encoder.get_next_state();
+            decoder.input(state);
+            std::cout << state;
         }
         std::cout << std::endl;
+        uint8_t decoded = 0xff;
+        decoder.get_next_byte(decoded);
+        std::cout << "Decoded: \t" << std::hex << +decoded << std::endl;
+        // draw a bar
+        std::cout << "================================" << std::endl;
     }
     return 0;
 }