If a recording sounds higher after editing, did its pitch change, or did the whole recording simply play faster? A small test can separate those two possibilities: inspect both frequency and duration.
I'm Alex, part of the Creatune team. On October 17, 2026, I tested our public Pitch Changer with a locally created 440 Hz sine wave. This is a narrow functional check, not a listening-quality benchmark for vocals or full songs.
The two numbers to predict
In equal temperament, a shift of n semitones has frequency ratio:
ratio = 2 ** (n / 12)
expected_hz = input_hz * ratio
For 440 Hz and +12 semitones, the expected frequency is 880 Hz. A duration-preserving pitch shift should keep an 8-second input approximately 8 seconds long. Simple double-speed playback would also produce 880 Hz, but its duration would be about 4 seconds.
Make a known input
Use a quiet synthetic signal so the expected frequency is unambiguous. This standard-library Python script creates an 8-second, 48 kHz, mono, 16-bit PCM WAV:
import array
import math
import wave
rate = 48000
samples = array.array("h", (
int(6000 * math.sin(2 * math.pi * 440 * i / rate))
for i in range(rate * 8)
))
import sys
if sys.byteorder != "little":
samples.byteswap()
with wave.open("tone-8s-48k.wav", "wb") as w:
w.setparams((1, 2, rate, 0, "NONE", "not compressed"))
w.writeframes(samples.tobytes())
This recreates the signal's test conditions; its exact amplitude need not match my fixture for the frequency and duration check.
Shift and export
Open Creatune's Pitch Changer, choose the WAV, and check that the input duration is 8.0 seconds.
Move Pitch (semitones) to +12 and verify the displayed number. Choose WAV under Output format, then Download. Checking the displayed value matters: changing focus or typing at a slider is not evidence that the setting changed.
The public page currently allows shifts from -12 to +12 semitones and describes local processing. Its stated file limit is 50 MB, with up to 5 minutes of audio, or 2.5 minutes on small screens.
Measure the saved file
For this pure sine wave, counting upward zero crossings over one middle second is a simple frequency estimate. Avoid the first instant of the file, where processing may have a transient.
import array
import sys
import wave
with wave.open("pitch-plus12.wav", "rb") as w:
assert w.getsampwidth() == 2, "This example expects 16-bit PCM"
rate, channels, frames = w.getframerate(), w.getnchannels(), w.getnframes()
pcm = array.array("h", w.readframes(frames))
if sys.byteorder != "little":
pcm.byteswap()
left = pcm[::channels]
window = left[rate:2 * rate]
crossings = sum(a <= 0 < b for a, b in zip(window, window[1:]))
print("seconds:", frames / rate)
print("sample_rate:", rate)
print("channels:", channels)
print("estimated_hz:", crossings)
My actual input measured 8.0 seconds and approximately 440 Hz. The saved output measured:
seconds: 7.999977324263039
sample_rate: 44100
channels: 2
estimated_hz: 880
The output was one 44.1 kHz sample shorter than 8 seconds. It was also exported as stereo at 44.1 kHz, so I used the output header rather than assuming the input's sample rate or channel count.
What this result establishes
For this test file, the frequency doubled while duration remained approximately unchanged. That distinguishes the result from simple double-speed playback.
It does not establish that a shifted singer retains natural formants, that transients remain clean, or that every instrument sounds good at +12. Zero crossings are not a reliable general pitch detector for a full mix. After a basic functional check, compare real material at the small interval you actually need, listen for artifacts, and verify the saved duration again.


Top comments (0)