mieki256's diary



2013/09/02(月) [n年前の日記]

#1 [haxe] Haxeで音を鳴らす実験

FlashDevelop + Haxe3 + OpenFL とやらで音が鳴らせるか実験中。一応鳴らせたように見えるけど…。

_Flash版
_html5版 (Firefox、Google Chrome、Opera は鳴る。IE10 と Safari は鳴りません)

サウンドファイルは、assets/sound/以下に入れておくとして。
.
├─assets
│  │  openfl.svg
│  │
│  ├─img
│  └─sound
│          bgm.mp3
│          bgm.ogg
│          bgm.wav
│          se1.mp3
│          se1.ogg
│          se1.wav
│          se2.mp3
│          se2.ogg
│          se2.wav

application.xml
<?xml version="1.0" encoding="utf-8"?>
<project>
    <!-- NMML reference: https://gist.github.com/1763850 -->
    
    <!-- metadata, make sure 'package' is at least 3 segments (ie. com.mycompany.myproject) -->
    <meta title="haxe_openfl_sound" package="haxeopenflsound" version="1.0.0" company="mieki256" />
    
    <!-- output -->
    <app main="Main" file="haxeopenflsound" path="bin" />
    
    <window background="#CCCCCC" fps="60" />
    <window width="640" height="360" unless="mobile" />
    <window orientation="landscape" vsync="false" antialiasing="4" if="cpp" />
    
    <!-- classpath, haxe libs -->
    <source path="src" />
    <haxelib name="openfl" />
    <haxelib name="actuate" />
    
    <!-- assets -->
    <icon path="assets/openfl.svg" />
    <assets path="assets/img" rename="img" />
    <assets path="assets/sound" rename="sound" />
    
    <assets path="assets/sound/se1.mp3" id="se1" if="flash" />
    <assets path="assets/sound/se2.mp3" id="se2" if="flash" />
    <assets path="assets/sound/bgm.mp3" id="bgm" if="flash" />
    
    <assets path="assets/sound/se1.ogg" id="se1" unless="flash" />
    <assets path="assets/sound/se2.ogg" id="se2" unless="flash" />
    <assets path="assets/sound/bgm.ogg" id="bgm" unless="flash" />
    
    <!-- optimize output
    <haxeflag name="-dce full" /> -->
    
</project>
肝(?)は、以下の部分。
    <assets path="assets/sound/se1.mp3" id="se1" if="flash" />
    <assets path="assets/sound/se1.ogg" id="se1" unless="flash" />
サウンドファイルにidを割り当てつつ、flash と flash以外で、使うファイルを変える。

Main.hx
package ;

import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.Lib;
import flash.media.Sound;
import flash.media.SoundChannel;
import flash.text.TextField;
import openfl.Assets;

/**
 * Haxe + OpenFLでサウンドを鳴らすテスト
 * @author mieki256
 */

class Main extends Sprite 
{
    var inited:Bool;

    var bgm:Sound;
    var se1:Sound;
    var se2:Sound;
    
    var sekind:Int;
    
    /* ENTRY POINT */
    
    function resize(e) 
    {
        if (!inited) init();
        // else (resize or orientation change)
    }
    
    function init() 
    {
        if (inited) return;
        inited = true;
        
        if (false) {
            // application.xml 内で使うファイルを変えた場合
            
            // BGM
            bgm = Assets.getSound("bgm");
            
            // SE read
            se1 = Assets.getSound("se1");
            se2 = Assets.getSound("se2");
        } else {
            // ソース内で使うファイルを決めていく場合
            
            var ext:String = "ogg";
            
            #if flash
            // flash出力時はここを通る
            ext = "mp3";
            #elseif html5
            // html5出力時はここを通る
            ext = "ogg";
            // ここで canPlayType() を使って対応形式を判別できれば
            // 対応ブラウザを増やせるのだけど…
            #end
            
            // BGM
            bgm = Assets.getSound('sound/bgm.$ext');
            
            // SE
            se1 = Assets.getSound('sound/se1.$ext');
            se2 = Assets.getSound('sound/se2.$ext');
        }

        // BGM 再生開始
        var channel:SoundChannel = bgm.play(0, 9999);

        #if (flash || neko)
        // 音量変更。html5出力時は利用できないみたい
        var trans = channel.soundTransform;
        trans.volume = 0.5;
        channel.soundTransform = trans;
        #end

        // 文字表示
        var tf:TextField = new TextField();
        tf.selectable = false;
        tf.text = "Click me!";
        tf.textColor = 0x333333;
        tf.width = 640;
        Lib.current.stage.addChild(tf);
        
        sekind = 0;
        
        // マウス左クリック時のイベントを登録
        Lib.current.stage.addEventListener(MouseEvent.CLICK, onMouseDown);
    }

    /**
     * マウス左クリック時の処理
     * @param e
     */
    function onMouseDown(e:MouseEvent):Void
    {
        // SEを鳴らす
        if (sekind == 0) {
            se1.play();
        } else {
            se2.play();
        }
        sekind = (sekind + 1) % 2;
    }

    /* SETUP */

    public function new() 
    {
        super();    
        addEventListener(Event.ADDED_TO_STAGE, added);
    }

    function added(e) 
    {
        removeEventListener(Event.ADDED_TO_STAGE, added);
        stage.addEventListener(Event.RESIZE, resize);
        #if ios
        haxe.Timer.delay(init, 100); // iOS 6
        #else
        init();
        #end
    }
    
    public static function main() 
    {
        // static entry point
        Lib.current.stage.align = flash.display.StageAlign.TOP_LEFT;
        Lib.current.stage.scaleMode = flash.display.StageScaleMode.NO_SCALE;
        Lib.current.addChild(new Main());
    }
}
肝は、
 se1 = Assets.getSound("se1");
 se1.play();
だろうか…。xml内で、各サウンドファイルにidを割り当ててあれば、ide文字列を指定するだけで読み込める・再生できるはず。

flash、neko で出力したら鳴ってくれた。

html5 で出力した場合は問題有り。
canPlayType() を使えれば、ブラウザで対応しているサウンドフォーマットを判別して、拡張子を変更して、対応ブラウザを増やすこともできそうなのだけど。Haxe3 でそれをやる方法が分からず。

まあ、全てのブラウザ上で音を鳴らしたいなら、Flash で出力すればいいだけの話なんだけど…。

以上です。

過去ログ表示

Prev - 2013/09 - Next
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30

カテゴリで表示

検索機能は Namazu for hns で提供されています。(詳細指定/ヘルプ


注意: 現在使用の日記自動生成システムは Version 2.19.6 です。
公開されている日記自動生成システムは Version 2.19.5 です。

Powered by hns-2.19.6, HyperNikkiSystem Project