Я использую порт Java генератора звуковых эффектов SFXR, который включает в себя множество загадочного музыкального кода, который я не понимаю, будучи новичком, когда дело касается аудио. Что я знаю, так это то, что код может надежно генерировать и воспроизводить звуки в Java с использованием объекта SourceDataLine.
Данные, которые использует объект SDL, хранятся в байте []. Однако просто записать это в файл не получится (возможно, из-за отсутствия WAV-заголовка, или так я думал).
Однако я скачал этот класс чтения / записи WAV: http://computermusicblog.com/blog/2008/08/29/reading-and-writing-wav-files-in-java/, который добавляет информацию заголовка при записи файла WAV. Предоставление данных байта [] из SFXR по-прежнему приводит к созданию файлов, которые не могут быть воспроизведены ни одним моим музыкальным проигрывателем.
Я полагаю, что я что-то упускаю. Вот соответствующий код при воспроизведении звуковых данных:
public void play(int millis) throws Exception {
AudioFormat stereoFormat = getStereoAudioFormat();
SourceDataLine stereoSdl = AudioSystem.getSourceDataLine(stereoFormat);
if (!stereoSdl.isOpen()) {
try {
stereoSdl.open();
} catch (LineUnavailableException e) {
e.printStackTrace();
}
}
if (!stereoSdl.isRunning()) {
stereoSdl.start();
}
double seconds = millis / 1000.0;
int bufferSize = (int) (4 * 41000 * seconds);
byte[] target = new byte[bufferSize];
writeBytes(target);
stereoSdl.write(target, 0, target.length);
}
Это из порта SFXR. Вот файл save () из класса WavIO (в этом классе, конечно, много другого кода, я подумал, что это может стоить опубликовать на тот случай, если кто-то захочет увидеть, как именно обрабатываются данные буфера:
public boolean save()
{
try
{
DataOutputStream outFile = new DataOutputStream(new FileOutputStream(myPath));
// write the wav file per the wav file format
outFile.writeBytes("RIFF"); // 00 - RIFF
outFile.write(intToByteArray((int)myChunkSize), 0, 4); // 04 - how big is the rest of this file?
outFile.writeBytes("WAVE"); // 08 - WAVE
outFile.writeBytes("fmt "); // 12 - fmt
outFile.write(intToByteArray((int)mySubChunk1Size), 0, 4); // 16 - size of this chunk
outFile.write(shortToByteArray((short)myFormat), 0, 2); // 20 - what is the audio format? 1 for PCM = Pulse Code Modulation
outFile.write(shortToByteArray((short)myChannels), 0, 2); // 22 - mono or stereo? 1 or 2? (or 5 or ???)
outFile.write(intToByteArray((int)mySampleRate), 0, 4); // 24 - samples per second (numbers per second)
outFile.write(intToByteArray((int)myByteRate), 0, 4); // 28 - bytes per second
outFile.write(shortToByteArray((short)myBlockAlign), 0, 2); // 32 - # of bytes in one sample, for all channels
outFile.write(shortToByteArray((short)myBitsPerSample), 0, 2); // 34 - how many bits in a sample(number)? usually 16 or 24
outFile.writeBytes("data"); // 36 - data
outFile.write(intToByteArray((int)myDataSize), 0, 4); // 40 - how big is this data chunk
outFile.write(myData); // 44 - the actual data itself - just a long string of numbers
}
catch(Exception e)
{
System.out.println(e.getMessage());
return false;
}
return true;
}
Все, что я знаю, это то, что у меня есть куча данных, и я хочу, чтобы они оказались в каком-то воспроизводимом аудиофайле (в этот момент я бы взял ЛЮБОЙ формат!). Какой лучший способ для меня поместить этот байтовый буфер в воспроизводимый файл? Или этот байт [] не тот, что я думаю?