Согласованный звук во время воспроизведения звука через SourceDataLine - PullRequest
1 голос
/ 24 января 2020

Я сейчас пишу основной c синтезатор и столкнулся с какой-то странной проблемой. При воспроизведении массива байтов, представляющих 16-битный монофонический звук, через SourceDataLine. Я получаю постоянный звук. Попса немного отличаются по частоте, хотя (опять же, из того, что я слышу), некоторые ноты имеют звучание низкочастотного звучания, а другие звучат высокочастотно. Хотя всплывающие окна не переопределяются, вы все равно можете слышать желаемый звук в фоновом режиме.

Ничто не меняет частоту всплывающих окон, не высоту звука, ни размер буфера SourceDataLine, ни количество байтов, в которые я записываю это за раз, кроме частоты дискретизации.

Понижение частоты дискретизации уменьшает частоту всплывающих окон и наоборот.

Чтобы проверить мою сторону программы, я распечатал данные записывается в SourceDataLine в течение примерно полсекунды и просматривает около 15 циклов воспроизводимой синусоиды, и это было совершенно нормально; никаких внезапных скачков, отсечений или чего-либо еще.

Единственное, для чего я использую значение частоты дискретизации, это некоторая базовая c математика, чтобы помочь моей выборке сэмплера на правильной частоте, которая рассчитывается только один раз для каждой ноты, и он определенно работает, поскольку высота тона идеально подходит и для создания SourceDataLine.

Вот как я запускаю SourceDataLine (взятый из нескольких частей основного метода):

AudioFormat format = new AudioFormat(AudioEnvironment.SAMPLE_RATE, AudioEnvironment.BIT_DEPTH, 1, true, true);

SourceDataLine line = AudioSystem.getSourceDataLine(format);
line.open(format, 8000);
line.start();

Мои данные находятся в правильном порядке с прямым порядком байтов, проверено мной, меняя флаг порядка байтов в конструкторе и заставляя мои уши взрываться белым шумом.

После того, как программа все настроила, она постоянно записывает данные к SourceDataLine в этой бесконечной l oop:

while (true) {              
    for (Channel channel : channelSystem.getChannels()) {
        if (channel.pitch != 0) {
            wave.sample(channel, buffer);

            line.write(buffer, 0, AudioEnvironment.SUB_BUFFER_SIZE * 2);
        }
    }
}

(A Channel - это созданный мною класс, который содержит все данные для одной заметки (хотя, очевидно, программа настроена неправильно для на данный момент полифония), buffer - это массив байтов, wave.sample() - это место, где я собираю данные в buffer, а AudioEnvironment.SUB_BUFFER_SIZE * 2 - размер buffer) * 102. 7 *

Мне не обязательно нужен пример того, как это исправить в коде, но объяснение того, почему это может происходить, было бы замечательно.

РЕДАКТИРОВАТЬ: Что-то, что я также, вероятно, должен добавить, что Я попытался поместить оператор print в бесконечную запись l oop, чтобы распечатать число доступных байтов в SourceDataLine, и оно постоянно остается около 500 - 2000, иногда доходя до 5000, но никогда не около 8000, поэтому в буфере никогда не заканчиваются данные.

1 Ответ

0 голосов
/ 24 января 2020

Ну, как выясняется, проблема была совершенно не связана с тем, что, как я думал, могло быть.

Оказалось, что в моем сэмплере было написано одно уравнение, которое было просто явно неверным.

После воспроизведения 2048 сэмплов я просто хотел бы oop вернуться к началу сигнала, вызывая всплеск.

Честно говоря, я понятия не имею, почему я это написал, но эй, это работает сейчас.

...