How to a make a particle system based on .wav oscillation?

To clarify, I would like to be able to make a script that makes the max and min emission for a particle system based on the oscillation of a music file being played in the same object.

For example, the sound of an explosion would cause the particle system to burst to life with about 200 max, 100 min, suddenly then tail off to about 50 max then 10 then 0 as the explosion becomes inaudible.

While for white sound the particle system would just have a constant 50-ish.

And in the case of a metronome it would look exactly like the particle system’s ‘One Shot’ button was pressed.

Many thanks! - Harhinger of night

Post Script
My English isn’t so bad, this keyboard however is almost unusable.

You may find this handy:

You can look at the spectrum for high or low pitched sounds or whatever and act accordingly.

For others, who search answer:

video demo

using UnityEngine;

public class SoundToPS : MonoBehaviour 
{
    public AudioSource AS;
    public ParticleSystem PS;
    [Header("Emit")]
    public bool Emit = true;
    public float EmitMultiplier = 200f;
    public float CurrentEmit;

    [Header("Size")]
    public bool Size = true;
    public float MinSize = 1f;
    public float MaxSize = 5f;
    public float CurrentSize;
    [Header("Speed")]
    public bool Speed = true;
    public float MinSpeed  = 1f;
    public float MaxSpeed = 5f;
    public float CurrentSpeed;
    [Header("Alpha")]
    public bool Alpha = true;
    public float MinAlpha = 1f;
    public float MaxAlpha = 5f;
    public float CurrentAlpha;


    [Range(0f, 1f)] public float MinRMS = .1f;
    [Range(0f, 1f)] public float MaxRMS = .25f;
    [Range(0f,1f)] public float CurrentRMS;
    public bool DebugRMS = true;

    public int qSamples = 4096;
    private float[] samples;

    ParticleSystem.EmissionModule em;
    ParticleSystem.MainModule sz;
    ParticleSystem.MinMaxGradient clr;

    private void Start()
    {
        em = PS.emission;
        sz = PS.main;
        clr = PS.main.startColor;
        samples = new float[qSamples];
    }

    private void Update()
    {
        var rms = GetRMS();

        if (AS && DebugRMS) CurrentRMS = rms;
        if (!PS || !AS) return;
        if (Emit) em.rateOverTimeMultiplier = CurrentEmit = Mathf.InverseLerp(MinRMS,MaxRMS , rms) * EmitMultiplier;

        if (Size) sz.startSizeMultiplier = CurrentSize = Mathf.Lerp(MinSize,MaxSize, Mathf.InverseLerp(MinRMS, MaxRMS, rms));
        if (Speed) sz.startSpeedMultiplier = CurrentSpeed = Mathf.Lerp(MinSpeed, MaxSpeed, Mathf.InverseLerp(MinRMS, MaxRMS, rms));
        if (Alpha)
        {
            var col = sz.startColor.color;
            col.a = CurrentAlpha = Mathf.Lerp(MinAlpha, MaxAlpha, Mathf.InverseLerp(MinRMS, MaxRMS, rms));
            sz.startColor = col;
        }
    }

    float GetRMS()
    {
        return GetRMSPerChannel(0) + GetRMSPerChannel(1);
    }

    float GetRMSPerChannel(int channel)
    {
        if (!AS) return 0f;

        AS.GetOutputData(samples, channel);
        float sum = 0;
        foreach (float f in samples)
        {
            sum += f * f;
        }
        return Mathf.Sqrt(sum / qSamples);
    }
}