Следующий код должен создать файл, содержащий синусоидальную волну. На типичных частотах (220 Гц, 440 Гц, 880 Гц) он идет отлично, но на многих других частотах он, например, не принимает 225 Гц, 883 Гц и так далее. Что делать, чтобы получить хорошую синусоидальную волну для любой частоты?Как сгенерировать WAV-файл с синусоидальной волной и определяемой пользователем продолжительностью и частотой?
import java.lang.Math;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
public class CreateSine
{
static String fileNameString = "Sine.wav";
static File file = new File(fileNameString);
static String filePath = file.getAbsolutePath();
static RandomAccessFile raw;
static int byteCount = 0;
static double pow215 = Math.pow(2, 15);
static float freq = 440.0f;
static int sRate = 44100;
static int bitDepth = 16;
static int nChannels = 1;
static int dur = 1;
static float changeRate = (float)((2.0 * Math.PI * freq)/sRate);
public static void main(String[] args)
{
try
{
raw = new RandomAccessFile(filePath, "rw");
raw.setLength(0); // Set file length to 0, to prevent unexpected behavior in case the file already existed
raw.writeBytes("RIFF");
raw.writeInt(0); // Final file size not known yet, write 0. This is = sample count + 36 bytes from header.
raw.writeBytes("WAVE");
raw.writeBytes("fmt ");
raw.writeInt(Integer.reverseBytes(16)); // Sub-chunk size, 16 for PCM
raw.writeShort(Short.reverseBytes((short) 1)); // AudioFormat, 1 for PCM
raw.writeShort(Short.reverseBytes((short)nChannels));// Number of channels, 1 for mono, 2 for stereo
raw.writeInt(Integer.reverseBytes(sRate)); // Sample rate
raw.writeInt(Integer.reverseBytes(sRate*bitDepth*nChannels/8)); // Byte rate, SampleRate*NumberOfChannels*bitDepth/8
raw.writeShort(Short.reverseBytes((short)(nChannels*bitDepth/8))); // Block align, NumberOfChannels*bitDepth/8
raw.writeShort(Short.reverseBytes((short)bitDepth)); // Bit Depth
raw.writeBytes("data");
raw.writeInt(0); // Data chunk size not known yet, write 0. This is = sample count.
}
catch(IOException e)
{
System.out.println("I/O exception occured while writing data");
}
for (int i = 0; i < sRate*dur; i++)
{
writeSample((float)Math.sin(i * changeRate));
}
closeFile();
System.out.print("Finished");
}
static void writeSample(float floatValue)
{
try
{
short hexSample = (short)((floatValue * pow215));
raw.writeShort(Short.reverseBytes(hexSample));
byteCount += 2;
}
catch(IOException e)
{
System.out.println("I/O exception occured while writing data");
}
}
static void closeFile()
{
try
{
raw.seek(4); // Write size to RIFF header
raw.writeInt(Integer.reverseBytes(byteCount + 36));
raw.seek(40); // Write size to Subchunk2Size field
raw.writeInt(Integer.reverseBytes(byteCount));
raw.close();
}
catch(IOException e)
{
System.out.println("I/O exception occured while closing output file");
}
}
}
Благодарим за помощь.