Для этого вы можете преобразовать потоки в данные PCM, умножить канал, громкость которого вы хотите изменить, на желаемый коэффициент, сложить данные PCM из результатов вместе, а затем преобразовать обратно в байты.
Чтобы получить доступ к AudioStreams побайтно, ознакомьтесь с первым фрагментом расширенного кода в разделе «Учебники по Java» на Использование файлов и преобразователей форматов. Это показывает, как получить массив звуковых байтовых данных. Есть комментарий следующего содержания:
// Here, do something useful with the audio data that's
// now in the audioBytes array...
На этом этапе переберите байты, конвертируя в PCM. Должен работать набор команд, основанный на следующем:
for (int i = 0; i < numBytes; i += 2)
{
pcmA[i/2] = audioBytesA[i] & 0xff ) | ( audioBytesA[i + 1] << 8 );
pcmB[i/2] = audioBytesB[i] & 0xff ) | ( audioBytesB[i + 1] << 8 );
}
В приведенном выше примере audioBytesA и audioBytesB — это два входных потока (имена основаны на коде из примера), а pcmA и pcmB может быть либо массивом int, либо массивом short, содержащим значения, попадающие в диапазон short. Возможно, лучше всего сделать массивы pcm числом с плавающей запятой, так как вы будете выполнять некоторые математические операции, которые приведут к дробям. Использование float, как в приведенном ниже примере, увеличивает точность только на один разряд (округление лучше, чем при использовании int), и int будет работать быстрее. Я думаю, что использование поплавков чаще используется, если аудиоданные нормализуются для использования с дополнительной обработкой.
Оттуда лучший способ изменить громкость — умножить каждое значение PCM на одну и ту же сумму. Например, чтобы увеличить громкость на 25%,
pcmA[i] = pcmA[i] * 1.25f;
Затем добавьте pcmA и pcmB и снова преобразуйте их в байты. Вы также можете добавить минимальные или максимальные функции, чтобы объем и слияние не превышали значений, которые могут поместиться в 16-битном формате.
Я использую следующее для преобразования обратно в байты:
for (int i = 0; i < numBytes; i++)
{
outBuffer[i*2] = (byte) pcmCombined[i];
outBuffer[(i*2) + 1] = (byte)((int)pcmCombined[i] >> 8 );
}
Выше предполагается, что pcmCombined[] является массивом с плавающей запятой. Код преобразования может быть немного проще, если это массив short[] или int[].
Я вырезал и вставил приведенное выше из работы разработчиков, которую я сделал для программ, размещенных на моем веб-сайте, и отредактировал его. для вашего сценария, поэтому, если есть опечатка или ошибка, сообщите мне об этом в комментариях, и я это исправлю.
person
Phil Freihofner
schedule
21.09.2015
AmplitudeConverter
для одного из потоков. - person Andrew Thompson   schedule 21.09.2015