Шум в фоне при генерации синусоидальной волны в Java

Вы можете отбросить квалификатор const: table_remove((table *)t);, но у вас могут возникнуть проблемы, если table_remove попытается изменить структуру table, например, если она хранится в чтении только сегмент.

Поэтому вы не должны делать это. Довольно неожиданно, что функция поиска все равно изменит таблицу. Если это происходит по уважительным причинам, таким как создание хеш-таблицы или поддержка кэша, аргумент не должен быть объявлен как const.

5
задан yxk 11 April 2009 в 18:57
поделиться

2 ответа

В ваших комментариях говорится, что в коде используется big-endian.

Технически вы на самом деле ] в выходном формате с прямым порядком байтов, но это, похоже, не имеет значения, потому что благодаря счастливой причуде ваш самый значимый байт всегда равен 0.

РЕДАКТИРОВАТЬ: объяснить это далее - когда ваше значение достигает максимального значения 127, вы должно записывать (0x00, 0x7f), но фактический вывод из вашего кода равен (0x7f, 0x00), что составляет 32512. Это происходит вблизи правильного 16-битного максимального значения 32767, но с нижней 8 бит все ноль. Было бы лучше всегда использовать 32767 в качестве максимального значения, а затем отбрасывать нижние 8 битов, если это необходимо.

Это означает, что даже если вы выводите 16-битные данные, эффективное разрешение составляет только 8 бит. Похоже, это объясняет отсутствие качества звука.

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

Кроме того, для чего-то стоит ваша математика будет легче, если вы вычислите волновое уравнение, основанное на счетчиках выборок, а затем будете беспокоиться о смещениях байтов отдельно:

int samples = 2 << 19;
byte audioBuffer[] = new byte[samples * channels * sampleSizeInBytes];

for ( int i = 0, j = 0; i < samples; ++i )
{
    int wave = (int)(32767.0 * Math.sin(2.0 * Math.PI * frequency * i / sampleRate));
    byte msb = (byte)(wave >>> 8);
    byte lsb = (byte) wave;

    for (int c = 0; c < channels; ++c) {
        audioBuffer[j++] = msb;
        if (sampleSizeInBytes > 1) {
            audioBuffer[j++] = lsb;
        }
    }
 }
7
ответ дан 14 December 2019 в 01:16
поделиться

Полагаю, вы неоднократно вызываете этот код для воспроизведения длинного звука.

Есть ли вероятность, что волна Вы генерируете, что не завершаете полный период до того, как он будет записан?

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

Например:

        /-------\              /-------\              /-------\
  -----/         \       -----/         \       -----/         \
                  \                      \                      \
                   \-----                 \-----                 \-----

Обратите внимание на разрыв между частями этой волны. Это может вызывать жужжание.

2
ответ дан 14 December 2019 в 01:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: