diff --git a/guitfx.c b/guitfx.c
index 02f8a12..4ab88e1 100644
--- a/guitfx.c
+++ b/guitfx.c
@@ -14,7 +14,9 @@
 #include <pipewire/filter.h>
 
 #include "delay.h"
+#include "sust.h"
 
+float envelope( float x );
 struct data;
 
 struct port {
@@ -31,6 +33,7 @@ struct data {
 	//! effect data
 	uint64_t last_tap;
 	struct delay delay;
+	struct sust sust;
 
 	//! elapsed time in number of samples
 	uint64_t time;
@@ -90,7 +93,17 @@ static void on_process(void *userdata, struct spa_io_position *position)
 
 								    case 0x42:
 										// sust pedal
+										if( midi_data[2] >= 64) {
+											sust_swap( &data->sust );
+										    data->sust.playing = true;
 
+											data->sust.start_idx = data->sust.idx;
+											data->sust.idx = 0;
+										} else {
+											data->sust.playing = false;
+										}
+
+										// tap tempo
    									    uint64_t cur_tap = frame + c->offset;
     									uint64_t duration = cur_tap - data->last_tap;
     									data->last_tap = cur_tap;
@@ -126,7 +139,8 @@ static void on_process(void *userdata, struct spa_io_position *position)
 	float * const in = pw_filter_get_dsp_buffer(data->guit_in_port, n_samples);
 	float * out = pw_filter_get_dsp_buffer(data->out_port, n_samples);
 	if( in && out ) {
-        delay_process( &data->delay, n_samples, in, out );
+        //delay_process( &data->delay, n_samples, in, out );
+        sust_process( &data->sust, n_samples, in, out );
 	}
 }
 
@@ -146,6 +160,7 @@ int main(int argc, char *argv[])
 	struct data data = { 0, };
 
 	delay_init( &data.delay );
+	sust_init( &data.sust );
 
 	const struct spa_pod *params[1];
 	uint8_t buffer[1024];
diff --git a/meson.build b/meson.build
index 5f61c36..9fc0dd8 100644
--- a/meson.build
+++ b/meson.build
@@ -1,8 +1,13 @@
 project('guitfx', 'c')
 pipewire_dep = dependency('libpipewire-0.3')
+
+cc = meson.get_compiler('c')
+m_dep = cc.find_library('m', required : false)
+
 executable(
     'guitfx',
     'guitfx.c',
     'delay.c',
-    dependencies : [pipewire_dep],
+    'sust.c',
+    dependencies : [pipewire_dep, m_dep],
 )
diff --git a/sust.c b/sust.c
new file mode 100644
index 0000000..c836b2a
--- /dev/null
+++ b/sust.c
@@ -0,0 +1,80 @@
+#include "sust.h"
+#include <math.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+void sust_init( struct sust * sust ) {
+    sust->mode = MODE_Sostenuto;
+
+    sust->playing = false;
+
+    sust->start_idx = 0;
+    sust->idx = 0;
+
+    sust->buf_len = 12800;
+    sust->record_buf = malloc( sizeof(float) * sust->buf_len );
+    sust->play_buf = malloc( sizeof(float) * sust->buf_len );
+}
+
+float envelope( float x ) {
+    if( x < 0.4 )
+        return (x / 0.4) * (x / 0.4);
+    if( x < 0.6 )
+        return 1.0;
+
+   float v  = 1.0 - ((x - 0.6) / 0.4);
+   return v*v;
+}
+
+float softcos( float x ) {
+    return sin( x * (3.141 / 2.0) );
+}
+
+void sust_swap(
+    struct sust * sust
+) {
+    float * tmp = sust->play_buf;
+    sust->play_buf = sust->record_buf;
+    sust->record_buf = tmp;
+
+    for( int i = 0; i  < sust->buf_len; ++i ) {
+        sust->record_buf[i] = sust->play_buf[i];
+    }
+}
+
+void sust_process(
+    struct sust * sust,
+    size_t frame_size,
+    float const * in,
+    float * out
+) {
+    for( size_t i = 0; i < frame_size; ++i ) {
+
+        if( sust->mode == MODE_Sustain && sust->idx == 0 ) {
+            sust_swap( sust );
+        }
+
+        float out_value = in[i];
+
+        if( sust->playing ) {
+            int n_voices = 5;
+
+            for( int v = 0; v < n_voices; ++v ) {
+                size_t play_idx = (sust->start_idx + sust->idx + ((v*sust->buf_len)/n_voices)) % sust->buf_len;
+                float gain = envelope( ((float) play_idx) / ((float)sust->buf_len) );
+               //printf("gain = %f\n", gain);
+                out_value += 0.5 *gain * sust->play_buf[ play_idx ];
+            }
+        }
+
+        if( sust->mode == MODE_Sostenuto ) {
+            sust->record_buf[ sust->idx ] = in[i];
+        }
+        if( sust->mode == MODE_Sustain ) {
+            sust->record_buf[ sust->idx ] = 0.5*out_value;
+        }
+
+        sust->idx = (sust->idx + 1) % sust->buf_len;
+        out[i] = out_value;
+    }
+}
diff --git a/sust.h b/sust.h
new file mode 100644
index 0000000..23c6f67
--- /dev/null
+++ b/sust.h
@@ -0,0 +1,31 @@
+#pragma once
+
+#include <stdbool.h>
+#include <stddef.h>
+
+enum sust_mode {
+    MODE_Sustain = 0,
+    MODE_Sostenuto = 1
+};
+
+struct sust {
+    enum sust_mode mode;
+    bool playing;
+
+    size_t start_idx;
+    size_t idx;
+    size_t buf_len;
+    float * record_buf;
+    float * play_buf;
+};
+
+
+void sust_init( struct sust * sust );
+void sust_swap( struct sust * sust );
+
+void sust_process(
+    struct sust * sust,
+    size_t frame_size,
+    float const * in,
+    float * out
+);