gpt4 book ai didi

java - JFugue 5 音符问题

转载 作者:行者123 更新时间:2023-11-30 05:45:48 29 4
gpt4 key购买 nike

我正在尝试在我的 Java 项目中使用 JFugue 5.0.9 来创建 *.midi 文件。在我的项目中实现 JFugue 的 midi 功能时,该项目使用 24 tune makam piano 的频率。 ,我意识到它有一些曲调问题。

例如这段代码:

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

在控制台上,正如所说的那样 here .

但是打印

E4MAJ E4MAJ E4MAJ A4MIN

在我的项目中。是的,由于某种原因,前三个和弦是相同的。当然,它们听起来也一样。

此外,当使用“m390”等微音时,它听起来并不完全在该频率。

在另一个文件的 main 方法中我写了这个:

Player player = new Player();
player.play("A4 m440 m400 m390 m380 m370 m360");

我知道 A4 和 m440 是相同的,但正如所说的 here ,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 的源代码,这是我在 ChordProgression.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; }
}

有点懒...:D 问题之一就在这里。如果您使用 toLowerCase() 方法而不指定语言环境,则会在运行时导致一些问题。在我现在使用的土耳其语字母表中,小写的 I 是“ı”,而不是“i”。因此,程序将我的和弦从“I-II-III”转换为“i-i-i”,因为如您所见,土耳其字母表 (ı) 的小写 I 没有 if 语句,这导致它返回 0,如本例所示“我”。

要解决此问题,我们必须删除小写转换并为大写 I 编写所有 if 语句,或者将默认区域设置设置为“en”以确保它将(大写)I 转换为(小写)i 。因此,这应该在源代码中使用:

Locale.setDefault(new Locale("en"));

幸运的是,JFugue 是在 Apache 2.0 下发布的开源软件。

仍然并不能解释为什么曲调听起来不对,但现在至少我们知道这些是完全不同的问题。或者也许看起来是这样……我不知道。如果我找到其余问题的解释或解决方案,我将编辑此答案。

编辑

最后我偶然发现了微音的问题。我决定再看一遍源代码中的微音计算函数。

在 MicrotonePreprocessor 类(位于 org.staccato 包中)中有一个名为 convertFrequencyToStaccato() 的函数。该函数的作用是将频率转换为 MIDI 音符编号和弯音值。在第 107 行,如果计算出的音高值非常接近下一个音符,则该代码会对半音、 Octave 和音高值进行舍入:

// 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 会怎样?”。有效。这是我们俩都犯过的一个美丽的认知错误。 :D 我现在真的笑得很开心。

这解决了微音问题。我现在可以听到完美的音程了!我感到幸福和满足。

编辑2

我只是想分享我的进一步更改,这些更改会带来更好的微色调调音:

if (pitches >= 12288)
{
int diff = 16384-pitches;
int applieddiff = 8192-diff;
pitches = applieddiff;
semitone += 1;
if (semitone == 12)
{
octave += 1;
semitone = 0;
}
}

这也有助于在 midi 板上使用半音(黑色)键,而不是仅使用具有高音高值的音调(白色)键。因此,如果您将数据发送到另一个软件,它会单独检测所有 key 。比如之前没有G和G#,只有G和G-高音。当同时发送音符消息时,这些会导致按键互相停止。

关于java - JFugue 5 音符问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54853476/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com