生成WAV音频后播放变慢的原因及速度影响因素咨询
Hey there! Let's dig into why your generated WAV is playing in slow motion, and break down the key parameters that control audio playback speed.
Why Your WAV Is Playing Slow
Looking at your code, there are a few critical issues in how you're constructing the WAV file header that's causing the slow playback:
Incorrect audio data length declaration
Your linelong myDataSize = output.length - 100000;is hardcoding an arbitrary reduction in the data length reported to the WAV header. Players use this value to calculate how long the audio should play. If you tell the player your audio is half as long as it actually is, it'll stretch the full data into that shorter time window—resulting in slow motion playback. This is almost certainly the biggest culprit here.Mismatched subchunk size calculation
You’re calculatingmyChunk2SizeasmyDataSize * myChannels * myBitsPerSample/8, but this formula is only valid ifmyDataSizerepresents the number of audio samples (not bytes). Sinceoutputis a byte array containing your raw audio data,myDataSizeshould equaloutput.length, andmyChunk2Sizeshould directly match that value too.Non-standard sample rate
You’re usingmySampleRate = 44400;, which is not a widely supported standard sample rate (common ones are 44100Hz, 48000Hz). While this alone might not cause drastic slowdown, it can lead to player inconsistencies, especially if your audio data was generated for a different rate.Potential sample formatting errors
Your code assignsoutput[i] = outputSample;but doesn’t show howoutputSampleis calculated. If you’re not properly converting your mixed floating-point samples (samplef1,samplef2) to 16-bit PCM bytes (the format you declared in the header), you could be writing invalid data that players misinterpret as slower audio.
Parameters That Determine Playback Speed
These are the core parameters that dictate how fast your audio plays:
- Sample Rate (
mySampleRate): The number of audio samples per second (measured in Hz). Players use this to know how many samples to play each second. For example, if you generate data at 44100Hz but tell the player it’s 22050Hz, the audio will play at half speed. - Header-declared Data Length: The
myDataSize(andmyChunk2Size) values in the WAV header must exactly match the length of your raw audio data byte array. Mismatches here force players to miscalculate playback duration. - Block Align & Byte Rate: These values are derived from sample rate, channel count, and bit depth. While they’re secondary to the above two, incorrect calculations can confuse players into misinterpreting the audio stream.
Fixes for Your Code
Here’s how to adjust your code to fix the slow playback:
1. Correct the WAV Header Calculations
Fix the data size and subchunk size values to match your actual audio data:
public void saveToFile(byte[] output, String globalName, String nameMix) { long mySubChunk1Size = 16; int myBitsPerSample = 16; int myFormat = 1; long myChannels = 1; long mySampleRate = 44100; // Switch to a standard sample rate long myByteRate = mySampleRate * myChannels * myBitsPerSample / 8; int myBlockAlign = (int) (myChannels * myBitsPerSample / 8); long myDataSize = output.length; // Match actual byte length of audio data long myChunk2Size = myDataSize; // Subchunk2Size equals raw data byte count long myChunkSize = 36 + myChunk2Size; // Rest of your file writing code remains the same... }
2. Fix Sample Conversion & Output Array Population
Ensure you’re correctly converting mixed samples to 16-bit PCM bytes (WAV uses little-endian format for 16-bit samples):
for (int i = 0; i < output.length / 2; i++) { // Each 16-bit sample uses 2 bytes float samplef1 = 0.0f; float samplef2 = 0.0f; if (i <= arrayMusic1.length - 1) samplef1 = arrayMusic1[i] / 128.0f; if (i <= arrayMusic2.length - 1) samplef2 = arrayMusic2[i] / 128.0f; // Mix samples and prevent clipping (keep within -1.0 to 1.0 range) float mixedSample = samplef1 + samplef2; mixedSample = Math.max(-1.0f, Math.min(1.0f, mixedSample)); // Convert to 16-bit short (range: -32768 to 32767) short outputSample = (short)(mixedSample * 32767); // Split short into two bytes (little-endian) output[i*2] = (byte)(outputSample & 0xFF); output[i*2+1] = (byte)((outputSample >> 8) & 0xFF); }
Final Notes
Double-check that your output array is sized correctly (2 bytes per sample for 16-bit mono audio). If you’re still having issues, verify that your input arrays (arrayMusic1, arrayMusic2) are normalized properly (dividing by 128 is correct for 8-bit input samples to get -1.0 to 1.0 floats).
内容的提问来源于stack exchange,提问作者Diogo Odelli

