diff --git a/code/daisy-looper/button_grid.h b/code/daisy-looper/button_grid.h
index 4a7ddcf2a5b637d5dd418225f439bc9f2bba4793..eba3a9faebc209e55662b792648661063df4ea08 100644
--- a/code/daisy-looper/button_grid.h
+++ b/code/daisy-looper/button_grid.h
@@ -112,6 +112,7 @@ class ButtonGrid {
           return i;
         }
       }
+      return -1;
     }
 
     void hideAllDescriptions() {
diff --git a/code/daisy-looper/daisy-looper.ino b/code/daisy-looper/daisy-looper.ino
index 24a57a3f4449de55f582de009d0574695cce2c10..2d84ecbeed826e5a178d33c8c905747b6de3ff8b 100644
--- a/code/daisy-looper/daisy-looper.ino
+++ b/code/daisy-looper/daisy-looper.ino
@@ -93,7 +93,11 @@ void AudioCallback(float **in, float **out, size_t size) {
   for (size_t i = 0; i < size; i++) {
     uint8_t trig = tick.Process();
     float lfo_value = lfo.Process();
-    float rand = sample_and_hold.Process(trig, noise.Process() * 5.0f, sample_and_hold.MODE_SAMPLE_HOLD);
+    float noise_value = noise.Process();
+    float rand = sample_and_hold.Process(trig, noise_value * 5.0f, sample_and_hold.MODE_SAMPLE_HOLD);
+    if (ui.rec_source == REC_SOURCE_NOISE) {
+     looper.Record(noise_value * 0.7f);
+    }
     // When the metro ticks, trigger the envelope to start.
     float random_amount = (lfo_amount -0.5f) * 2.0;
     if (trig) {
@@ -109,25 +113,44 @@ void AudioCallback(float **in, float **out, size_t size) {
     } else {
       looper.setPlaybackSpeed(pitch_val + lfo_value * lfo_amount);
     }
+
+    float looper_out;
     
     // res.SetDamping(0.1+delaymix*0.2f);
-    auto looper_out = looper.Process(in[1][i]);
-
-    // 
+    // Record into the buffer
+    if (ui.rec_source == REC_SOURCE_PRE) {
+     looper.Record(in[1][i]);
+    }
+    
     input_envelope_follower.Process(in[1][i]);
+
+    // Process the Looper
+    looper_out = looper.Process();
+
+    // Mix the dry/Wet of the looper
     output = drywetmix * looper_out + in[1][i] * (1.0f - drywetmix);
+    
     // output = output * (1.0f - resmix) + res.Process(output*resmix);
     no_delay = output;
     wet_delay = delayline.Read();
     delayline.Write((wet_delay * delaymix * 0.95f)/2.0f + (no_delay*delaymix)/2.0f);
 
+    // Add the delay
     output += wet_delay * delaymix;
+
+    // Compress the signal
     compressor.Process(output);
 
     // Process reverb
     reverb.Process(output, output, &out1, &out2);
+
     // Mix reverb with the dry signal depending on the amount dialed
     output = output * (1.0f - reverbmix) + out1 * reverbmix;
+
+    // Record the output if needed
+    if (ui.rec_source == REC_SOURCE_OUT) {
+     looper.Record(output);
+    }
     
     out[0][i] = out[1][i] = output;
   }
diff --git a/code/daisy-looper/looper.h b/code/daisy-looper/looper.h
index adfe56c02f25486113a5ccc908bb568f767831f4..770f9d1b39d4811ca9382692553746549d9446a3 100644
--- a/code/daisy-looper/looper.h
+++ b/code/daisy-looper/looper.h
@@ -76,7 +76,7 @@ class Looper {
       is_loop_set = true;
     }
   
-    float Process(float in) {
+    void Record(float in) {
       // Calculate iterator position on the record level ramp.
       if (rec_env_pos_inc > 0 && rec_env_pos < kFadeLength
        || rec_env_pos_inc < 0 && rec_env_pos > 0) {
@@ -132,12 +132,15 @@ class Looper {
         }
         
       }
-      
+    }
+
+    float Process() {
+      // Early return if the buffer is empty
       if (is_empty) {
         return 0;
       }
 
-      // Playback from the buffer
+      // Variables for the Playback from the Buffer
       float attenuation = 1;
       float output = 0;
 
@@ -149,13 +152,16 @@ class Looper {
         attenuation = static_cast<float>(loop_length - play_head) / static_cast<float>(kFadeLength);
       }
       
-      // Read from the buffer
+      // Ensure we are actually inside the buffer
       auto play_pos = int(loop_start + play_head) % buffer_length;
+
+      // Read from the buffer
       output = buffer[play_pos] * attenuation;
 
-      // Advance playhead
+      // Advance playhead by the increment
       play_head += playback_increment;
-      // Ensure the playhead stays within bounds
+
+      // Ensure the playhead stays within bounds of the loop
       if (play_head >= loop_length) {
         loop_start = pending_loop_start;
         loop_length = pendingloop_length;
@@ -166,7 +172,7 @@ class Looper {
         play_head = loop_length;
       }
       
-      
+      // Return the attenuated signal
       return output * attenuation;
     }
 
diff --git a/code/daisy-looper/ui.h b/code/daisy-looper/ui.h
index c26f25cbc11b35377551edf5cb6022e22b20893f..ccb239862183298aebb73a87da6ed11a7db8ff00 100644
--- a/code/daisy-looper/ui.h
+++ b/code/daisy-looper/ui.h
@@ -50,6 +50,15 @@ enum RecMode {
   REC_MODE_LAST
 };
 
+// Represents possible recording sources
+enum RecSource {
+  REC_SOURCE_PRE,            // Record Incoming audio
+  REC_SOURCE_POST,           // Record effects
+  REC_SOURCE_OUT,            // Record the buffer output
+  REC_SOURCE_NOISE,          // Record Noise
+  REC_SOURCE_LAST
+};
+
 // Represents possible playback modes
 enum PlayMode {
   PLAY_MODE_DRUNK,        // Drunken Walk
@@ -114,9 +123,12 @@ class Ui {
     // Stores the current Ui Mode
     UiMode ui_mode = UI_MODE_SPLASH;
 
-    // RecMode rec_mode = REC_MODE_FULL;
+    // Default Recording Mode
     RecMode rec_mode = REC_MODE_LOOP;
 
+    // Default Recording Source
+    RecSource rec_source = REC_SOURCE_PRE;
+
     // Set the mode of the UI (and thus change the screen)
     void setMode(UiMode mode) {
       if (last_ui_mode == mode) { return; }
@@ -282,9 +294,9 @@ class Ui {
         
         // Set Recording Source (Pre/Post/Out/Noise)
         button_3.onPress([this, n](){
-          // TODO: Implement Pre/Post/Out Recording
           button_grids[n].grid_buttons_[2].next();
-        }); // FULL ONESHOT
+          rec_source = (RecSource) button_grids[n].grid_buttons_[2].active;
+        }); 
 
         // Switch Recording modes (Full/Loop/Oneshot)
         button_4.onPress([this, n](){