The code that handles firing logic should be calling the execution of the sound. Not an Input. Each time the weapon actually fires you execute the playing of the sound. This way you aren’t playing audio when the weapon can’t fire (out of ammo etc).
For rapid firing I have the audio in two pieces. Frontend and backend (tail). During fast repetition the tail is never played, only the frontend. The last shot gets the tail applied.