7

我正在做一些双耳节拍的工作,并正在尝试构建一个 Java 应用程序,它可以以稍微不同的频率播放两种声音......大约 25-30Hz 的差异。

在一个完美的世界里,我想给 Java 两个整数输入,比如 440 和 410,让 Java 播放一个 440Hz 的音调和一个 410Hz 的音调。

鉴于我在javax.sound.*课堂上看到的情况,Java 似乎只支持相当于钢琴音符...A4 @ 440Hz,然后是 A-sharp-4 @ 466.164Hz,而在另一个方向上,G-sharp-4 @ 415.305Hz。虽然“相邻”通常在产生双耳节拍的范围内,但我正在尝试对我的音调频率进行更多控制。

由于简单的音频合成只不过是频率、强度和时间长度,在我看来,在javax.sound.*课程的某个地方,有某种查找说明当我告诉 Java 播放“A4”时,那就是440赫兹。问题变成了是否有办法破解该表以说“A4.1”相当于449Hz。

我一直在搞砸javax.sound.midi,还没有探索过javax.sound.sampled;看来我需要对我的音调进行采样才能使用这些sampled课程;我更喜欢合成。如果我弄错了,请引导我。

我见过的大多数第三方界面都是专门针对音乐制作和操作的,因此,它们使用微音的能力有限。有没有人有解决方案的经验或建议?

4

2 回答 2

5

您可以使用中的类生成样本并将它们发送到声卡javax.sound.sampled.*;基本上创建一个软件振荡器。

它需要一些知识,但是当你开始工作时会很有趣;)

当我创建这个时,我正在玩这些分类:http: //bobusumisu.net/testing/bobusynth-alpha1/

这是让我入门的教程:http ://www.drdobbs.com/jvm/230500178

于 2012-05-24T00:08:02.027 回答
4

这只是为了补充已经提供和接受的答案(我给了+1)。

You can use wavetables as an alternative to running trig functions on the fly--sort of half sampled/half synthesized. I also use a sine wave table with six independent cursors pointing into it for FM synthesis, and have duplicated several Yamaha DX7 patches this way. But this is all done via javax.sound.sampled. Once a soft-synth has been built, you might want to control it with the midi library classes.

Let's say you populate a 1K array with floats for a single sine wave.

If you "play" the wave table by incrementing and looping through it and extracting each array member in turn (to write to the sound card via a SourceDataLine), you will get a pitch directly related to your sample rate. For 44100 samples per second, the 1024-member array will cycle 44100/1024 = 43.066... times in to fill that "second" with data (a very low pitch--roughly 43 Hz). If you skip every second table member, the pitch is twice that, etc. To get the pitch 440, one needs to find the correct "increment" to use to step through the wave table array, which can be found: incr = (size of waveTable * desired pitch) / sample rate

For example (1024 * 440 ) / 44100 gives an increment of: 10.21678... Thus, if the first value from the waveTable is at array location 0, the second value to be used would be in between locations 10 and 11. To get a value that lies in between two array locations, use linear interpolation.

I use this method, with javax.sound.sampled libraries, for a "Theremin" at this link. There is a keyboard displayed, but you can easily hear/see microtonal control as you move the mouse across the keys.

http://www.hexara.com/VSL/JTheremin.htm

In the above, the mouse position (called via MouseMotionListener) is used to calculate desired pitch via this function:

return Math.pow(2, ((mouseX + tuningLoc) / (octaveWidth)));

where octaveWidth is the number of pixels that covers an octave.

于 2012-05-24T20:44:09.140 回答