Play sound on collision, how do I avoid having the sound play every frame when a player character pushes the object into a corner?

I’m using the following code to play sound on collision:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Crate : MonoBehaviour {

    Rigidbody rb;
    AudioSource audioSource;

    float timer;

    void Start() {
        rb = GetComponent<Rigidbody>();
        audioSource = GetComponent<AudioSource>();
    }

    void OnCollisionEnter(Collision col) {
        ImpactSound(col);
    }

    void OnCollisionStay(Collision col) {
        ImpactSound(col);
    }

    void ImpactSound(Collision col) {
        float volume = (col.impulse / Time.fixedDeltaTime).magnitude / 2000f;
        volume = Mathf.Min(1f, volume);
        if (volume > 0.05f && timer <= Time.time) {
            audioSource.PlayOneShot(audioSource.clip, volume);
            timer = Time.time + 0.2f;
        }
    }
}

Without the timer, when I push the Crate into a wall, I end up with the sound playing every frame, which sounds broken, of course.

I don’t know how to distinguish between collisions that are based on actual motion and those based on the ones being caused by the crate being squeezed between the player and wall.

How can I avoid this without the timer?

In the OnCollisionStay method, the call to ImpactSound happens for (almost) every frame that any collider is touching this collider. I would remove it from OnCollisionStay, so that it only happens in OnCollisionEnter, when the other collider first touches the crate.