カテゴリー別アーカイブ: Sound

Action Audio APIのモジュール追加

ActionScript 3.0でWeb Audio APIをシミュレートするライブラリであるAction Audio APIに, AudioBuffer.as と AudioBufferSourceNode.as を追加しました.

また, AudioContextインスタンスにdecodeAudioDataメソッドも追加しました.

使い方はほとんどWeb Audio APIと同じです. ただし, decodeAudioDataの第1引数にはSoundインスタンスを指定します.

import flash.events.Event;
import flash.media.Sound;
import flash.net.URLRequest;
import audioapi.AudioContext;
import audioapi.AudioBuffer;
import audioapi.audionodes.AudioBufferSourceNode
import audioapi.audionodes.GainNode;

var context:AudioContext = new AudioContext(stage.frameRate);

trace(context.sampleRate);

var gain:GainNode = context.createGain();

var sound:Sound = new Sound();

sound.addEventListener(Event.COMPLETE, function(event:Event):void {
    context.decodeAudioData(sound, function(audioBuffer:AudioBuffer):void {
        var source:AudioBufferSourceNode = context.createBufferSource();

        source.buffer = audioBuffer;

        source.connect(gain);
        gain.connect(context.destination);

        source.start();
    }, function():void {
    });
}, false, 0, true);

sound.load(new URLRequest('sample.mp3'));

ActionScript 3.0 オーディオのループ再生

ActionScript3.0でオーディオをループ再生するには, SoundChannelインスタンスのEvent.SOUND_COMPLETEイベントを監視する.

var sound:Sound = new Sound();

sound.addEventListener(Event.COMPLETE, function(event:Event):void {
    var loop:Boolean = true;
    var rate:Number         = sound.bytesTotal / sound.bytesLoaded;
    var durationMsec:Number = sound.length / rate;  // msec
    var duration:Number     = Math.floor(durationMsec / 1000);  // msec -> sec

    var channel:SoundChannel = sound.play();
    var currentTimeMsec:Number = channel.position;  // msec
    var currentTime:Number     = currentTimeMsec / 1000;  // msec -> sec

    channel.addEventListener(Event.SOUND_COMPLETE, function(event:Event):void {
        if (loop) {
             channel = sound.play(0);
        } else {
             channel.stop();
        }
    }, false, 0, true);
try {
    sound.load(new URLRequest('sample.mp3'));
} catch (error:Error) {
    trace(error.message);
}

ActionScript 3.0 Soundインスタンスから時間関連の値を取得する

まずは, オーディオのトータル時間, つまり, HTML5のHTMLAudioElementのdurationプロパティに相当する値

var sound:Sound = new Sound();

sound.addEventListener(Event.COMPLETE, function(event:Event):void {
    var rate:Number         = sound.bytesTotal / sound.bytesLoaded;
    var durationMsec:Number = sound.length / rate;  // msec
    var duration:Number     = Math.floor(durationMsec / 1000);  // msec -> sec
}, false, 0, true);

try {
    sound.load(new URLRequest('sample.mp3'));
} catch (error:Error) {
    trace(error.message);
}

オーディオの現在再生位置, つまり, HTML5のHTMLAudioElementのcurrentTimeプロパティに相当する値.
これは, SoundChannelインスタンスのポジションプロパティにアクセスするだけです. ただし, これはmsec単位なので, sec単位で取得したい場合は, 変換が必要です.

var sound:Sound = new Sound();

sound.addEventListener(Event.COMPLETE, function(event:Event):void {
    var rate:Number         = sound.bytesTotal / sound.bytesLoaded;
    var durationMsec:Number = sound.length / rate;  // msec
    var duration:Number     = Math.floor(durationMsec / 1000);  // msec -> sec

    var channel:SoundChannel = sound.play();
    var currentTimeMsec:Number = channel.position;  // msec
    var currentTime:Number     = currentTimeMsec / 1000;  // msec -> sec
}, false, 0, true);

try {
    sound.load(new URLRequest('sample.mp3'));
} catch (error:Error) {
    trace(error.message);
}

ActionScript 3.0 オーディオビジュアライザーのクラス

ActionScript 3.0 でオーディオビジュアライザーのクラスを作成してみた.

実質的に波形描画を担うのは, AnalyserNode.asのほうです.

使い方はこんな感じ.

import classes.AudioVisualizer;

var options:Object = {
    left   : 120,
    right : 120,
    fft    : false
};

var visualizer:AudioVisualizer = new AudioVisualizer('sample.mp3', options);

addChild(visualizer);

スペクトルを表示したい場合は, オプションのfftをtrueにする.

ActionScript 3.0 オーディオ再生のためのクラス

ActionScript 3.0でオーディオ再生のためのクラスを作成してみた.

使い方はこんな感じ

import flash.events.Event;
import flash.events.ProgressEvent;
import flash.events.IOErrorEvent;
import flash.events.MouseEvent;
import flash.events.KeyboardEvent;
import flash.ui.Keyboard;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;
import flash.text.TextFormatAlign;
import classes.Audio;

var audio:Audio = new Audio();

var progress:TextField = null;
var duration:String    = '00 : 00';
var currentTime:String = '00 : 00';

audio.onprogress = function(event:ProgressEvent):void {
    var rate:Number = Math.floor(event.bytesLoaded * 100 / event.bytesTotal);

    if (progress == null) {
        var textFormat:TextFormat = new TextFormat();
        textFormat.font  = 'Helvetica';
        textFormat.size  = 24;
        textFormat.color = 0x999999;
        textFormat.align = TextFormatAlign.CENTER;

        progress                   = new TextField();
        progress.autoSize          = TextFieldAutoSize.LEFT;
        progress.defaultTextFormat = textFormat;

        addChild(progress);
     }

    progress.text = rate + ' %';
};

audio.onerror = function(event:IOErrorEvent):void {
    var textFormat:TextFormat = new TextFormat();
    textFormat.font = 'Helvetica';
    textFormat.size = 24;
    textFormat.color = 0x999999;
    textFormat.align = TextFormatAlign.CENTER;

    var error:TextField    = new TextField();
    error.defaultTextFormat = textFormat;
    error.text              = event.text;

    addChild(error);
};

audio.oncanplay = function(event):void {
    stage.addEventListener(MouseEvent.CLICK, function(event:MouseEvent):void {
        if (audio.paused) {
            audio.play(audio.currentPosition);
        } else {
            audio.pause();
        }
    }, false, 0, true);
};

audio.ondurationchange = function(event:Event):void {
    var minutes:String = ('0' + Math.floor(audio.duration / 60)).slice(-2);
    var seconds:String = ('0' + Math.floor(audio.duration % 60)).slice(-2);

    duration = minutes + ' : ' + seconds;

    progress.text = currentTime + ' / ' + duration;
}

audio.ontimeupdate = function():void {
    var minutes:String = ('0' + Math.floor(audio.currentTime / 60)).slice(-2);
    var seconds:String = ('0' + Math.floor(audio.currentTime % 60)).slice(-2);

    currentTime = minutes + ' : ' + seconds;

    progress.text = currentTime + ' / ' + duration;
};

audio.onended = function(event:Event) {
    currentTime = '00 : 00';
}

stage.addEventListener(KeyboardEvent.KEY_DOWN, function(event:KeyboardEvent):void {
    switch (event.keyCode) {
        case Keyboard.UP :
            audio.volume += 0.05;
            break;
        case Keyboard.DOWN :
            audio.volume -= 0.05;
            break;
        case Keyboard.LEFT :
            audio.pan -= 0.1;
            break;
        case Keyboard.RIGHT :
            audio.pan += 0.1;
            break;
        case Keyboard.SPACE :
            audio.muted = !audio.muted;
            trace('MUTE : ' + audio.muted);
            break;
        case Keyboard.SHIFT :
            audio.loop = !audio.loop;
            trace('LOOP : ' + audio.loop);
            break;
        case Keyboard.PERIOD :
            audio.currentTime += 1;
            break;
        case Keyboard.COMMA :
            audio.currentTime -= 1;
            break;
        default :
            break;
    }
}, false, 0, true);

audio.src = 'sample.mp3';

addChild(audio);

HTML5 AudioをシミュレーションするようなAPIにしています.

ActionScript 3.0 Microphoneを利用するためのクラス

Flash PlayerでMicrophoneからの入力を視覚化するためのクラスを作成してみました.

使い方は, コンストラクタにstageを渡すだけでOKです.

import classes.MediaStream;

var stream:MediaStream = new MediaStream(stage);

Microphoneの設定を変更する場合は, コンストラクタの残りの引数を指定します.
また, アニメーション (視覚化) の設定を変更するには, setDrawSettingsメソッドを呼び出します.