Нашел способ обрабатывать записи голоса, решил использовать этот проект.
Столкнулся с проблемой:
На Java всё работает отлично, но я не могу разобраться, как сохранить результат в wav-файл. Вот код:
public static void main(String args[]) throws UnsupportedAudioFileException, IOException, LineUnavailableException {
// Новые параметры
float speed = 1.0f;
float pitch = 0.8f;
float rate = 0.75f;
float volume = 7.0f;
boolean emulateChordPitch = false;
int quality = 1;
// Читаем файл
AudioInputStream stream = AudioSystem.getAudioInputStream(new File("test.wav"));
AudioFormat format = stream.getFormat();
int sampleRate = (int) format.getSampleRate();
int numChannels = format.getChannels();
SourceDataLine.Info info = new DataLine.Info(SourceDataLine.class, format,
((int) stream.getFrameLength() * format.getFrameSize()));
SourceDataLine line = (SourceDataLine) AudioSystem.getLine(info);
// Файл воспроизводится
line.open(stream.getFormat());
line.start();
runSonic(stream, line, speed, pitch, rate, volume, emulateChordPitch, quality,
sampleRate, numChannels);
line.drain();
line.stop();
}
И метод runSonic:
private static void runSonic(
AudioInputStream audioStream,
SourceDataLine line,
float speed,
float pitch,
float rate,
float volume,
boolean emulateChordPitch,
int quality,
int sampleRate,
int numChannels) throws IOException {
Sonic sonic = new Sonic(sampleRate, numChannels);
int bufferSize = line.getBufferSize();
byte inBuffer[] = new byte[bufferSize];
byte outBuffer[] = new byte[bufferSize];
int numRead, numWritten;
sonic.setSpeed(speed);
sonic.setPitch(pitch);
sonic.setRate(rate);
sonic.setVolume(volume);
sonic.setChordPitch(emulateChordPitch);
sonic.setQuality(quality);
do {
numRead = audioStream.read(inBuffer, 0, bufferSize);
if (numRead <= 0) {
sonic.flushStream();
} else {
sonic.writeBytesToStream(inBuffer, numRead);
}
do {
numWritten = sonic.readBytesFromStream(outBuffer, bufferSize);
if (numWritten > 0) {
// Если закомментировать следующую строчку, файл не будет воспроизводиться
line.write(outBuffer, 0, numWritten);
// По логике, в outBuffer должны храниться байты результата
// Выводил на экран - много разных массивов размером 96000
// Их нужно объединить и записать в файл, или как?
}
} while (numWritten > 0);
} while (numRead > 0);
}
В примерах кода привел комментарии.
Суть: результативный файл воспроизводится, а мне нужно, чтобы воспроизведения не было, а была лишь запись в файл. Думаю, исходники проекта нет смысла приводить, и что-то нужно изменить/добавить в коде, который я привел. Спасибо заранее.
UPDATE:
В цикле после line.write
каждый раз добавлял outBuffer к существующему массиву байтов:
public byte[] concat(byte[] a, byte[] b) {
int aLen = a.length;
int bLen = b.length;
byte[] c = new byte[aLen + bLen];
System.arraycopy(a, 0, c, 0, aLen);
System.arraycopy(b, 0, c, aLen, bLen);
return c;
}
затем записал его в файл:
FileUtils.writeByteArrayToFile(file, byte_array);
и попытался сконвертировать этот файл в wav, как описано вот здесь.
До этого момента ошибок нет, массивы склеиваются правильно (проверено), файл тоже записывается, и так далее. Даже wav рабочий. Однако не без косяков: Прослушать пример: линк.wav. Причём, самое странное, что при одних настройках всё нормально, а при других как на приведенной записи - какие-то участки записи повторяются. Почему так и как можно исправить?
UPDATE:
Попробовал записать этот же результативный byte[] в wav, но уже другим способом, результат получается абсолютно аналогичный. Второй способ тут.
Использую AudioFormat от исходного файла, то есть различий в rate/sampleSize/каналах быть не может. В чем же проблема? При воспроизведении всё хорошо, потом этот результативный массив записывается в файл, и вылазят косяки. Если в line.write использовать inBuffer, то, логично, воспроизводиться будет первоначальный файл, также если и записывать в файл inBuffer, то будет записана исходная запись, но с тем же косяком на тех же моментах. Если же изначально в "новых параметрах" rate указать именно 1.3f (не больше и не меньше), то получается нормально, только после слов чувствуются паузы, как будто запись прерывается (???). Если менять именно этот параметр, косяк лишь усугубляется.
Вся результативная запись (которая и воспроизводится) разбита на блоки по 96 кб. Их же я все и объединяю в один файл. Я попробовал сохранять каждый блок в отдельный файл и обнаружил, что есть идентичные wav-файлы, которые получаются из абсолютно разных массивов. Я вычислял специально повторяющиеся блоки, смотрел на массивы байтов, и в начале, и в середине, и в конце, они все различаются. Однако файлы идентичны абсолюнто: открыл через текстовый редактор их, разница есть в первых нескольких строках, и всё. Так вот я не понимаю вообще, в чем дело. В таком случае, придется искать костыли, сравнивать эти кучи wav-файлов, удалять повторяющиеся, а потом склеивать в один файл. Но это слишком уж костыльно, да и как сравнивать wav-файлы, тоже не очень понятно.
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Здравствуйте, как поместить Navigation Drawer под Toolbar? чтоб когда я слева вытягиваю это самое меню, - toolbar не вылазил наперёд
Есть несколько кнопок на экране, нужно посчитать сколько в состоянии "ON"Как это лучше организовать?
Стоит ли вообще копать в эту сторону? На сайте защита-скриннинг, не позволяющая часто подключаться к серверам, временно блокируется доступПробовал...
Как создать список самому? В принципе я написал так, что я могу добавить элемент в список, но как удалить - не представляю,точнее представляю,...