Взять под контроль звуковую карту с JAVA
Я пытаюсь построить "микшерный пульт" в JAVA. В этом микшере каждый "слайдер" был бы линией, как если бы это была физическая консоль микширования. Но после поиска в Goo*** и прочтения документации оракула я не нашел ничего, что могло бы мне помочь.
Во-первых, я перечисляю доступные микшеры (см. Код в конце) и, к счастью, он перечисляет все мои звуковые карты и находит линейные и линейные выходы. Но тогда что мне делать?
Моя цель - создать "виртуальную линию", которая будет перехватывать звук с любой линии (микрофон) или линии (захват звука, воспроизводимого в VLC), позволяя мне "работать над этим", а затем повторно вводить его в другую строку., Конечно, мне придется установить для каждой строки, которая является "в" и которая является "из" Примеры использования:
3 физических линии (микрофоны) будут перехвачены, затем "отрегулированы по уровню", а затем повторно введены в виртуальную линию, которая будет называться "хором", и эта виртуальная линия будет повторно введена в мою основную физическую линию, называемую "Мастер-уровень".
песня, проигрываемая VLC (например, мелодия песни), которая обычно напрямую отправляется на основной "out", перехватывается, как "перехват". Затем я решаю настроить уровень, прежде чем повторно вводить его в свой мастер и микшировать это с микрофоном. Таким образом, это позволит мне регулировать уровень певца с уровнем музыки.
Итак, кто мог бы помочь мне начать и прогрессировать? Спасибо за твою помощь.
Вот код, который перечисляет мои микшеры:
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Control;
import javax.sound.sampled.Line;
import javax.sound.sampled.Mixer;
public class Mixers {
Mixers() {
try {
//List of the mixers from the system
Mixer.Info[] mixerInfo = AudioSystem.getMixerInfo();
//Characteristics of each mixer
for (Mixer.Info info : mixerInfo) {
System.out.println("\n"+info+ " - Description : "+info.getDescription());
Mixer mix=AudioSystem.getMixer(info);
//Controles available for this mixer
for (Control c:mix.getControls()) {
System.out.println ("\t Control supported by this mixer : "+c);
}
//Sources available for this mixer
for (Line.Info i : mix.getSourceLineInfo()) {
System.out.println("\t Source line available : "+i);
//Controls available for this Source
for (Control c : AudioSystem.getLine(i).getControls()) {
System.out.println ("\t\t ==> Controls supported by this source : "+c);
}
}
// TargeLines available for this mixer
for (Line.Info i : mix.getTargetLineInfo()) {
System.out.println("\t Target line available : "+i);
//Controls available for this Target
for (Control c : AudioSystem.getLine(i).getControls()) {
System.out.println ("\t\t Controls supported by this target : "+c);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
Еще раз спасибо всем, кто прочитал мой пост до конца и дал мне начало решения.
никола
2 ответа
Если это можно сделать, я думаю, что следующий шаг, который вы хотите, - это иметь возможность читать данные из различных микшеров и выполнять операции для каждого кадра. Учебное пособие по захвату аудио Java относится к чтению данных с внешних линий. Учебное пособие " Использование файлов и преобразователей формата" содержит пример кода, который показывает, как добраться до отдельных кадров. Под заголовком "Чтение звуковых файлов" приведен пример кода для этого. Наиболее важный момент отмечен следующим комментарием:
// Here, do something useful with the audio data that's
// now in the audioBytes array...
В вашем случае у вас будет несколько массивов auiodBytes, по одному для каждой вводимой строки.
Чтобы смешать, данные кадра PCM из разных строк могут быть добавлены вместе. Регулировка громкости между линиями может осуществляться с помощью множителя, например, с коэффициентом, который варьируется от 0 (тишина) до 1 (полная громкость).
Необходимо соблюдать осторожность, чтобы не слишком сильно изменить множитель в одном кадре, иначе разрыв, введенный в данные, вызывает щелчок. Поэтому распространяйте любые изменения на несколько кадров. Линейные изменения в множителе не совсем соответствуют уровням слышимого звука. Я думаю, что экспоненциальное распределение 3-й степени часто используется для преобразования между линейными значениями и эквивалентными множителями, которые на самом деле звучат как эти значения. Возможно, вы захотите включить функции min и max, чтобы данные PCM никогда не выходили за пределы диапазона -1 и 1. Большая часть этого параграфа посвящена тонким точкам смешивания и может быть разногласия относительно того, каковы лучшие практики.
В stackru есть и другие публикации, в которых рассказывается, как преобразовать ваш формат потока байтов в PCM и обратно. Насколько я знаю, javax.sound.sampled, источник этого кода, в значительной степени опирается на нативный код и имеет довольно низкий уровень. Я смог многое сделать с микшированием таким образом, хотя я полагаюсь на свои собственные источники данных, а не на внешние линии, как вы пытаетесь сделать. Я не знаю, как управляются эти внешние линии, особенно если вы хотите, чтобы ваш компьютер не воспроизводил их, пока вы проигрываете полученную смесь.
Я не уверен, что Java Sound API может сделать это. Вам, вероятно, следует взглянуть на гораздо более низкий API, например, на OpenAL (в Java есть привязки), который обеспечивает больший контроль над звуковыми потоками.