如何在Java声音中连续改变音高?
Posted
技术标签:
【中文标题】如何在Java声音中连续改变音高?【英文标题】:How to change pitch continuously in Java sound? 【发布时间】:2010-01-10 05:34:43 【问题描述】:我正在使用 Java 声音 API 处理 midi。基本上我试图实现滑音效果,我可以在不同的音符之间滑动。我得到的最接近的是在 MidiChannel 中使用 setPitchBend() 方法。但是,这只允许从我开始的音符开始的 2 个半音范围内。有没有其他方法可以实现这种滑音效果,或者改变弯音范围?
如果JFugue 有办法实现这一点,那也是可以接受的。
【问题讨论】:
【参考方案1】:JFugue 支持微音。 (它是通过 JavaSound API 完成的,并结合了大量的数学知识)
它是否可以完全满足您的要求是另一个问题。我相信你会遇到的问题是你弹奏的每个新音符听起来都像是一个新音符,而不是一堆捆绑在一起的音符。当一个音符的起音和衰减值不是 0 时,或者乐器在音符的开头和结尾处具有固有的不同声音时,这一点尤其明显。
在 JFugue 中,您可以通过在音符后添加 'a' 和 'd' 以及 0-128 的值来设置音符的起音和衰减:
C5wa0d0
- C-note,第 5 个八度,整个持续时间,起音 = 0,衰减 = 0。
当前编写的微音助手允许您为字符串定义单个频率;例如,您可以将 400 映射到“A400”。然后要使用它,你会说player.play("[A400]w")
(注意括号)。
获得所需内容的一种方法是为所需的多个微音定义频率和字符串,然后使用 for 循环创建模式...Pattern p = new Pattern("[A400]wa0d0 [A410]wa0d0 [A420]wa0d0"...);
您可能使用大于 1 赫兹的步长对于每个音符,因为我们的耳朵无法区分如此细微的频率差异。
如果有更优雅的解决方案就好了!但看看这是否有帮助。
【讨论】:
谢谢,这听起来是正确的做法。然而,出于某种原因,攻击速度似乎是音量的同义词。 a0 根本听不见,a5 几乎听不见,依此类推。我尝试了几种不同的连续乐器(长号、中提琴等),结果都是一样的 它与音量不同,但我想我明白这里发生了什么 - 说 attack=0, decay=0 并没有给乐器足够的时间来达到最大音量来播放音符。尝试不带 a/d 并使用较短的持续时间(如 64 分音符 - JFugue 中的“s”),看看是否有帮助。【参考方案2】:MIDI 具有用于音高幻灯片的滑音控制。尝试调用controlChange(65,127)
打开portametno 控件,然后播放两个音符。 controlChange(5, xxx)
应该改变音高滑动的速度。 controlChange(65,0)
将关闭滑音。
【讨论】:
【参考方案3】:只是一个猜测 - 你能演奏出两个连续音高的音符,并在你淡出另一个音符的同时淡入一个音符吗?
【讨论】:
我尝试了这种技术,并且一直在使用不同的值进行测试,但它只是不一样。两个音符相距太远。为了正确模拟弯音的渐变,需要微音音符,Java 声音 API 不支持。【参考方案4】:这可能已经过时了 - 自从我放弃 MIDI 并改用无品贝司以来已经将近二十年了 - 但是对于更长的幻灯片,您过去必须演奏一个音符,将它的音高弯曲到中途下一个音符,然后弹奏下一个音符 音符向下弯曲一半,使它们以相同的音高相遇,然后重复该过程。
【讨论】:
【参考方案5】:弯音控制只是定义了一个范围;如何解释它取决于接收端(例如合成器)。如果接收端支持两个半音,那么你会得到两个半音 - 除非它可以重新配置!在大多数合成器上,您可以重新配置弯音范围;你的目标设备是什么?
(我不熟悉JFugue。)
【讨论】:
以上是关于如何在Java声音中连续改变音高?的主要内容,如果未能解决你的问题,请参考以下文章