我正在尝试仅使用6个音频剪辑来重新创建吉他的全部范围。
我当时在想有一种方法可以设置音频剪辑的频率,但是audio.frequency仅基于压缩格式而不是实际音调返回音频的频率。
我知道我可以阅读GetSpectrumData,但是该解决方案相当复杂,需要进行傅里叶变换分析或类似的分析。
影响音高,更改音调很容易,因此我可以上下移动,但是有一种方法可以弄清楚要使用的步骤。
void Update ()
{
CheckAudio(KeyCode.Q, 1.0f);
CheckAudio(KeyCode.W, 1.1f);
CheckAudio(KeyCode.E, 1.2f);
CheckAudio(KeyCode.R, 1.3f);
CheckAudio(KeyCode.T, 1.4f);
}
void CheckAudio(KeyCode key, float pitch)
{
if (Input.GetKeyDown (key))
{
audio.pitch = pitch;
audio.Play ();
}
}
我听到声音听起来不正确。
知道初始音调为E4 329.63Hz且音高为1时,是否有任何影响音高的方程式,我会得到下一个键F4 349.23Hz(或足够接近)吗?
还必须考虑到Unity AudioSource将音高限制在-3/3范围内(我认为这超出了需要)。
编辑:添加一些个人研究。音高1似乎是初始音符,将音高1设置为2可使同一音调高 Octave 。
由于半音阶(钢琴上的所有黑白音符)是12个琴键,因此我假设对每一步使用1/12即可。
听起来很近,但我倒是不太对。这是新的代码:
[SerializeField] private AudioSource audio;
float step = 1f/12f;
KeyCode[]keys = new KeyCode[]{
KeyCode.Q, KeyCode.W,KeyCode.E,KeyCode.R,KeyCode.T,
KeyCode.Y, KeyCode.U, KeyCode.I, KeyCode.O, KeyCode.P,
KeyCode.A, KeyCode.S, KeyCode.D
};
void Update ()
{
float f = 0.0f;
foreach (KeyCode key in keys)
{
CheckAudio(key, f);
f += 1f;
}
}
void CheckAudio(KeyCode key, float pitch)
{
if (Input.GetKeyDown (key))
{
audio.pitch = 1f + pitch * step;
audio.Play ();
}
}
最佳答案
您要尝试执行的操作仅更改音频的音调,就不能使不能很好地工作。通过更改音调,您会遇到其他问题,例如声音音调过快或需要花费更多的时间来完成,声音也不佳。
的第一个解决方案是在 C++ 中制作一个插件( Synthesizer ),该插件可从Unity读取音频文件并更改频率。它还应执行其他操作来解决速度问题。除非您是一位具有出色数学技能的音频工程师,否则这将非常复杂。而在移动设备上进行尝试则完全不同。 OnAudioFilterRead是您决定使用此方法时应使用的函数。
第二个和推荐的解决方案是为每个吉他琴键制作的音频文件,然后将它们放入audioClip
数组。这可以解决的每个其他问题。不利的一面是,您将还有个文件。
编辑:
如果您不关心它是否完美,则可以在internet上使用以下来自这个好人的东西。void playSound(){
float transpose = -4;
float note = -1;
if (Input.GetKeyDown("a")) note = 0; // C
if (Input.GetKeyDown("s")) note = 2; // D
if (Input.GetKeyDown("d")) note = 4; // E
if (Input.GetKeyDown("f")) note = 5; // F
if (Input.GetKeyDown("g")) note = 7; // G
if (Input.GetKeyDown("h")) note = 9; // A
if (Input.GetKeyDown("j")) note = 11; // B
if (Input.GetKeyDown("k")) note = 12; // C
if (Input.GetKeyDown("l")) note = 14; // D
if (note>=0){ // if some key pressed...
audio.pitch = Mathf.Pow(2, (note+transpose)/12.0);
audio.Play();
}
编辑:对于那些对为什么使用Mathf.Pow方程并起作用的人感兴趣,请阅读以下内容:https://en.wikipedia.org/wiki/Twelfth_root_of_two
关于c# - AudioClip的频率和音高关系-Unity3D,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36793628/