Java JFugue 5注释问题
我试图在Java项目中使用JFugue 5.0.9来创建*.midi文件。当我在使用a频率的项目中实现JFugue的midi功能时,我意识到它有一些音调问题 例如,此代码:Java JFugue 5注释问题,java,jfugue,Java,Jfugue,我试图在Java项目中使用JFugue 5.0.9来创建*.midi文件。当我在使用a频率的项目中实现JFugue的midi功能时,我意识到它有一些音调问题 例如,此代码: ChordProgression cp = new ChordProgression("I-III-IV-iv").setKey("E"); System.out.println(cp); Player player = new Player(); player.play(cp); 应该打印 E4MAJ G#4MAJ A4
ChordProgression cp = new ChordProgression("I-III-IV-iv").setKey("E");
System.out.println(cp);
Player player = new Player();
player.play(cp);
应该打印
E4MAJ G#4MAJ A4MAJ A4MIN
在控制台上,正如所说
但是指纹
E4MAJ E4MAJ E4MAJ A4MIN
在我的项目中。是的,前三个和弦出于某种原因是相同的。当然,它们听起来也一样
此外,当使用像“m390”这样的微音时,它听起来并不完全在那个频率
在另一个文件中,我在main方法中写道:
Player player = new Player();
player.play("A4 m440 m400 m390 m380 m370 m360");
我知道A4和m440是一样的,但正如上面所说的,A5和m440的声音应该是一样的。但在我的项目A4和m440听起来一样,但并不完全是440Hz。当我意识到出现问题时,我决定使用一个调谐应用程序,下面是它分别计算的频率:
221.5 221.5 197.5 186.6 186.6 186.6 176.2
正如你所看到的,它播放的东西非常接近A3,而不是清晰的A4。但这还不是全部。m390、m380和m370的声音也完全相同
这里到底出了什么问题?任何帮助都将不胜感激
一点提示:我很确定这与我的项目无关。我尝试在一个全新的项目中运行上述代码,同样的问题也发生了。我的系统没有问题,因为我的主要项目和任何其他软件,如SunVox,实际上听起来都很不错。好的,我看了一下JFugue 5.0.9的源代码,下面是我在chordProgration.java中得到的:
/**
* Only converts Roman numerals I through VII, because that's all we need in music theory...
* VIII would be the octave and equal I!
*/
private int romanNumeralToIndex(String romanNumeral) {
String s = romanNumeral.toLowerCase();
if (s.startsWith("vii")) { return 6; }
else if (s.startsWith("vi")) { return 5; }
else if (s.startsWith("v")) { return 4; }
else if (s.startsWith("iv")) { return 3; }
else if (s.startsWith("iii")) { return 2; }
else if (s.startsWith("ii")) { return 1; }
else if (s.startsWith("i")) { return 0; }
else { return 0; }
}
有点懒…:其中一个问题就在这里。如果使用toLowerCase()方法而不指定区域设置,则会在运行时导致一些问题。在我现在使用的土耳其语字母表中,I的小写字母是“ı”,而不是“I”。因此,程序将我的和弦从“I-II-III”转换为“I-I-I”,因为正如您所看到的,土耳其字母(ı)的小写I没有if语句,这导致它返回0,就像“I”一样
为了解决这个问题,我们必须删除小写转换并为大写I编写所有if语句,或者将默认语言环境设置为“en”,以确保它将(大写)I转换为(小写)I。因此,应在源代码中使用:
Locale.setDefault(new Locale("en"));
幸运的是,JFugue是在Apache2.0下发布的开源软件
这仍然不能解释为什么曲调听起来不正确,但至少现在我们知道这是完全不同的问题。也许看起来是这样。。。我不知道。如果我能找到其他的解释或解决方案,我会编辑这个答案
编辑
最后我偶然发现了微音的问题。我决定再看一次源代码中的微音计算函数
在MicrotoneProcessor类(位于org.staccato包中)中,有一个名为ConvertFrequencytocystato()的函数。此函数的作用是将频率转换为midi音符编号和音调弯曲值。在第107行,如果计算出的音高值非常接近下一个音符,则该代码对半音、八度和音高值进行四舍五入:
// If we're close enough to the next note, just use the next note.
if (pitches >= 16380)
{
pitches = 0;
semitone += 1;
if (semitone == 12)
{
octave += 1;
semitone = 0;
}
}
重置变桨的线路应更改为:
pitches = 8192;
因为,你们知道,中性节距值是8192。0(零)是最小节距值,16384是最大节距值。起初,我的想法与开发人员的想法相同:“16384年之后,它应该是0。没关系。这里没有问题。”。然后我说,“如果我把音高重置值从0改为8192怎么办?”。成功了。这是一个我们都有过的美丽的感知错误我现在真的很开心
这解决了微音问题。我现在能听到完美的音程了!我感到高兴和满足
编辑2
我只想与大家分享我的进一步变化,这些变化带来了更好的微调调谐效果:
if (pitches >= 12288)
{
int diff = 16384-pitches;
int applieddiff = 8192-diff;
pitches = applieddiff;
semitone += 1;
if (semitone == 12)
{
octave += 1;
semitone = 0;
}
}
这也有助于在midi板上使用半音(黑色)键,而不是仅使用高音高值的半音(白色)键。因此,如果您将数据发送到另一个软件,它将分别检测所有密钥。例如,以前没有G和G,只有G和G高音。当同时发送消息上的便笺时,这些键会相互停止。我没有意识到toLowerCase()在不同的地区工作的方式不同!今天我学到了一些新东西——谢谢。对于你观察到的频率差异,我还没有一个答案,我必须对此进行调查。这是我第一次听说这个问题。谢谢你的评论!:)只要我有空,我仍然在搜索bug。顺便说一句,我想让你知道一些事情。我下载了jfugue-5.0.1.jar并进行了测试。这个问题也存在于那个版本中,但这次的平均频率分别是:22144041039139335353哇!每一个(除了第一个)几乎是我以前计算的一半。(idk为什么我以前看不到这个)不完美(特别是这部分:410 391 393,但可能与俯仰弯曲比计算有关),但看起来更准确。你还记得从那以后你做了什么改变吗?版本5.0.9引入了“微音计算更新”-我相信(d)我改进了微音计算!请给我发一封电子邮件,我可以分享其他详细信息,包括诊断microtone subparser输出的简单方法,这些方法不涉及连接调谐应用程序。