feb19.jp

Nobuhiro Takahashi
Designer / Engineer

Flash Player 10 Astroを予習。Dynamic Sound Generate編 #2

Flash Player 10 Astroを予習。Dynamic Sound Generate編 #2 チャルメラ編

音をFlashPlayerで生成して鳴らすことができるようになったので、その音の音階(高さ)や音価(長さ)を変化させて、一つ簡単なメロディーを演奏させてみたいと思います。

2008.10.28追記
> 最新のFlash Player 10に対応しました。

今回は伝説のあの楽曲、「チャルメラ」を演奏させてみます。

一応、譜面を作ってみました。アストロ・チャルメラです。

テンポ(一分間に四分音符が鳴る数)は、120とします。

それではコードとサンプルデモをどうぞ。

AstroDynamicSoundTest2.as
 
package 
{
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.SampleDataEvent;
	import flash.events.TimerEvent;
	import flash.media.Sound;
	import flash.media.SoundChannel;
	import flash.utils.Timer;
	public class AstroDynamicSoundTest2 extends Sprite
	{
		private var sound:Sound;
		private var ch:SoundChannel;
		private var timer:Timer;
		
		private var G3:Number = 391.995;
		private var A4:Number = 440.000;
		private var B4:Number = 493.883;
		
		private var pitch:Number = 0;
		private var volume:Number;
		
		private var samplingRate:uint = 44100;
		private var bufferSize:uint = 2048;
		
		public function AstroDynamicSoundTest2()
		{
			// プリロード
			this.loaderInfo.addEventListener(Event.COMPLETE, loadCompleteHandler);
		}
		private function loadCompleteHandler(event:Event):void
		{
			this.loaderInfo.removeEventListener(Event.COMPLETE, loadCompleteHandler);
			
			sound = new Sound();
			sound.addEventListener(SampleDataEvent.SAMPLE_DATA, onSampleDataHandler);
			ch = sound.play();
			
			var bpm:Number = 120;
			var bps:Number = 60 / bpm;
			var tick:Number = bps * 1000;
			tick /= 4;	//for 16note
			tick = Math.round(tick);
			
			var duration:uint = 27;
			
			volume = .2;
			
			timer = new Timer(tick, duration);
			timer.start();
			timer.addEventListener(TimerEvent.TIMER, function (e:TimerEvent):void
			{
				var target:Object = e.currentTarget;
				switch(target.currentCount)
				{
					case 1:
					case 10:
					case 14:
					case 18:
						volume = .2;
						pitch = G3;
						break;
					case 2:
					case 9:
					case 15:
					case 17:
					case 19:
					case 20:
					case 21:
					case 22:
					case 23:
					case 24:
					case 25:
					case 26:
						volume = .2;
						pitch = A4;
						break;
					case 3:
					case 4:
					case 5:
					case 6:
					case 7:
					case 8:
					case 16:
						volume = .2;
						pitch = B4;
						break;
					case 11:
					case 12:
					case 13:
						volume = 0;
						break;
					
				}
				if (duration <= target.currentCount) {
					ch.stop();
					target.removeEventListener(TimerEvent.TIMER, arguments.callee);
				}
			});
		}
		private function onSampleDataHandler(e:SampleDataEvent):void
		{
			var freq:Number = (Math.PI * 2) * pitch / samplingRate;
			for (var c:int = 0; c < bufferSize; c++)
			{
				var sample:Number = Math.sin(Number(c + e.position) * freq) * volume;
				e.data.writeFloat(sample);
				e.data.writeFloat(sample);
			}
		}
	}
}

サンプルデモ(Flash Player 10 beta 2が必要です)

アストロ・チャルメラです(サイン波でソラシーラソ、ソラシラソラーって言ってるだけですけど)。

構造としては、前回のサンプルに、Timerを加えて、時間に応じて、音階や音量を変化するというもの。

ちなみに音価は、タイマーのカウントで表しています。

タイマーのカウント間隔を計算するには、四分音符の長さをテンポ(bpm)から割り出す必要があります。単純に四分音符が刻まれている間隔を知りたいだけなら、テンポ(一分間に鳴らされる四分音符の数)から1分間=60秒を割って、それをミリ秒で表せば、FlashのTimerでその間隔を計ることができます。

このサンプルは、タイマーの1カウント = 16分音符になっていて、たとえば四分音符を表したいときは、4カウント使う必要があります。なので、四分音符の間隔からさらに今回は「4」で割っています。

これは、分解能が4である、「ステップシーケンサー」と呼ばれる作曲ソフト、音楽機材とほぼ同じ方式です。

また、休符はとりあえず音量(波形の振幅)を0にすることで、それっぽくしています。

これで簡単なメロディーは作れるようになりました。なんか、着メロ作ってる気分ですね。単音の。

Tweet Share Bookmark

Navigation

prev: Flash Player 10 Astroを予習。Dynamic Sound Generate編 #1
next: JavaScriptで、FlashPlayerのバージョンを判別する

Recently Entries