Взять под контроль звуковую карту с 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 есть привязки), который обеспечивает больший контроль над звуковыми потоками.

Другие вопросы по тегам