Как я могу преобразовать файл .wav в массив с плавающей точкой (отредактировать массив с плавающей точкой, например, добавив два сигнала) и обратно в файл .wav без отбеливания - PullRequest
0 голосов
/ 19 мая 2019

Я пытаюсь запрограммировать аурализацию с помощью Ray-Tracing при обработке. Чтобы отредактировать образец информации из Ray Tracer, мне нужно преобразовать файл .wav (формат файла: PCM-подпись, 16 бит, стерео, 2 байта / кадр, little-endian) в массив Float.

Я преобразовал аудио через audioInputStream и DataInputStream, где я загружаю аудио в байтовый массив.

Затем я преобразую массив байтов в массив с плавающей точкой, как этот.

byte[] samples;
float[] audio_data = float(samples); 

Когда я преобразую массив float обратно в файл .wav, я получаю звук оригинального аудио-файла.

Но когда я добавляю еще один массив с плавающей точкой к исходному сигналу и преобразовываю его обратно в a. WAV-файл с помощью метода выше (даже если я добавляю тот же сигнал), я получаю сигнал белого шума вместо полезного сигнала (я могу слышать оригинальный сигнал под модулированным белым шумом, но очень очень тихо).

Я читал об этой проблеме раньше, что могут возникнуть проблемы при преобразовании из массива с плавающей точкой в ​​байтовый массив. Это потому, что float - это 32-битный тип данных, а байт (в java) - всего 16 бит, и байты каким-то образом смешиваются друг с другом, поэтому в результате получается белый шум. В обработке есть тип данных с 16-битными целыми числами со знаком (с именем: "short"), но я больше не могу изменять амплитуду, потому что поэтому мне нужны значения с плавающей запятой, которые я не могу преобразовать в short.

Я также пытался справиться с переполнением (амплитудой) в массиве с плавающей запятой, модулируя сигнал от 16-битных значений (-32768/32767) до значений от -1/1 и обратно после микширования (добавления) сигналов. Результат дал мне белый шум. Когда я добавил более двух сигналов, это ничего не дает (ничего не слышно).

Конкретная проблема, которую я хочу решить, состоит в том, чтобы добавить множество сигналов (более 1000 с приличной задержкой для создания своего рода реверберации) в виде плавающих массивов. Затем я хочу объединить их в один массив Float, который я хочу сохранить как аудиофайл без белого шума.

Надеюсь, вы, ребята, сможете мне помочь.

1 Ответ

0 голосов
/ 20 мая 2019

Если у вас есть истинные точки данных PCM, не должно быть проблем с простым сложением.Единственная проблема заключается в том, что в редких случаях (при условии, что ваш звук не слишком горячий для начала) значения выходят за пределы диапазона.Это будет иметь тенденцию создавать резкое искажение, а не белый шум.Тот факт, что вы получаете белый шум, подсказывает мне, что, возможно, вы не конвертируете свои суммы PCM обратно в байты для формата, который вы выводите.

Вот код, который я использую в AudioCue для преобразования PCM обратно в байты.Предполагается, что формат будет 16-битный, 44100 кадров в секунду, стерео, little-endian.Я работаю с PCM как нормализованные поплавки.Этот алгоритм выполняет преобразование для данных буфера за раз.

for (int i = 0, n = buffer.length; i < n; i++)
    {
        buffer[i] *= 32767;

        audioBytes[i*2] = (byte) buffer[i];
        audioBytes[i*2 + 1] = (byte)((int)buffer[i] >> 8 );
    }

Иногда такая функция, как Math.min (Math.max (audioval, -1), 1) или Math.min (Math.max (audioval, -32767), 32767) используется для сохранения значений в диапазоне.Более сложные лимитеры или алгоритмы компрессора масштабируют объем, чтобы соответствовать.Но, тем не менее, если это не обрабатывается, результатом должно быть искажение, а не белый шум.

Если ошибка происходит на другом этапе, нам нужно будет увидеть больше вашего кода.

Все это говорит, я желаю вам удачи с ревербератором массива эхо-сигналов в 1000 точек.Я не слышал об этом подходе, работающем.Может быть, есть процессоры, которые могут справиться с вычислительной нагрузкой сейчас?(Вы пытаетесь сделать это в реальном времени?) Мой единственный успех в кодировании реверберации в реальном времени состоял в том, чтобы использовать метод Шредера, подключая структуру и значения из CCMRA Freeberb , отрабатывая код отКрэйг Линдли, ныне древняя (авторское право 2001) книга "Цифровое аудио с Java".Большая часть этой книги посвящена устаревшему коду GUI (pre-Swing!), Но код, который он дает для фильтров AllPass и Comb, все еще действителен.

Я вспоминаю, когда работал над этим, что отслеживал ссылкилучше реверберацию, чтобы попытаться написать код, но мне нужно было бы немного покопаться, чтобы попытаться найти мои заметки.В то время я чувствовал себя не в своей тарелке, так как алгоритм был представлен в виде блок-схем, а не деталей кода или даже псевдокода.Хотелось бы снова поработать над этим и получить лучшую реверберацию, чем у типа Шредера.Schoeder был пригоден для звуков, которые не были слишком ударными.

Получение решения для трассировки лучей в реальном времени было бы ценным достижением.Много приложений в AR / VR и играх.

...