JFugue 5 примечание проблем - PullRequest
       28

JFugue 5 примечание проблем

0 голосов
/ 24 февраля 2019

Я пытаюсь использовать JFugue 5.0.9 в своем проекте Java для создания * .midi файлов с ним.При реализации миди-возможностей JFugue в моем проекте, использующем частоты 24 мелодии для фортепиано , я понял, что у него есть некоторые проблемы с настройками.

Например, этот код:

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", он не звучит точно на этой частоте.

В другом файле, в основном методе, который я написалэто:

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, на самом деле все они звучат очень хорошо.

1 Ответ

0 голосов
/ 24 февраля 2019

ОК, я посмотрел исходные коды 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» в «iii», потому что, как вы можете видеть, нет оператора if для нижнего регистра I турецкого алфавита (ı), и это приводит к тому, что он возвращает 0, как в случаеиз «i».

Чтобы решить эту проблему, мы должны либо удалить преобразование в нижний регистр и записать все операторы if для I, также и в верхнем регистре, либо установить локаль по умолчанию на «en», чтобы убедиться, что она преобразуется (верхний регистр)Я должен (нижний регистр) я.Итак, это следует использовать в источнике:

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

К счастью, JFugue - это программное обеспечение с открытым исходным кодом, выпущенное под Apache 2.0.

Это все еще не объясняет почему мелодии звучат неправильно но теперь, по крайней мере, мы знаем, что это совершенно разные проблемы .Или, может быть, это так ... я не знаю.Я отредактирую этот ответ, если когда-нибудь найду объяснение или решение для остальных.

Редактировать

Наконец я случайно обнаружил проблему с микротонами.Я решил еще раз взглянуть на функции вычисления микротонов в источнике.

В классе MicrotonePreprocessor (который находится в пакете org.staccato) есть функция с именем convertFrequencyToStaccato () .Эта функция выполняет преобразование частоты в число нот миди и значение изменения высоты тона.На 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?».Это сработало.Это была прекрасная ошибка восприятия, которую мы оба имели.: D Сейчас я действительно много смеюсь.

Это исправляет проблему с микротонами.Теперь я слышу идеальные интервалы!Я чувствую себя счастливым и удовлетворенным.

Edit2

Я просто хотел поделиться своими дальнейшими изменениями, которые привели к улучшению микротональной настройки:

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

Это также помогает использовать полутон (черный) на миди-плате вместо тональных (белых) клавиш с высокими значениями высоты тона.Таким образом, если вы отправите данные в другое программное обеспечение, оно обнаружит все ключи отдельно.Например, раньше не было G и G #, только G и G-with-high-pitch.Это вызвало остановку клавиш при одновременной отправке сообщений с примечаниями.

...