Module: ISO_1996::Part_1_2016

Includes:
Constants
Defined in:
lib/iso_1996/part_1_2016.rb

Overview

ISO 1996-1:2016 Acoustics - Description, measurement and assessment of environmental noise -

Part 1: Basic quantities and assessment procedures

Module implementing calculations defined in ISO 1996-1:2016

Author

Maciej Ciemborowicz

Date

July 13, 2025

Defined Under Namespace

Modules: Constants

Constant Summary

Constants included from Constants

Constants::DAY_DURATION, Constants::EVENING_DURATION, Constants::EVENING_PENALTY, Constants::NIGHT_DURATION, Constants::NIGHT_PENALTY, Constants::REFERENCE_SOUND_PRESSURE, Constants::REFERENCE_TIME

Class Method Summary collapse

Class Method Details

.assessment_level(l_aeq_t, k_t, k_i) ⇒ Float

Calculate assessment level (L_r) as defined in Section 3.6

L_r = L_AeqT + K_T + K_I dB

Parameters:

  • l_aeq_t (Float)

    Equivalent continuous A-weighted sound pressure level (dB)

  • k_t (Float)

    Tonal adjustment factor (dB)

  • k_i (Float)

    Impulsive adjustment factor (dB)

Returns:

  • (Float)

    Assessment level in dB



190
191
192
# File 'lib/iso_1996/part_1_2016.rb', line 190

def self.assessment_level(l_aeq_t, k_t, k_i)
  l_aeq_t + k_t + k_i
end

.compliance_evaluation(assessment_level, noise_limit, measurement_uncertainty) ⇒ Boolean

Evaluate compliance with noise limits as defined in Section 9.2

Parameters:

  • assessment_level (Float)

    Calculated assessment level (dB)

  • noise_limit (Float)

    Applicable noise limit (dB)

  • measurement_uncertainty (Float)

    Measurement uncertainty (dB)

Returns:

  • (Boolean)

    True if limit is exceeded (assessment_level > noise_limit + measurement_uncertainty)



202
203
204
# File 'lib/iso_1996/part_1_2016.rb', line 202

def self.compliance_evaluation(assessment_level, noise_limit, measurement_uncertainty)
  assessment_level > noise_limit + measurement_uncertainty
end

.day_evening_night_level(l_day, l_evening, l_night, day_duration: Constants::DAY_DURATION, evening_duration: Constants::EVENING_DURATION, night_duration: Constants::NIGHT_DURATION, evening_penalty: Constants::EVENING_PENALTY, night_penalty: Constants::NIGHT_PENALTY) ⇒ Float

Calculate day-evening-night level (L_den) as defined in Annex C.2

L_den = 10 * log10( (1/24) * [t_d·10^(L_day/10) + t_e·10^((L_evening + P_e)/10) + t_n·10^((L_night + P_n)/10)] ) dB

Example:

Part_1_2016.day_evening_night_level(65.0, 62.0, 58.0) # => ~67.1 dB

Parameters:

  • l_day (Float)

    Day-time equivalent sound level (dB)

  • l_evening (Float)

    Evening-time equivalent sound level (dB)

  • l_night (Float)

    Night-time equivalent sound level (dB)

  • day_duration (Float) (defaults to: Constants::DAY_DURATION)

    Duration of day period (hours)

  • evening_duration (Float) (defaults to: Constants::EVENING_DURATION)

    Duration of evening period (hours)

  • night_duration (Float) (defaults to: Constants::NIGHT_DURATION)

    Duration of night period (hours)

  • evening_penalty (Float) (defaults to: Constants::EVENING_PENALTY)

    Penalty for evening period (dB)

  • night_penalty (Float) (defaults to: Constants::NIGHT_PENALTY)

    Penalty for night period (dB)

Returns:

  • (Float)

    Day-evening-night level in dB



129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/iso_1996/part_1_2016.rb', line 129

def self.day_evening_night_level(l_day, l_evening, l_night,
                                day_duration: Constants::DAY_DURATION,
                                evening_duration: Constants::EVENING_DURATION,
                                night_duration: Constants::NIGHT_DURATION,
                                evening_penalty: Constants::EVENING_PENALTY,
                                night_penalty: Constants::NIGHT_PENALTY)
  total_hours = day_duration + evening_duration + night_duration
  
  term_day = day_duration * 10 ** (l_day / 10.0)
  term_evening = evening_duration * 10 ** ((l_evening + evening_penalty) / 10.0)
  term_night = night_duration * 10 ** ((l_night + night_penalty) / 10.0)
  
  10 * Math.log10((term_day + term_evening + term_night) / total_hours)
end

.equivalent_continuous_sound_level(levels, measurement_time) ⇒ Float

Calculate equivalent continuous sound level (L_Aeq,T) as defined in Section 3.1.7

L_Aeq,T = 10 * log10( (1/T) * Σ(10^(0.1*L_i)) ) dB

Example:

levels = [65.0, 67.0, 63.0]
Part_1_2016.equivalent_continuous_sound_level(levels, 3.0) # => ~65.1 dB

Parameters:

  • levels (Array<Float>)

    Array of sound pressure levels (dB)

  • measurement_time (Float)

    Total measurement time (seconds)

Returns:

  • (Float)

    Equivalent continuous sound level in dB

Raises:

  • (ArgumentError)


90
91
92
93
94
95
96
97
# File 'lib/iso_1996/part_1_2016.rb', line 90

def self.equivalent_continuous_sound_level(levels, measurement_time)
  raise ArgumentError, "Measurement time must be positive" if measurement_time <= 0
  
  return -Float::INFINITY if levels.empty?

  energy_sum = levels.sum { |l| 10 ** (l / 10.0) }
  10 * Math.log10(energy_sum / measurement_time)
end

.impulsive_adjustment_factor(is_audible: false, is_distinct: false) ⇒ Float

Determine impulsive adjustment factor (K_I) as defined in Annex D.4

According to Annex D.4:

Distinct impulsive sound: 6 dB
Clearly audible but not distinct: 3 dB
Not clearly audible: 0 dB

Parameters:

  • is_audible (Boolean) (defaults to: false)

    Whether the impulsive sound is clearly audible

  • is_distinct (Boolean) (defaults to: false)

    Whether the impulsive sound is distinct

Returns:

  • (Float)

    Impulsive adjustment factor in dB (0.0, 3.0, 6.0)



174
175
176
177
178
# File 'lib/iso_1996/part_1_2016.rb', line 174

def self.impulsive_adjustment_factor(is_audible: false, is_distinct: false)
  return 0.0 unless is_audible
  return 6.0 if is_distinct
  3.0
end

.peak_sound_pressure_level(p_c_max) ⇒ Float

Calculate peak sound pressure level (L_pC,peak) as defined in Section 3.1.10

L_pC,peak = 20 * log10(p_Cmax / p₀) dB

Parameters:

  • p_c_max (Float)

    Maximum C-weighted sound pressure (Pa)

Returns:

  • (Float)

    Peak sound pressure level in dB



107
108
109
# File 'lib/iso_1996/part_1_2016.rb', line 107

def self.peak_sound_pressure_level(p_c_max)
  20 * Math.log10(p_c_max / Constants::REFERENCE_SOUND_PRESSURE)
end

.sound_exposure_level(p_a) ⇒ Float

Calculate sound exposure level (L_AE) as defined in Section 3.1.8

L_AE = 10 * log10( (1/t₀) * ∫(p_A²(t)/p₀²) dt ) dB

Note: This method assumes a single value for simplicity.

For time-varying signals, integration over time is required.

Parameters:

  • p_a (Float)

    A-weighted sound pressure (Pa)

Returns:

  • (Float)

    Sound exposure level in dB



73
74
75
# File 'lib/iso_1996/part_1_2016.rb', line 73

def self.sound_exposure_level(p_a)
  10 * Math.log10((1.0 / Constants::REFERENCE_TIME) * (p_a ** 2) / (Constants::REFERENCE_SOUND_PRESSURE ** 2))
end

.sound_pressure_level(p) ⇒ Float

Calculate sound pressure level (L_p) as defined in Section 3.1.2

L_p = 10 * log10(p² / p₀²) dB

Example:

Part_1_2016.sound_pressure_level(0.1) # => 74.0 dB

Parameters:

  • p (Float)

    Root-mean-square sound pressure (Pa)

Returns:

  • (Float)

    Sound pressure level in dB



58
59
60
# File 'lib/iso_1996/part_1_2016.rb', line 58

def self.sound_pressure_level(p)
  10 * Math.log10((p ** 2) / (Constants::REFERENCE_SOUND_PRESSURE ** 2))
end

.tonal_adjustment_factor(is_audible: false, is_prominent: false) ⇒ Float

Determine tonal adjustment factor (K_T) as defined in Annex D.3

According to Annex D.3:

Prominent tone: 6 dB
Clearly audible but not prominent: 3 dB
Not clearly audible: 0 dB

Parameters:

  • is_audible (Boolean) (defaults to: false)

    Whether the tone is clearly audible

  • is_prominent (Boolean) (defaults to: false)

    Whether the tone is prominent

Returns:

  • (Float)

    Tonal adjustment factor in dB (0.0, 3.0, 6.0)



156
157
158
159
160
# File 'lib/iso_1996/part_1_2016.rb', line 156

def self.tonal_adjustment_factor(is_audible: false, is_prominent: false)
  return 0.0 unless is_audible
  return 6.0 if is_prominent
  3.0
end