apply_dynamic_effect Subroutine

public subroutine apply_dynamic_effect(tape, track, t1, t2, threshold, ratio, below)

A basic dynamic effect with hard knee, and only two parameters : the threshold > 0 expressed linearly (not in dB) and the ratio. It is a compressor if the ratio is > 1. It can also be used as a limiter with a ratio >= 10. Or an upward expander with a ratio < 1. By default, the ratio is applied above the threshold, but the "below" optional parameter can be used to reverse it and obtain: - an upward compressor with ratio < 1 - a (downward) expander with ratio > 1. There are no attack and release parameters at this time. https://en.wikipedia.org/wiki/Dynamic_range_compression

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
real(kind=wp), intent(in) :: threshold
real(kind=wp), intent(in) :: ratio
logical, intent(in), optional :: below

Calls

proc~~apply_dynamic_effect~~CallsGraph proc~apply_dynamic_effect apply_dynamic_effect proc~db_to_linear dB_to_linear proc~apply_dynamic_effect->proc~db_to_linear proc~linear_to_db linear_to_dB proc~apply_dynamic_effect->proc~linear_to_db

Called by

proc~~apply_dynamic_effect~~CalledByGraph proc~apply_dynamic_effect apply_dynamic_effect program~demo_effects demo_effects program~demo_effects->proc~apply_dynamic_effect

Source Code

    subroutine apply_dynamic_effect(tape, track, t1, t2, threshold, ratio, below)
        type(tape_recorder), intent(inout) :: tape
        integer, intent(in)  :: track
        real(wp), intent(in) :: t1, t2, threshold, ratio
        logical, intent(in), optional :: below
        real(wp)             :: signal, thr_db
        integer              :: i

        thr_db = linear_to_db(threshold)

        do concurrent(i = nint(t1*RATE) : min(nint(t2*RATE), tape%last))
            associate(left => tape%left(track,  i), right => tape%right(track,  i))

            if (present(below)) then
                if (below) then  ! upward compression (ratio < 1) or (downward) expansion (ratio > 1)
                    signal = linear_to_db(left)
                    if (signal < thr_db) then
                        left = sign(dB_to_linear(thr_db - (thr_db - signal) * ratio), left)
                    end if

                    signal = linear_to_db(right)
                    if (signal < thr_db) then
                        right = sign(dB_to_linear(thr_db - (thr_db - signal) * ratio), right)
                    end if

                    cycle
                end if
            end if

            ! Else it is downward compression (ratio>1) or upward expansion (ratio<1)
            signal = linear_to_db(left)
            if (signal > thr_db) then
                left = sign(dB_to_linear(thr_db + (signal - thr_db) / ratio), left)
            end if

            signal = linear_to_db(right)
            if (signal > thr_db) then
                right = sign(dB_to_linear(thr_db + (signal - thr_db) / ratio), right)
            end if

            end associate
        end do
    end subroutine apply_dynamic_effect