探索声音与编程的结合

在人机交互的设计中,声音往往被视觉所掩盖,但它却是不可或缺的一部分。声音波是一种机械波,其物理特性为提供了丰富的应用可能性。

软件工程师用0和1构建他们的乌托邦,而音乐家用音符构建他们的伊甸园。当编码与音乐相遇时,会产生奇妙的化学反应。音乐可以丰富软件的用户体验,而编码则让人们更深入地了解音乐的结构。

音乐的构成

旋律由各种音符组成,而音符的时间值和音高是最重要的属性。下面将介绍如何使用JavaScript创建一个音乐音符。

人们能够识别不同音高的音符,因为每个音符都有其特定的频率。根据Web Audio API,可以创建一个振荡器节点,该节点可以生成具有特定频率的声波。可以尝试以下代码:

var context = new webkitAudioContext(), osc = context.createOscillator(); osc.frequency.value = 440; osc.connect(context.destination); osc.start(0);

上述代码创建了一个频率为440赫兹的振荡器。根据十二平均律,440赫兹是'LA'音符的频率。在十二平均律中,将八度音分为12个相等的部分,半音的宽度,即两个相邻音符之间的频率比,是2的12次方根。因此可以计算出其他音符的频率。

var MusicalAlphabet = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B'], freqChat = {}, freqRange = 3, i, j, base; for (i = 1; i < freqRange; i++) { freqChat[i] = {}; base = (i - 1) * 12; for (j = 0; j < 12; j++) { freqChat[i][MusicalAlphabet[j]] = 440 * Math.pow(2, (base + j - 9) / 12); } }

建议在脚本开始时计算所有音符的频率。现在,可以获取每个音符的音高。下一步是处理时间值。最简单的方法是使用振荡器节点的'stop'和'start'函数。

var context = new webkitAudioContext(); var osc = context.createOscillator(); osc.frequency.value = 440; osc.connect(context.destination); var _c = context.currentTime; osc.start(_c + 1); osc.stop(_c + 2);

可能已经注意到变量_c。在Web音频的上下文中,它有自己的时间线。上下文的'currentTime'属性是访问这个时间线的唯一方式。所有上下文的节点都按照这个时间线播放。'start'函数需要一个参数来定义振荡器节点的开始时间。如果这个参数小于context.currentTime,'start'函数将立即执行。

不幸的是,每个实例的'start'函数只能调用一次。这意味着一旦调用了'stop'函数,将不得不创建一个新的实例来播放相同的音符。因此,推荐另一种解决方案。关键是增益节点。通过增益节点,可以控制振荡器节点的信号强度。如果曾经玩过吉他放大器,可能会更好地理解这个节点。

var context = new webkitAudioContext(), gain = context.createGain(), osc = context.createOscillator(), _c = context.currentTime; osc.frequency.value = 440; gain.gain.value = 0; osc.connect(gain); gain.connect(context.destination); osc.start(_c); gain.gain.setValueAtTime(1, _c + 1); gain.gain.setValueAtTime(0, _c + 2);

上面的代码可以在1秒到2秒之间播放'La'(C大调)音符。可以将gain.gain.value的值从0设置为1。当这个值设置为0时,它就像调用了'stop'函数一样。下面的图片显示了信号的变化。

除了'setValueAtTime'函数外,增益节点还有一些其他方法可以改变其值。可以在Web音频API中找到它们。

到目前为止,应该能够通过JavaScript在一段时间内播放一个音乐音符。但是要实现一个音乐作品,还有很多事情要做。在本文的下一部分,将教如何使用名为'Jsonic'的JavaScript框架创建一个音乐作品。

使用Jsonic播放音乐作品

Jsonic是一个小巧且功能丰富的JavaScript库。通过Jsonic,可以创作音乐,通过超声波传输数据,使声波可视化,进行语音识别等。可以从jsonic.net或github获取Jsonic。

上面的图片显示了Jsonic旋律模块的结构。需要创建一个Track或TrackGain的实例来播放音乐作品。音乐作品由许多音符组成。让继续看详细的代码。

var note = new Jsonic.Melody.Note(1, 1/4, 0, false);

根据上面的代码,可以创建一个音乐音符。在Jsonic中,每个Jsonic.Melody.Note的实例都指的是一个音乐音符。Note的构造函数可以接受4个参数。第一个是角色名,第三个参数定义了这个音符所在的八度。Jsonic.Melody.Note使用角色名(0,1,2,3,4,5,6,7)来创建实例,这样就可以在MusicScore中轻松地改变音调。如果想得到中央C,第三个参数应该是0。第二个参数定义了音符的时间值(1,1/2,1/4,1/8,1/16)。MusicScore的速度是另一个影响音符实际时间值的元素。第四个参数定义了这个音符是否有点。

var musicScore = new Jsonic.Melody.MusicScore('C', 'major', '4/4');

当创建一个MusicScore的实例时,可以定义它的音调和节拍。上面的代码创建了一个4/4的C大调音乐作品。这里应该使用音乐字母表。

创建音乐作品后,可以按照以下代码将音符添加到音乐作品中:

musicScore.w(new Jsonic.Melody.Note(3), new Jsonic.Melody.Note(4));

函数'w'会将其所有参数追加到音乐作品的末尾。下一步是创建一个Track或TrackGain的实例来播放音乐作品。但应该先调用'compile'函数。

musicScore.compile();

正如在本文开头提到的,有两种方式来控制音符的时间值。Track和TrackGain分别对应这两种方式。

var track = new Jsonic.Melody.Track(); track.play(musicScore, 90);

上面的代码创建了一个轨道并播放了一个速度为90的音乐作品。速度的值指的是节拍器中的数据。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485