add_karplus_strong_drum Subroutine

public subroutine add_karplus_strong_drum(tape, track, t1, t2, P, Amp)

Karplus and Strong (1983) algorithm for obtaining a percussion sound. Typically, P is taken to be between 150 and 1000. Caution: this algorithm overwrites what may have existed on the track at the chosen location. You may also want to modify the b parameter to make some weird sounds, somewhere between percussion and guitar... http://crypto.stanford.edu/~blynn/sound/karplusstrong.html https://en.wikipedia.org/wiki/Karplus%E2%80%93Strong_string_synthesis

Arguments

Type IntentOptional Attributes Name
type(tape_recorder), intent(inout) :: tape
integer, intent(in) :: track
real(kind=wp), intent(in) :: t1
real(kind=wp), intent(in) :: t2
integer, intent(in) :: P
real(kind=wp), intent(in) :: Amp

Called by

proc~~add_karplus_strong_drum~~CalledByGraph proc~add_karplus_strong_drum add_karplus_strong_drum program~drum_machine drum_machine program~drum_machine->proc~add_karplus_strong_drum

Source Code

    subroutine add_karplus_strong_drum(tape, track, t1, t2, P, Amp)
        type(tape_recorder), intent(inout) :: tape
        integer, intent(in)  :: track, P
        real(wp), intent(in) :: t1, t2, Amp
        integer  :: i1, i2

        real(wp) :: r
        integer  :: i
        ! 0 <= b <= 1 but b = 0.5 is the best value for good drums:
        real(wp), parameter :: b = 0.5_wp
        real(wp) :: the_sign

        i1 = nint(t1*RATE)
        i2 = nint(t2*RATE) - 1

        ! Track 0 is used as an auxiliary track.

        ! Attack:
        tape%left( 0, i1:i1+P) = Amp
        tape%right(0, i1:i1+P) = Amp

        ! Evolution and decay:
        do i = i1 + P + 1, i2
            ! The sign of the sample is random:
            call random_number(r)
            if (r < b) then
                the_sign = +1._wp
            else
                the_sign = -1._wp
            end if

            ! Mean of samples i-P and i-P-1:
            tape%left( 0, i) = the_sign * 0.5_wp * (tape%left(0, i-P) + tape%left(0, i-P-1))
            tape%right(0, i) = tape%left(0, i)
        end do

        ! Transfer (add) on the good track:
        tape%left( track, i1:i2) = tape%left( track, i1:i2) + tape%left( 0, i1:i2)
        tape%right(track, i1:i2) = tape%right(track, i1:i2) + tape%right(0, i1:i2)
    end subroutine add_karplus_strong_drum