Вывод MIDI на более чем 16 каналов в программном синтезаторе Java
MIDI-канал управляет такими параметрами, как звук, панорамирование, громкость и т. д.; таким образом, для ансамблевой музыки каждый из его реальных инструментов должен быть представлен отдельным каналом. Если задействовано более 15 неударных инструментов, одной MIDI-линии недостаточно.
Программное обеспечение Java, которое я пишу, предназначено для пользователей, большинство из которых будет использовать встроенный программный синтезатор Java. Я хочу разрешить более 16 инструментов. Учитывая существующий API, насколько мне известно, мне нужно несколько объектов MidiReceiver, которые работают независимо.
Первая попытка: программный синтезатор утверждает "getMaxReceivers() == -1", т.е. неограниченно, поэтому я создаю столько, сколько мне нужно. К сожалению, все они используют одни и те же каналы — провал.
Вторая попытка: я создаю два объекта MidiDevice для одного и того же объекта Info и MidiReceiver для каждого. Когда я пытаюсь открыть второй, я получаю исключение, говорящее, что больше нет доступных звуковых линий.
Третья попытка: То же, что и вторая, но для открытия устройств я использую специальный метод класса SoftSynthesizer, который позволяет мне открывать его с заданной звуковой линией; Я делаю это, используя ту же строку. Никаких исключений, но хаотичный вывод звука. Поскольку два объекта ничего не знают друг о друге, они не могут корректно добавлять свои выходные данные. Снова неудача.
Вопросы:
А) Я что-то упустил из виду?
Б) Если нет, то не мог бы кто-нибудь, у кого есть контакты и репутация, предупредить авторов интерфейса Java и SoftSynthesizer? Мое предложение, минимально инвазивное: объект (Soft)Synthesizer должен быть наделен дополнительным методом, таким как «MidiDevice getSubdevice()», на котором getReceiver() предлагает свежие каналы по мере необходимости.
(При повторном редактировании: может ли быть так, что обычный метод getReceiver() на самом деле предназначен для этой цели, как описано в моей «Первой попытке» выше, и просто неправильно реализован SoftSynthesizer «Gervill»? Если это так, Gervill должен быть в курсе, кого, однако, не так просто найти в гугле.Вы можете знать, как связаться с ним/ней/ними.)
public boolean GetTwoIndependenttReceivers (Receiver [] inhereplease)
{
for (MidiDevice.Info info : MidiSystem.getMidiDeviceInfo ()) try
{
MidiDevice device = MidiSystem.getMidiDevice (info);
if ( device instanceof Synthesizer
&& ( device.getMaxReceivers () < 0
|| device.getMaxReceivers () >= 2)) try
{
device.open ();
inhereplease [0] = device.getReceiver ();
inhereplease [1] = device.getReceiver ();
// will be distinct as objects, but with Gervill not independent
return true;
} catch (Exception ex) {}
} catch (Exception ex) {}
return false;
}
Обратите внимание, что, например, бесплатное программное обеспечение MuseScore прекрасно справляется с этой задачей с помощью собственного программного синтезатора. Он экспортирует MIDI-файлы с MIDI-сообщениями «MIDI-порт», как это предусмотрено стандартом MIDI именно для этой цели, и изящно импортирует их. Встроенный секвенсор Java просто игнорирует эти сообщения порта и поэтому воспроизводит файлы неправильно. Это может быть дополнительным стимулом для атаки на проблему: по одному объекту Receiver на каждый порт.