AS3でwavファイルをEmbedしたりエフェクトかけたり(要POPFORGE)

FlashIDE(FlashCS3)だとライブラリにwavファイルを追加してリンケージすることによって、Embed可能だけど、Flex環境というか.asファイルにwavファイルのEmbedは不可能。(だと思うけど違っていたら教えてください)

そこでバイナリーとして読み込んでPOPFORGEで復元、再生することにした。

派生物として、サウンドの生データが取得できるのでそれにフィルターをかけてやるとエフェクトをかけることも可能。やる気出せばサウンドへのリアルタイムエフェクトの可能性が見えるかも。

もともとはPOPFORGEでオリジナルの音源を使って、ストリームを生成させることが目的だったんだけど、Voiceクラスを解析するのがかなり大変そうなので、泥臭いがシンプルな方法を模索しているウチに上記の様な事になった。いつの日かドップラー効果やリバーブ、ディストーションをグリグリかけられるようになるかも。

フローは以下の形。
1.バイナリーとしてwavを読み込み、Class化
2.バイトコードを取得
3.fromByteArrayにバイトコードを渡す
4.再生
*エフェクトのサンプルとして1オクターブ高くなるeffect()が付随


package
{
  import de.popforge.audio.output.Audio;
  import de.popforge.audio.output.SoundFactory;
  
  import flash.display.Sprite;
  import flash.media.Sound;
  import flash.utils.ByteArray
  import flash.utils.Endian
  

  public class SirenASound_REF extends Sprite
  {
    
    //バイナリーとしてwavを読み込み、Class化
    [Embed(source="wav/siren_short.wav", mimeType="application/octet-stream")]
    public static const Song:Class;
    
    //wavファイルヘッダー部分のoffset
    public static const WAV_HEADER_END:uint = 44
    
    public function SirenASound_REF(){
      init();
    }
    
    private function init(): void {
      //バイトコードを取得
      var bytes:ByteArray = getByteArray()    
      var array:Array = byteArray2Array(bytes)
      
      //effectの有無 1オクターブ高くなる
      //array = effect(array)
      //var bytes2:ByteArray = array2ByteArray(array)
      
      //fromByteArrayにバイトコードを渡す
      SoundFactory.fromByteArray(bytes,Audio.STEREO, Audio.BIT16, Audio.RATE44100, onSoundGenerated );
    }
    
    private function onSoundGenerated( sound: Sound ): void {
      //再生
      sound.play();
    }
    
    private function getByteArray():ByteArray {
      var bytes:ByteArray = new ByteArray()
      bytes.endian = Endian.LITTLE_ENDIAN
      var wavData:ByteArray = new Song() as ByteArray
      bytes.writeBytes(wavData, WAV_HEADER_END)
      bytes.position = 0    
      return bytes;
    }
    
    private function byteArray2Array(bytes:ByteArray):Array {
      var array:Array = new Array()
      while(bytes.position < bytes.length-1){array.push(bytes.readShort())}      
      return array;
    }
    private function array2ByteArray(array:Array):ByteArray {
      var bytes:ByteArray = new ByteArray()
      bytes.endian = Endian.LITTLE_ENDIAN
      for each(var index:int in array){bytes.writeShort(index)}      
      bytes.position = 0
      return bytes;
    }
    
    private function effect(sample:Array):Array {
      var array:Array = new Array()
      for (var i:int = 0; i < sample.length;i+=2){
        array.push(sample[i])
      }
      
      return array
    }
  }
}

* http://qurage.net/labo/as2html/ でコードフォーマットさせていただきました

サンプルファイル

Trackback

http://memo.kappa-lab.com/mt-tb.cgi/140

Comment (2)

通りすがり : 2009 .07 .04

昔の記事にコメントするのもどうかとは思いますが、
検索で辿り着いた人向けにメモ。

MP3でもWavでもEmbed出来ます。以下サンプルコード(抜粋)

// Classの宣言(Extern的な)
[Embed(source='Sample.mp3')]
private static var SampleSound:Class;

// こちらがメンバ
private var snd:Sound;

public function Main():void {
 this.snd = new SampleSound() as Sound;
 addEventListener(MouseEvent.CLICK, onClick);
}

private function onClick(e:MouseEvent):void {
 this.snd.play();
}


ちなみに、POPFORGEというライブラリは知らないのですが、
プラグイン拡張でも無い限り、それらのライブラリも全てAS3上で同じ立場で記述されている
(=ソースライブラリ)なので、「他で出来るなら自分でも」出来ます。

※記事中「ASで出来ない、ライブラリで出来る」のような記述があった為補足

補足に補足します : 2009 .07 .11

MP3の埋め込みは通りすがりさんのように行うことができますが、
現在(Flex SDK3.2、Flash10)ではWAVを埋め込んでSoundクラスに
変換する機能はありません。

ただし、SWFに埋め込まれたWAVを参照してSoundクラスに変換することは可能です。
POPFORGEではバイナリのSWFを埋め込み、そのSWFにサウンドデータを書き込んで
Loaderクラスのloadbytesを使って変換してからSoundクラスに変換しています。

WAV再生を自分で0から実装するにはWAVとSWFのフォーマット、ActionScriptの
制限を熟知し、その制限の中でできるように努力する必要があります。

Leave your comment :

(いままで、ここでコメントしたことがないときは、コメントを表示する前に承認が必要になることがあります。そのときはしばらくお待ちください。)




RSS + Contuct

  • rss
  • email

Credit

Copyright (C) 2007 kappa-lab.com.
All Rights Reserved.