Java软合成器中超过16个通道的MIDI输出
MIDI频道管理参数,例如声音,平移,音量等;因此,对于合奏音乐,其每种真正的乐器都应由自己的渠道代表。如果涉及15种以上的非渗透仪器,则单个MIDI线还不够。
我编写的Java软件旨在为用户提供大多数使用Java内置软件合成器的用户。我想允许16多种乐器。据我所知,鉴于现有的API,我需要几个独立起作用的中级对象。
首先尝试:软合成器断言“ getmaxreceivers()== -1”,即无限,因此我创建了尽可能多的。不幸的是,他们都使用相同的渠道 - 失败。
第二次尝试:我为相同的信息对象创建两个中端对象,每个信息对象为每个对象创建了一个中级对象。当我尝试打开第二个时,我会得到一个例外,说没有其他音频线。
第三次尝试:与第二次相同,但是为了打开设备,我使用了一种特殊的柔软连接器类的方法,使我可以使用给定的音频线打开它。我使用同一行。没有例外 - 而混乱的音频输出。由于两个对象彼此不了解,因此他们无法优雅地添加输出。再次失败。
问题:
a)我忽略了什么吗?
b)如果不是,那么有联系和声誉的人会警告Java界面的作者和Softshesernthesizer吗?我的建议,最少的入侵:(软)合成对象应具有其他方法,例如“ Mididevice GetSubdevice()”,getReceiver()在其上提供了根据需要提供新的通道。
(在重新编辑后:是否是普通的getReceiver()方法实际上是为了实现此目的,如我上面的“第一次尝试”中所述,并且只是被软同觉的“ 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;
}
。它以MIDI标准为此目的导出了MIDI文件中的“ MIDI端口” MIDI消息,并优雅地导入它们。内置的Java Sequencer只是忽略了这些端口消息,因此播放文件不正确。这可能是攻击问题的另一个动机:每个端口的一个接收器对象。
更新:(2024年1月)读者可能有兴趣知道,早在2022年,我将此问题发布给 oracle ,并且在那里被接受为 bug < /strong>: https://bugs.java.com/bugdatabase/bugdatabase/view a 8290993 - 不过,迄今为止未固定。
A MIDI channel administers parameters such as sound, panning, volume etc.; thus for ensemble music, each of its real instrument should be represented by a channel of its own. If more than 15 non-percussion instruments are involved, a single MIDI line is not enough.
The Java software I write is intended for users most of whom will use the Java built-in software synthesizer. I want to allow for more than 16 instruments. Given the existing API as far as I know it, I need several MidiReceiver objects that work independently.
First try: the soft synthesizer asserts "getMaxReceivers() == -1", i.e. unlimited, so I create as many as I need. Unfortunately, they all use the same channels – failure.
Second try: I create two MidiDevice objects for the same Info object, and a MidiReceiver for each. When I try to open the second one, I get an exception saying that no further audio line is available.
Third try: Same as second, but for opening the devices, I use a special method of the SoftSynthesizer class that allows me to open it with a given audio line; I do so using the same line. No exception thrown – but chaotic audio output. Since the two objects don't know about each other, they cannot add their output gracefully. Failure again.
Questions:
A) Have I overlooked something?
B) If not, would someone who has the contacts and reputation please alarm the authors of the Java interface and the SoftSynthesizer? My proposal, minimally invasive: A (Soft)Synthesizer object should be endowed with an additional method such as "MidiDevice getSubdevice()", on which getReceiver() offers fresh channels as required.
(Upon re-editing: Could it be that the ordinary getReceiver() method is actually meant for this purpose, as described in my "First try" above, and has simply been misimplemented by the SoftSynthesizer "Gervill"? If so, Gervill should be informed, who, however, is not easy to find by googling. You may know how to contact him/her/them.)
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;
}
Note that, for example, the free software MuseScore manages the problem all right with its own software synthesizer. It exports MIDI files with "MIDI port" MIDI messages, as intended by the MIDI standard for exactly that purpose, and imports them gracefully. The built-in Java sequencer simply ignores those port messages and therefore plays the files incorrectly. This may be an additional incentive to attack the problem: one Receiver object for each port.
Update: (Jan. 2024) Readers may be interested to know that back in 2022 I posted this issue to Oracle, and it was accepted there as a bug: https://bugs.java.com/bugdatabase/view_bug?bug_id=8290993 – hitherto unfixed, though.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
MIDI标准仅支持16个频道。全停止。
因此,您想做的任何事情都比正常的MIDI规范之外的任何通道要多。常规的Windows GM合成器支持它支持的内容,并且不会改变。如果您需要其他功能,则必须在应用程序内使用其他合成器。
The MIDI standard only supports 16 channels. Full stop.
So, anything you want to do to control more channels than that goes outside the normal MIDI specification. The regular Windows GM synthesizer supports what it supports and isn't going to change. If you need additional capabilities, you'll have to use a different synthesizer, inside your application.