To avoid generation of extra harmonics (by nonlinear distortion of sine wave tones) not present in the original music recording, the compression or expansion should be done in the amplitude-frequency domain. This implies a sample time window, and not an instant-by-instant scaling in the pressure-time domain. Perhaps a moving finite window or one encompassing an entire song or track.
The simplest compression-expansion algorithm I can think of is as follows, performed on a sound sample represented as amplitudes of a finite set of sine tones of discrete (distinct) frequencies. Let A(f) be the amplitude A as a function of frequency f, with A in units of pressure or volts or other linear scale and not a log or dB scale. Let B be the maximum amplitude in the sound sample, and C be the minimum amplitude among all the frequencies that you care to preserve, and D the amplitude corresponding to the threshold of hearing. Pick any real number S such that 0 <= S <= (B-D)/(B-C). For each frequency f, calculate A_ce(f) = B - S*(B - A(f)). Discard any negative amplitudes; they correspond to original amplitudes less than C, which you decided you do not care about.
Then the function A_ce(f) is a compressed (S < 1) or expanded (S > 1) version of A(f). The number S is a scaling factor for the dynamic range. The case S=0 gives extreme compression in which all of the original tones wind up with amplitude B to give music that has zero dynamic range. On the other hand, S=(B-D)/(B-C) gives extreme expansion in which the original tones with the minimum amplitude of C wind up with new amplitudes D, while original tones with amplitude B retain their amplitude, i.e., the dynamic range goes from B-C to B-D. The case S=1 just preserves the original tones and original dynamic range.
The above compression algorithm does not involve any interaction between distinct frequencies and will not generate any new frequency tones, i.e., no new harmonics. Of course, the compression or expansion will unavoidably change the tonality of a general music sample and the timbre of instruments and voices in it. The advanced compression algorithms are probably attempts to minimize these effects by frequency-dependent scaling, rather than a single scale factor such as S above. Bear in mind that I have no knowledge of how compression is actually carried out. I just based the scaling above by inferring from the current thread the requirement that the overall volume stay the same, which I translated to the peak amplitude B needing to stay the same. You can come up with something similar to make the average volume stay the same, too.
Compression and loudness wars are not on my radar for the most part. Highly commercial pop and rock dropped out of my musical diet some time during the nineties.