A waveform can look substantial, and both channels can contain valid samples, while a mono mix of the same file is almost silent. Before blaming the audio converter, check how the left and right channels relate to each other.
Iām Alex, a member of the Creatune team. This is a reproducible numerical test with an original synthetic signal, not a listening comparison or a claim about every playback device.
Build a deliberately extreme control
For this control, the right channel is the exact negative of the left. This is a polarity inversion, not a time delay. For a sine wave it is also equivalent to a half-cycle phase difference; that equivalence should not be generalized to arbitrary music.
import math, struct, wave
frames = bytearray()
for i in range(96000):
left = round(8000 * math.sin(2 * math.pi * 440 * i / 48000))
frames.extend(struct.pack('<hh', left, -left))
with wave.open('antiphase.wav', 'wb') as w:
w.setparams((2, 2, 48000, 0, 'NONE', 'not compressed'))
w.writeframes(frames)
This creates two seconds of 48 kHz, 16-bit stereo audio. Each channel has a peak sample magnitude of 8000. A simple mono average is (left + right) / 2, which is zero for every frame of this input.
Do not use the control at high listening volume: numerical verification does not require playback.
Pass it through an explicit WAV conversion
Open the Creatune audio converter, choose the generated file, and wait for its waveform and two-second duration to appear. The public interface accepts local audio and offers MP3, WAV, and FLAC output.
Open Output format, select WAV, and download the result as antiphase-export.wav. The initial format in this run was MP3, so choosing WAV is a deliberate part of the test.
Measure channels before measuring their sum
import math, struct, wave
for path in ['antiphase.wav', 'antiphase-export.wav']:
with wave.open(path, 'rb') as w:
assert w.getnchannels() == 2 and w.getsampwidth() == 2
n = w.getnframes()
values = struct.unpack('<' + 'h' * n * 2, w.readframes(n))
left, right = values[::2], values[1::2]
mono = [(a + b) / 2 for a, b in zip(left, right)]
rms = lambda a: math.sqrt(sum(x*x for x in a) / len(a))
print(path, w.getframerate(), n,
max(map(abs, left)), max(map(abs, right)),
round(rms(left), 2), max(map(abs, mono)))
On October 30, 2026, the input measured 48000 Hz and 96000 frames. The downloaded WAV measured 44100 Hz and 88199 frames, with two 16-bit channels. Both output channel peaks were still 8000; left-channel RMS was 5656.71. The maximum absolute value of the mono average was 0 in both files.
The export therefore retained the exact cancellation relationship in this test. It did not retain the original sample rate or frame count. The waveform preview was not evidence of mono compatibility, and the silent mono average was not evidence that the stereo channels were empty.
Use the result to isolate a real delivery problem
For an affected music file, keep three separate checks: left alone, right alone, and the intended mono fold-down. Compare identical time ranges and avoid changing playback gain between checks. A weak mono result with strong individual channels is a reason to investigate stereo processing, duplicated tracks, polarity, and the actual downmix rule.
Do not automatically invert a channel in finished music. That may improve one source while damaging another. Our exact inverse control is intentionally unrealistic; partial cancellation in music varies with frequency and time, and a device may use a different mix than the simple average above.
For the amplitude side of the investigation, checking a gain change with sample peaks explains what a peak measurement can establish before a listening comparison. For a file that is correct except for a click at its edge, checking an exact cut for a rough boundary covers a different failure that a duration check alone misses. Both are earlier tutorials from our team.


Top comments (0)