ログイン
ユーザ名:

パスワード:


パスワード紛失

新規登録
メインメニュー
フォーラム一覧   -   トピック一覧
   ActionScript 3.0
     wavファイルを再生する方法
投稿するにはまず登録を

スレッド表示 | 新しいものから 前のトピック | 次のトピック | 下へ
投稿者 トピック
hirossy
投稿日時: 2007-3-21 13:10
ご主人様
登録日: 2006-12-14
居住地: 大阪
投稿: 123
wavファイルを再生する方法
いつもすみません

Soundクラスを利用すると、"外部"MP3を再生することができたのですが、"外部"wavファイルを再生する方法ってどなたかご存知ないでしょうか。

リファレンスには、外部"mp3"ファイルが再生できますとだけ記述されていて、他のファイル形式については書かれてないようです。

http://livedocs.adobe.com/flex/2_jp/langref/flash/media/Sound.html#includeExamplesSummary


宜しくお願いします。
kazumichi
投稿日時: 2007-3-26 7:34
ご主人様
登録日: 2006-1-10
居住地: TOKYO/JAPAN
投稿: 77
Re: wavファイルを再生する方法
実際にソースコードを書いて試した訳ではありませんが、
Flex2のSoundクラスにおいては、おそらくMP3フォーマット以外の音源ファイルは再生できないと思います。。。

「音源ファイルを再生する」ということはそれぞれの音源フォーマットに対応した音源再生プログラムをFlex2コア内に内蔵する必要があり、おそらくFlex2のSoundクラスではMP3音源再生プログラムしか実装されていないと思います。

他にもこのあたりに詳しい方いらっしゃいましたらご意見ください(^-^)/
venzou
投稿日時: 2007-3-29 18:22
ご主人様
登録日: 2007-1-25
居住地: 穴の中
投稿: 101
Re: wavファイルを再生する方法
こんばんは

Flex2はWAVには対応していないみたいですね。
しかし、SWFの仕様では、対応しているフォーマットは、

0 = uncompressed
1 = ADPCM (SWF 4 or later only)
2 = MP3
3 = uncompressed little-endian (SWF 6 or later only)
6 = Nellymoser

一方、WAVファイルのフォーマットは実は沢山あり、共通する形式に、PCM(非圧縮データ)とADPCMがあります。
(しかしADPCMも何種類か方式があり、互換があるか分りませんでした。)

という事で、PCMなら何とか変換できるのでは?と思い挑戦してみました。

取り合えず、再生出来る所まではたどりつきました。
しかし、かなり強引な方法で再生しています。
実用的なコードでは無いと思うので、開発はここまでにしようと思います。
(エラー処理とか、いい加減な状態です。)

PCM形式のWAVファイルなら再生できると思います(WindowsのWAVファイルは、ほとんどがPCM形式だと思います)。

ファイルサイズに関しては、50MByteのWAVファイルまでは動作確認しました。どこまで再生できるかは不明です。
非圧縮データを全てメモリに読み込むので、大きなファイルには適しません。

実用性は余り無いと思いますが、参考程度にどうぞ・・・

test.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" >
    <mx:Script><![CDATA[ 
    
        import WavFile;

        private var urlldr:URLLoader;
        private var swf:Loader;

        private function wavTest():void {
            //URLLoaderでWAVファイルをByteArrayに読み込む
            urlldr = new URLLoader();
            urlldr.dataFormat = URLLoaderDataFormat.BINARY;
            urlldr.addEventListener(Event.COMPLETE, wavLoaded);
            urlldr.load(new URLRequest("test.wav"));
        }
        
        private function wavLoaded(event:Event):void {
            //読み込んだWAVファイルをSWFファイルに変換
            var wav:WavFile = new WavFile();
            if(wav.loadFromByteArray(ByteArray(URLLoader(event.target).data))){
                //LoaderでSWFファイルとして読み込む
                swf = new Loader();
                swf.loadBytes(wav.swfFile);
            }else{
                db("変換に失敗しました。");
            }
            db("------------------------------------------");
            db("ファイルサイズ:", wav.fileSize);
            db("フォーマットID:", wav.formatID);
            db("チャンネル数:", wav.channel);
            db("サンプリングレート(Hz):", wav.rate);
            db("データ速度(Byte/sec):", wav.bps);
            db("ブロックサイズ:", wav.blockSize);
            db("サンプルあたりのビット数:", wav.sampling);
            db("------------------------------------------");
        }

        private function db(... arguments):void {
            for(var i in arguments){
                debug.text += arguments[i].toString();
            }
            debug.text += "\n";
        }

    ]]></mx:Script>
    <mx:TextArea id="debug" width="100%" height="100%" />
    <mx:Button id="btn" label="再生" click="wavTest();"/>
</mx:Application>


WavFile.as
package {
    public class WavFile {
        import flash.utils.*;

        //プロパティ
        public var formatID:int;
        public var channel:int;
        public var rate:uint;
        public var bps:uint;
        public var blockSize:int;
        public var sampling:int;
        public var fileSize:uint;

        public var swfFile:ByteArray;

        //WAV 定数
        private const RIFF:uint = 0x46464952;
        private const WAVE:uint = 0x45564157;
        private const FMT :uint = 0x20746D66;
        private const DATA:uint = 0x61746164;
        private const FormatID_PCM:uint = 0x0001;

        //SWF データ&定数
        private const DummyData:Array = [
            //Header
            0x46,0x57,0x53,0x06,0x00,0x00,0x00,0x00,
            0x80,0x00,0x00,0xC8,0x00,0x00,0x00,0xC8,
            0x00,0x00,0x0C,0x01,0x00,
            //SetBackgroundColor
            0x43,0x02,0xFF,0xFF,0xFF,
            //DefineShape3
            0x13,0x08,0x02,0x00,0xC0,0x00,0x00,0x00,
            0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
            0x00,0x00,0x00,0x88,0x00,
            //PlaceObject2
            0x85,0x06,
            0x02,0x01,0x01,0x02,0x00,
            //Show Frame
            0x40,0x00
        ];

        private const SwfFileSizePosition:uint = 4;

        private var StartSoundTag:Array = [
            0xC3,0x03,0x01,0x00,0x00
        ];
        
        private var EndTag:Array = [
            0x00,0x00
        ];

        private const DefineSoundTagNo:uint = 14;
        private const DefineSoundTagHeaderLength:uint = 7;
        private const SoundFormat_PCM_Little:uint = 3;

        //ByteArrayに読み込まれたWavファイルを解析する
        public function loadFromByteArray(ba:ByteArray):Boolean {
            var tag:uint;
            var len:uint;
            var tmp:uint;
            var pos:uint;
            
            var data:ByteArray = new ByteArray();

            ba.endian = Endian.LITTLE_ENDIAN;
            ba.position = 0;

            if(ba.readUnsignedInt() != RIFF){
                trace("WAV Format Error(RIFF)");
                return false;
            }
            fileSize = ba.readUnsignedInt();
            if(ba.readUnsignedInt() != WAVE){
                trace("WAV Format Error(WAVE)");
                return false;
            }
            while(ba.bytesAvailable > 0){
                tag = ba.readUnsignedInt();
                len = ba.readUnsignedInt();
                pos = ba.position;
                switch(tag){
                case FMT:
                    //fmtチャンクの読込 
                    formatID = ba.readUnsignedShort();
                    channel = ba.readUnsignedShort();
                    rate = ba.readUnsignedInt();
                    bps = ba.readUnsignedInt();
                    blockSize = ba.readUnsignedShort();
                    sampling = ba.readUnsignedShort();
                    break;
                case DATA:
                    //dataチャンクの読込
                    data.writeBytes(ba, ba.position, len);
                    break;
                }
                ba.position = pos + len;
            }
            return writeToSwfFile(data);
        }

        //読み込んだWAVファイルのデータをSWFファイルに変換
        private function writeToSwfFile(data:ByteArray):Boolean {
            var i:int;
            var tmp:int;

            //PCM形式のみ対応
            if(formatID != FormatID_PCM){
                trace("Format ID Error");
                return false;
            }

            swfFile = new ByteArray();
            swfFile.endian = Endian.LITTLE_ENDIAN;

            //SWF Dummuy Data
            for(i = 0; i < DummyData.length; i++){
                swfFile.writeByte(DummyData[i]);
            }
            
            //SWF Define Sound Tag
            //Recordheader
            if((DefineSoundTagHeaderLength + data.length) < 0x3f){
                swfFile.writeShort((DefineSoundTagNo << 6) | (DefineSoundTagHeaderLength + data.length));
            }else{
                swfFile.writeShort((DefineSoundTagNo << 6) | 0x3f);
                swfFile.writeUnsignedInt(DefineSoundTagHeaderLength + data.length);
            }
            //Sound ID
            swfFile.writeShort(1);
            //Sound Format
            tmp = SoundFormat_PCM_Little;
            //Sound Rate
            tmp <<= 2;
            switch(int(rate/5500)){
            case 1:
                break;
            case 2:
                tmp |= 1;
                break;
            case 4:
                tmp |= 2;
                break;
            case 8:
                tmp |= 3;
                break;
            default:
                trace("Sound Rate Error");
                return false;
            }
            //Sound Size
            tmp <<= 1;
            switch(sampling){
            case 8:
                break;
            case 16:
                tmp |= 1;
                break;
            default:
                trace("Sound Size Error");
                return false;
            }
            //Sount Type
            tmp <<= 1;
            switch(channel){
            case 1:
                break;
            case 2:
                tmp |= 1;
                break;
            default:
                trace("Sound Type Error");
                return false;
            }
            swfFile.writeByte(tmp);
            //Sound Sample Count
            swfFile.writeUnsignedInt(int(data.length/blockSize));
            //Sound Data
            swfFile.writeBytes(data);

            //SWF StartSound Tag
            for(i = 0; i < StartSoundTag.length; i++){
                swfFile.writeByte(StartSoundTag[i]);
            }

            //SWF End Tag
            for(i = 0; i < EndTag.length; i++){
                swfFile.writeByte(EndTag[i]);
            }
            
            //ファイルサイズの設定
            swfFile.position = SwfFileSizePosition;
            swfFile.writeUnsignedInt(swfFile.length);
            return true;
        }
    }
}

hirossy
投稿日時: 2007-3-30 0:28
ご主人様
登録日: 2006-12-14
居住地: 大阪
投稿: 123
Re: wavファイルを再生する方法
kazumichiさん
venzouさん
ありがとうございます。

やっぱりバイト読むんですね。

相当時間空けないと作れんっ!とほとんどあきらめてたんですが・・・

す、すごい!

感謝です。帰ったら即試してみます!

ありがとうございました。
試した結果をまた報告します。
hirossy
投稿日時: 2007-4-1 18:16
ご主人様
登録日: 2006-12-14
居住地: 大阪
投稿: 123
Re: wavファイルを再生する方法
venzouさん
報告が遅くなりましたが、うまく再生できました。

ちなみにvenzouさんのサンプルに以下のインポート文つけましたので、
使われる方、注意して下さい。

引用:

import flash.net.URLLoader;
import flash.display.Loader;
import flash.net.URLLoaderDataFormat;
import flash.utils.ByteArray;


ありえないくらい短い音って、
mp3では再生できなかったのでとても助かりました。
ありがとうございました。
venzou
投稿日時: 2007-4-3 13:31
ご主人様
登録日: 2007-1-25
居住地: 穴の中
投稿: 101
Re: wavファイルを再生する方法
引用:
ちなみにvenzouさんのサンプルに以下のインポート文つけましたので、
使われる方、注意して下さい。


フォローありがとうございます。
SDKではエラーにならないのですが、Builderではエラーになるのでしょうか?
(私はSDKしか使ったことないので・・・(^^;)

引用:
ありえないくらい短い音って、
mp3では再生できなかったのでとても助かりました。


知りませんでした。何でもmp3に変換すればよいと思っていたのですが、mp3にも制限があるのですね。
mmajin
投稿日時: 2008-9-4 12:44
一見さん
登録日: 2008-9-3
居住地:
投稿: 1
Re: wavファイルを再生する方法
こんにちは。
このソースを利用させていただきたいのですが、下記のURLから入手できるWAVファイルだと再生スピードが遅くなり、声が低くなってしまいます。
http://www.research.att.com/~ttsweb/tts/demo.php

改善方法はあるでしょうか?

▽声が低くなるWAVファイル
ファイルサイズ:87076
フォーマットID:1
チャンネル数:1
サンプリングレート(Hz):16000
データ速度(Byte/sec):32000
ブロックサイズ:2
サンプルあたりのビット数:16

▽正常に聞こえたWAVファイル。
ファイルサイズ:310870
フォーマットID:1
チャンネル数:1
サンプリングレート(Hz):22050
データ速度(Byte/sec):44100
ブロックサイズ:2
サンプルあたりのビット数:16

venzou
投稿日時: 2009-3-26 23:15
ご主人様
登録日: 2007-1-25
居住地: 穴の中
投稿: 101
Re: wavファイルを再生する方法
しばらくFlexから遠のいてまして、
回答が遅くなりました。ごめんなさい。

手遅れかと思いますが、回答です。

SWFファイルで対応している、
サンプリングレートは、

 5.5 kHz
 11 kHz
 22 kHz
 44 kHz

と、なっており、それ以外の場合、
近い値で再生するようにしてあります。

16000Hzの場合、11000Hzで再生され、
低い音になるのだと思います。

WAVファイルを編集できるツール等で、
サンプリングレートを変換してみて下さい。
スレッド表示 | 新しいものから 前のトピック | 次のトピック | トップ

投稿するにはまず登録を