gpt4 book ai didi

java - 如何在 java 中创建一个简单但结构良好的乐谱类(乐谱)?

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:51:19 31 4
gpt4 key购买 nike

我正在使用非常基本的声音合成在我的游戏中即时创建音频和效果。基本上,我有一些方法可以在给定频率、振幅和持续时间的情况下播放声音。

对于简短的短语和旋律,我想提出一个基本的符号,以便我可以轻松地重写或将新的旋律添加到代码中(最后也许我可以从文件中读取,但这可能有点过分了) .

但是我不确定如何实现它。

我首先创建了一个 EqualTemperamentTuning 枚举,其中包含所有 88 个基本钢琴音符以及一个 MIDI # 字段和一个频率字段。这至少意味着我可以处理音符名称而不是频率。

public enum EqualTemperamentTuning {
A_0 (1, 27.5),
A_SHARP_0 (2, 29.1352),
...
C_8 (88, 4186.01);

private int num;
private double frequency;

EqualTemperamentTuning(int num, double frequency){

this.num = num;
this.frequency = frequency;
}

public double getFrequency(){
return frequency;
}

public double getNum(){
return num;
}
}

然后我开始创建更多对象,首先是一个包含 EqualTemperamentTuning、振幅和长度的音符:

public class Note {

/** Note frequency */
private double frequency;
/** Note Amplitude */
private double amplitude;
/** Note length */
private int length;

public Note(EqualTemperamentTuning tuning, double amplitude, int length){

this.frequency = tuning.getFrequency();
this.amplitude = amplitude;
this.length = length;
}

public double getFrequency(){
return frequency;
}

public double getAmplitude(){
return amplitude;
}

public int getLength(){
return length;
}
}

最后为了定义我想要播放的旋律,我创建了一个 NotePhrase 类:

public class NotePhrase {

/** The arrayList of notes*/
private Note[] notes;

public NotePhrase(Note[] notes){

this.notes = notes;
}

public double getFrequency(int counter){

// for each note in the array
for (int i = 0; i< notes.length; i++){

// for each unit of length per note
for (int j=0; j<notes[i].getLength(); j++){

counter--;

// return the frequency at this point
if (counter <= 0) return notes[i].getFrequency();

}
}
return -1;
}
}

然后在我的音频生成类中,我有一个循环(带计数器)从波形发生器生成样本。每次我需要播放新样本时,它都会根据上面的 NotePhrase.getFrequency(int counter) 方法设置波形的频率。这应该(我还没有真正测试过!)只是根据频率和幅度(待添加)播放NotePhrase旋律。

问题是,它看起来不是很优雅,更具体地说,很难以任何一种清晰的方式“写”一段旋律。我必须编写一大堆新的 Note 对象,然后用它们的数组构造一个 NotePhrase 对象……我不太清楚我将如何硬编码这些旋律,然后稍后在它们之间轻松切换。

我真的很想创建一个旋律枚举或类似的东西,在这里我可以轻松地为每个不同的旋律硬编码一个人类可读的配置,然后当我想使用它们时,只需将枚举类型传递给音频播放器...

我得到的最好的是:

private static enum Melody {
NOKIA_RINGTONE ( new Note(EqualTemperamentTuning.E_5, 0.5, 1), new Note(EqualTemperamentTuning.D_5, 0.5, 1))
;

private Note[] notes = new Note[2];

Melody (Note note1, Note note2){
this.notes[0] = note1;
this.notes[1] = note2;
}
}

然后我会在运行时将其加载到 NotePhrase 对象中。这不是很好,因为我必须为具有不同音符数量的旋律创建一个新的构造函数。如果我反过来做,用一组音符构造枚举,那么我只是在别处和两部分中“写”旋律,这看起来更令人困惑......

所以我对如何正确构建它感到困惑?即要创建什么类以及它们应该包含什么信息......我想得到这个“正确”因为,我可能想在未来扩展符号以包括效果(回声等)并且我已经找到了我的非常很少有人知道正确的类、结构和关系(甚至名称)可以使我的程序非常容易或难以理解。

很抱歉这篇文章,这可能不是一个措辞很好(咳咳)的问题,但作为 Java 和 OOP 的初学者,任何提示都将非常受欢迎!

编辑**

感谢您的回答和建议,非常有帮助。考虑在这种情况下给出的答案促使我重新考虑我的一般音频实现,它现在非常不稳定。不过不确定我应该将谁标记为正确,因为我真的只是想采纳所有建议并尝试从那里开始。

最佳答案

不要对旋律使用枚举,因为旋律不代表真正的常量,而是音符数据的集合。我建议不要使用数组,而是使用 ArrayList<Note>哪个更灵活。

在 Melody 中,我会将音符与小节和节拍相关联,并且会给 Melody 类一个 addNote(Note, int measure, int beatFraction),删除音符也是如此。

考虑将您的 12 个核心笔记作为枚举,然后使用它们加上一个 Octave 整数来创建一个笔记对象。

...有很多方法可以玩这个练习。 “关键”是不断尝试。

关于java - 如何在 java 中创建一个简单但结构良好的乐谱类(乐谱)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10723832/

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