diff --git a/csound-expression-typed.cabal b/csound-expression-typed.cabal
--- a/csound-expression-typed.cabal
+++ b/csound-expression-typed.cabal
@@ -1,5 +1,5 @@
 Name:          csound-expression-typed
-Version:       0.2.0.2
+Version:       0.2.1.0
 Cabal-Version: >= 1.22
 License:       BSD3
 License-file:  LICENSE
@@ -49,9 +49,9 @@
     data/opcodes/MultiFX/RingModulator.udo
     data/opcodes/MultiFX/StChorus.udo
     data/opcodes/MultiFX/StereoPingPongDelay.udo
+    data/opcodes/MultiFX/TapeEcho.udo
     data/opcodes/Utility/Delay1k.udo
 
-
 Homepage:        https://github.com/anton-k/csound-expression-typed
 Bug-Reports:     https://github.com/anton-k/csound-expression-typed/issues
 
@@ -126,6 +126,7 @@
     Csound.Typed.Misc
 
     Csound.Typed.Plugins.TabQueue
+    Csound.Typed.Plugins.TapeEcho
     Csound.Typed.Plugins.Zdf
     Csound.Typed.Plugins.Diode
     Csound.Typed.Plugins.Korg35
diff --git a/data/opcodes/MultiFX/TapeEcho.udo b/data/opcodes/MultiFX/TapeEcho.udo
new file mode 100644
--- /dev/null
+++ b/data/opcodes/MultiFX/TapeEcho.udo
@@ -0,0 +1,89 @@
+; Original research and code by Jon Downing  as in paper
+; Real-time digital modeling of the Roland Space Echo by Jon Downing, Christian Terjesen (ECE 472 - Audio Signal Processing, May 2016)
+;
+; Reimplemented in Csound by Anton Kholomiov
+
+; Error function approximation ~ 2% accuracy
+opcode ErrorFunApprox, a, a
+  aIn xin
+  kCoeff init ( (3.1415926535 ^ 0.5) * log(2) )
+  xout tanh(kCoeff * aIn)
+endop
+
+; Bandpass Chebyshev Type I filter
+opcode bandpassCheby1, a, akkii
+  aIn, kLowFreq, kHighFreq, iOrder, iRipple xin
+
+  aHigh clfilt aIn,   kLowFreq,  1, iOrder, 1, iRipple
+  aLow  clfilt aHigh, kHighFreq, 0, iOrder, 1, iRipple
+
+  xout aLow
+endop
+
+; Function to read from tape.
+;
+; tapeRead aIn, kDelay, kRandomSpread
+;
+; The function is used in the same manner as deltapi
+; first init the delay buffer and the use tapeRead.
+;
+; aIn - input signal
+; kDelay - delay time
+; kRandomSpread - [0, Inf] - the random spread of reading from the tape
+;    the higher the worser the quality of the tape.
+opcode tapeRead, a, akk
+  aIn, kDelay, kRandomSpread xin
+  iTauUp = 1.07
+  iTauDown = 1.89
+  aPrevDelay init 0.06
+  kOldDelay  init 0.06
+  kLambda init 0.5
+
+  kDelChange changed kDelay
+  if (kDelChange == 1) then
+    if (kOldDelay < kDelay) then
+      kLambda = exp(-1/(iTauUp*sr))
+    else
+      kLambda = exp(-1/(iTauDown*sr))
+    endif
+  endif
+
+  anoise noise kRandomSpread, 0
+  anoise = 3*(7.5 - aPrevDelay*(10^-3))*(10^-7)*anoise
+  anoiseMod butterlp anoise, 0.25  ; (0.5 / sr) * giNyquistFreq
+  aActualDelay = (1 - kLambda) * kDelay + kLambda * aPrevDelay + anoiseMod
+  aPrevDelay = aActualDelay
+                                         ; measured
+  aDelaySamps = aActualDelay * sr
+  aReadSr = floor(aDelaySamps)          ; in samples
+  aLastSr = aReadSr + 1                 ; in samples
+  aReadIndex = aReadSr / sr             ; in seconds
+  aLastIndex = aLastSr / sr             ; in seconds
+  aFrac = aDelaySamps - aReadSr
+  aFracScale = (1 - aFrac) * (1 + aFrac)
+
+  aReadSample deltapi aReadIndex
+  aLastSample deltapi aLastIndex
+
+  aEcho ErrorFunApprox (aLastSample + aFracScale * (aReadSample - aLastSample))
+
+  kOldDelay = kDelay
+  xout aEcho
+endop
+
+; function to write to tape
+;
+; tapeWrite aIn, aOut, kFbGain
+;
+; It should be though of as delayw for magnetic tape.
+;
+; aIn - input signal
+; aOut - output signal
+; kFbGain - gain of feedback [0, 2]
+opcode tapeWrite, 0, aak
+  aIn, aOut, kFbGain xin
+  iOrder    = 2
+  iRippleDb = 6
+  aProc bandpassCheby1 aOut * kFbGain, 95, 3000, iOrder, iRippleDb
+  delayw aIn + aProc * kFbGain
+endop
diff --git a/src/Csound/Typed/GlobalState/Elements.hs b/src/Csound/Typed/GlobalState/Elements.hs
--- a/src/Csound/Typed/GlobalState/Elements.hs
+++ b/src/Csound/Typed/GlobalState/Elements.hs
@@ -42,6 +42,7 @@
     analogDelayPlugin, distortionPlugin, envelopeFolollowerPlugin, flangerPlugin, freqShifterPlugin,
     loFiPlugin, panTremPlugin, monoTremPlugin, phaserPlugin, pitchShifterPlugin, reversePlugin,
     ringModulatorPlugin, stChorusPlugin, stereoPingPongDelayPlugin,
+    tapeEchoPlugin,
     delay1kPlugin,
 ) where
 
@@ -592,5 +593,7 @@
 ringModulatorPlugin = UdoPlugin "MultiFX/RingModulator"
 stChorusPlugin = UdoPlugin "MultiFX/StChorus"
 stereoPingPongDelayPlugin = UdoPlugin "MultiFX/StereoPingPongDelay"
+
+tapeEchoPlugin = UdoPlugin "MultiFX/TapeEcho"
 
 delay1kPlugin = UdoPlugin "Utility/Delay1k"
diff --git a/src/Csound/Typed/Plugins.hs b/src/Csound/Typed/Plugins.hs
--- a/src/Csound/Typed/Plugins.hs
+++ b/src/Csound/Typed/Plugins.hs
@@ -1,7 +1,7 @@
 module Csound.Typed.Plugins(
     adsr140,
     audaciousEq,
-    
+
     -- Solina chorus
     solinaChorus, testSolinaChorus,
 
@@ -12,10 +12,10 @@
     zdf2, zlp, zbp, zhp, zdf2_notch, zbr,
 
     -- Ladder filter
-    zladder, 
+    zladder,
 
     -- Four poles filters
-    zdf4, zlp4, zbp4, zhp4, 
+    zdf4, zlp4, zbp4, zhp4,
 
     -- Eq-filters
     peakEq, highShelf, lowShelf,
@@ -33,9 +33,12 @@
     pitchShifterDelay,
 
     -- Iain's fxs
-    fxAnalogDelay, fxDistortion, fxEnvelopeFollower, fxFlanger, fxFreqShifter, fxLoFi, 
+    fxAnalogDelay, fxDistortion, fxEnvelopeFollower, fxFlanger, fxFreqShifter, fxLoFi,
     fxPanTrem, fxMonoTrem, fxPhaser, fxPitchShifter, fxReverse, fxRingModulator, fxChorus2, fxPingPong,
 
+    -- * Tape echo
+    tapeRead, tapeWrite,
+
     -- utilities
     delay1k
 
@@ -49,4 +52,5 @@
 import Csound.Typed.Plugins.SolinaChorus
 import Csound.Typed.Plugins.ZeroDelayConvolution
 import Csound.Typed.Plugins.Iain
+import Csound.Typed.Plugins.TapeEcho
 import Csound.Typed.Plugins.Utilities
diff --git a/src/Csound/Typed/Plugins/Iain.hs b/src/Csound/Typed/Plugins/Iain.hs
--- a/src/Csound/Typed/Plugins/Iain.hs
+++ b/src/Csound/Typed/Plugins/Iain.hs
@@ -1,6 +1,6 @@
-module Csound.Typed.Plugins.Iain(  
+module Csound.Typed.Plugins.Iain(
     pitchShifterDelay,
-    fxAnalogDelay, fxDistortion, fxEnvelopeFollower, fxFlanger, fxFreqShifter, fxLoFi, 
+    fxAnalogDelay, fxDistortion, fxEnvelopeFollower, fxFlanger, fxFreqShifter, fxLoFi,
     fxPanTrem, fxMonoTrem, fxPhaser, fxPitchShifter, fxReverse, fxRingModulator, fxChorus2, fxPingPong
 ) where
 
@@ -12,7 +12,7 @@
 
 import Csound.Typed.Types
 import Csound.Typed.GlobalState
-import qualified Csound.Typed.GlobalState.Elements as E(pitchShifterDelayPlugin, 
+import qualified Csound.Typed.GlobalState.Elements as E(pitchShifterDelayPlugin,
     analogDelayPlugin, distortionPlugin, envelopeFolollowerPlugin, flangerPlugin, freqShifterPlugin,
     loFiPlugin, panTremPlugin, monoTremPlugin, phaserPlugin, pitchShifterPlugin, reversePlugin, ringModulatorPlugin, stChorusPlugin, stereoPingPongDelayPlugin)
 
@@ -33,10 +33,10 @@
 --; -----------
 --; ain     --  input audio to be pitch shifted
 --; ktrans  --  pitch transposition (in semitones)
---; kdlt    --  delay time employed by the pitch shifter effect (should be within the range ksmps/sr and imaxdlt) 
+--; kdlt    --  delay time employed by the pitch shifter effect (should be within the range ksmps/sr and imaxdlt)
 --; kFB1    --  feedback using method 1 (output from delay taps are fed back directly into their own buffers before enveloping and mixing)
 --; kFB2    --  feedback using method 2 (enveloped and mixed output from both taps is fed back into both buffers)
--- 
+--
 -- opcode  PitchShifterDelay,a,akkkki
 csdPitchShifterDelay :: Sig -> Sig -> Sig -> Sig -> Sig -> D -> Sig
 csdPitchShifterDelay ain ktrans kdlt kFB1 kFB2 imaxdlt = fromGE $ do
@@ -107,7 +107,7 @@
 -- ; kfreq  --  base frequency of the filter before modulation by the input dynamics (range: 0 to 1)
 -- ; kres   --  resonance of the lowpass filter (suggested range: 0 to 0.99)
 csdEnvelopeFollower :: Sig -> Sig -> Sig -> Sig -> Sig
-csdEnvelopeFollower ain ksens kfreq kres = fromGE $ do 
+csdEnvelopeFollower ain ksens kfreq kres = fromGE $ do
     addUdoPlugin E.envelopeFolollowerPlugin
     f <$> toGE ain <*> toGE ksens <*> toGE kfreq <*> toGE kres
     where f ain ksens kfreq kres = opcs "EnvelopeFollower" [(Ar,[Ar,Kr,Kr,Kr])] [ain, ksens, kfreq, kres]
@@ -162,7 +162,7 @@
 -- ; -----------
 -- ; ain    --  input audio to have low fidelity distortion effects applied
 -- ; kbits  --  bit depth reduction (suggested range 0 to 0.6)
--- ; kfold  --  amount of foldover (range 0 to 1)    
+-- ; kfold  --  amount of foldover (range 0 to 1)
 fxLoFi :: Sig -> Sig -> Sig -> Sig
 fxLoFi kbits kfold ain = fromGE $ do
     addUdoPlugin E.loFiPlugin
@@ -219,7 +219,7 @@
 -- ; krate  --  rate of lfo of the effect (range 0 to 1)
 -- ; kdepth --  depth of lfo of the effect (range 0 to 1)
 -- ; kfreq  --  centre frequency of the phase shifting effect in octaves (suggested range 6 to 11)
--- ; kfback --  feedback and therefore intensity of the effect (range 0 to 1)    
+-- ; kfback --  feedback and therefore intensity of the effect (range 0 to 1)
 fxPhaser :: Sig -> Sig -> Sig -> Sig -> Sig -> Sig
 fxPhaser krate kdepth kfreq kfback ain = fromGE $ do
     addUdoPlugin E.phaserPlugin
@@ -239,7 +239,7 @@
 -- ; kscal  -- pitch ratio
 -- #### ; kpitch --  pitch shifting interval in thousands of a semitone (suggested range -0.012 to 0.012)
 -- #### ; kfine  --  fine control of pitch shifting interval in octaves (range -1/12 to 1/12)
--- ; kfback --  control of the amount of output signal fed back into the input of the effect (suggested range 0 to 1)    
+-- ; kfback --  control of the amount of output signal fed back into the input of the effect (suggested range 0 to 1)
 fxPitchShifter :: D -> Sig -> Sig -> Sig -> Sig -> Sig
 fxPitchShifter ifftsize kmix kscal kfback ain = fromGE $ do
     addUdoPlugin E.pitchShifterPlugin
@@ -256,7 +256,7 @@
 -- ; Performance
 -- ; -----------
 -- ; ain    --  input audio to be reversed
--- ; ktime  --  time duration of each chunk (suggested range: 0.3 to 2)--     
+-- ; ktime  --  time duration of each chunk (suggested range: 0.3 to 2)--
 fxReverse :: Sig -> Sig -> Sig
 fxReverse ktime ain = fromGE $ do
     addUdoPlugin E.reversePlugin
@@ -297,8 +297,8 @@
 fxChorus2 :: Sig -> Sig -> Sig -> Sig2 -> Sig2
 fxChorus2 krate kdepth kwidth (ainL, ainR) = toTuple $ do
     addUdoPlugin E.stChorusPlugin
-    f <$> toGE ainL <*> toGE ainR <*> toGE krate <*> toGE kdepth <*> toGE kwidth 
-    where f ainL ainR krate kdepth kwidth = ($ 2) $ mopcs "StChorus" ([Ar,Ar], [Ar,Ar,Kr,Kr,Kr]) [ainL, ainR, krate, kdepth, kwidth] 
+    f <$> toGE ainL <*> toGE ainR <*> toGE krate <*> toGE kdepth <*> toGE kwidth
+    where f ainL ainR krate kdepth kwidth = ($ 2) $ mopcs "StChorus" ([Ar,Ar], [Ar,Ar,Kr,Kr,Kr]) [ainL, ainR, krate, kdepth, kwidth]
 
 -- aInL, aInR, kdelayTime, kFeedback, kMix, iMaxDelayTime xin
 
diff --git a/src/Csound/Typed/Plugins/TapeEcho.hs b/src/Csound/Typed/Plugins/TapeEcho.hs
new file mode 100644
--- /dev/null
+++ b/src/Csound/Typed/Plugins/TapeEcho.hs
@@ -0,0 +1,52 @@
+module Csound.Typed.Plugins.TapeEcho(
+    tapeRead
+  , tapeWrite
+) where
+
+import Control.Monad.Trans.Class
+import Control.Applicative
+
+import Csound.Dynamic
+
+import Csound.Typed.Types
+import Csound.Typed.GlobalState
+import qualified Csound.Typed.GlobalState.Elements as E(tapeEchoPlugin)
+
+--  Function to read from tape.
+--
+--  tapeRead aIn, kDelay, kRandomSpread
+--
+-- The function is used in the same manner as deltapi
+--  first init the delay buffer and the use tapeRead.
+--
+--  aIn - input signal
+--  kDelay - delay time
+--  kRandomSpread - [0, Inf] - the random spread of reading from the tape
+--     the higher the worser the quality of the tape.
+-- opcode tapeRead, a, akk
+tapeRead :: Sig -> Sig -> Sig -> SE Sig
+tapeRead ain kdel kRandomSpread = fmap (Sig . return) $ SE $ (depT =<<) $ lift $ do
+  addUdoPlugin E.tapeEchoPlugin
+  f <$> toGE ain <*> toGE kdel <*> toGE kRandomSpread
+  where f ain kdel krand = opcs "tapeRead" [(Ar, [Ar, Kr, Kr])] [ain, kdel, krand]
+
+
+-- function to write to tape
+--
+-- tapeWrite aIn, aOut, kFbGain
+--
+-- It should be though of as delayw for magnetic tape.
+--
+-- aIn - input signal
+-- aOut - output signal
+-- kFbGain - gain of feedback [0, 2]
+tapeWrite :: Sig -> Sig -> Sig -> SE ()
+tapeWrite ain aout kFeedback = SE $ (depT_ =<<) $ lift $ do
+  f <$> toGE ain <*> toGE aout <*> toGE kFeedback
+  where f ain aout kfb = opcs "tapeWrite" [(Xr, [Ar, Ar, Kr])] [ain, aout, kfb]
+
+{-
+addUdoPlugin E.pitchShifterDelayPlugin
+    f <$> toGE ain <*> toGE ktrans <*> toGE kdlt <*> toGE kFB1 <*> toGE kFB2 <*> toGE imaxdlt
+    where f ain ktrans kdlt kFB1 kFB2 imaxdlt = opcs "PitchShifterDelay" [(Ar, [Ar, Kr, Kr, Kr, Kr, Ir])] [ain, ktrans, kdlt, kFB1, kFB2, imaxdlt]
+-}
diff --git a/src/Csound/Typed/Plugins/Zdf.hs b/src/Csound/Typed/Plugins/Zdf.hs
--- a/src/Csound/Typed/Plugins/Zdf.hs
+++ b/src/Csound/Typed/Plugins/Zdf.hs
@@ -1,5 +1,5 @@
 -- Zero delay filters (implemented in Csound by Steven Yi)
-module Csound.Typed.Plugins.Zdf( 
+module Csound.Typed.Plugins.Zdf(
     -- One pole filters
     zdf1, zlp1, zhp1, zap1,
 
@@ -7,13 +7,13 @@
     zdf2, zlp, zbp, zhp, zdf2_notch, zbr,
 
     -- Ladder filter
-    zladder, 
+    zladder,
 
     -- Four poles filters
-    zdf4, zlp4, zbp4, zhp4, 
+    zdf4, zlp4, zbp4, zhp4,
 
     -- Eq-filters
-    peakEq, highShelf, lowShelf   
+    peakEq, highShelf, lowShelf
 ) where
 
 import Data.Boolean
@@ -74,22 +74,22 @@
 -- ladder
 
 zladder :: Sig -> Sig -> Sig -> Sig
-zladder cfq q asig = zdf_ladder asig cfq q 
+zladder cfq q asig = zdf_ladder asig cfq q
 
 -- zdf_4pole
 
 zdf4 ::  Sig -> Sig -> Sig -> (Sig, Sig, Sig, Sig, Sig, Sig)
 zdf4 cfq q asig = zdf_4pole asig cfq q
 
-zlp4 ::  Sig -> Sig -> Sig -> Sig 
+zlp4 ::  Sig -> Sig -> Sig -> Sig
 zlp4 cfq q asig = lows
     where (_, _, _, lows, _, _) = zdf4 cfq q asig
 
-zbp4 ::  Sig -> Sig -> Sig -> Sig 
+zbp4 ::  Sig -> Sig -> Sig -> Sig
 zbp4 cfq q asig = mids
     where (_, _, _, _, mids, _) = zdf4 cfq q asig
 
-zhp4 ::  Sig -> Sig -> Sig -> Sig  
+zhp4 ::  Sig -> Sig -> Sig -> Sig
 zhp4 cfq q asig = highs
     where (_, _, _, _, _, highs) = zdf4 cfq q asig
 
@@ -103,7 +103,7 @@
 
 -- zdf_low_shelf_eq
 lowShelf :: Sig -> Sig -> Sig -> Sig
-lowShelf kcf kres ain = zdf_low_shelf_eq ain kcf kres 
+lowShelf kcf kres ain = zdf_low_shelf_eq ain kcf kres
 
 -------------------------------------------------------------------------------
 -- Steven implementation
