Hi-farm blog

ActionScript 3.0 , AIR , FLEXからCocoa, OpenGL

Archive for June, 2008

いやーすごいですね!astro!

ローカルへのファイル保存が可能だなんて!

実際は、FileReferenceはローカルファイルを読み込んで直接操作できるみたいですが、ひとまず今回は保存です。

 

サンプルはこちら。

(Flashサンプル。赤丸をクリックすると、保存ダイアログが現れて、適当な名前を入力してボタンを押すと、保存。)

注意点としては、同じファイル名で上書き保存しようとすると例外をはくらしいです。

(これはもしかすると僕のサンプルが悪いだけかもです。。)

corelibのJPGEncoderを使って、stageを画像として保存しています。

ようは、FileReferenceにsaveというメソッドができて、それを使うと保存できるよ、ということです。

ちなみに、保存できる形式は、

String, XML, ByteArrayらしいです。

今回のサンプルは、ByteArrayを使って保存しています。

 

ちなみにソースはこんなのです。

 

package
{
import com.adobe.images.*;
import flash.display.*;
import flash.events.*;
import flash.net.*;
import flash.utils.ByteArray;
public class main extends MovieClip
{
private var jpg:JPGEncoder = new JPGEncoder(100);
private var container:Sprite;
private var bmpdata:BitmapData;
private var btn:Sprite;
private var fr:FileReference;
public function main()
{
init();
}

private function init():void
{
//保存ダイアログを出すためのボタン。
btn = new Sprite();
btn.graphics.beginFill(0xff0000, 1);
btn.graphics.drawCircle( 0, 0, 10);
btn.graphics.endFill();
addChild(btn);
btn.width = btn.height = 10;
btn.x = btn.y = 320;
btn.addEventListener(MouseEvent.CLICK, onSave);
fr = new FileReference();
}
private function onSave(e:MouseEvent):void
{
bmpdata = new BitmapData(400, 400, true);
bmpdata.draw(stage);
var ba:ByteArray = new ByteArray();
// stageをBitmap化したものを、ByteArrayに変換。
ba = jpg.encode(bmpdata);
// 保存ダイアログを出す。
fr.save(ba, “astroSavedFile.jpg”);
}
}
}
いや、ほんとにastroはDynamic Sound Generationといい、すごい進化してますね。

 

またまたDynamic Sound Generationです。

これは、mouseXの値をもとに、音程を変えるというサンプルです。

ちなみに、音のもとになるのはぜんかいのと同じ矩形波を使っています。

ソースは後ほど。

サンプル(音が鳴り、そしてボリューム等の調整はできないです)。

今回は色々とサンプルをつくってみながら書いてみます。

波形には色々とあるようですが、今回は、矩形波をいじってみました。

基本的なのは、これ。

ちなみに、512ってのはおまじないと思って下さい。

※サンプルFlash(音がなります。しかも制御できません。)

基本的な矩形波

 

で、矩形の周期を半分にすると、こうなります。

※サンプルFlash(こちらも音がなります。もちろん制御はできないです。)

半分周期の矩形波

 

二つを聴き比べると、二つ目(周期が短い方)が音が高いですよね。

どうやら、周期が短いほど音が高くなる、という仕組みらしいです。

 

と、いうことは、この周期を徐々に短くしていくと、どうなるんでしょう?

※サンプルFlash(音がなり、制御不能。今までと同様ですね。)

一応、「徐々に音が高く」なりましたよね?

 

うんうん。

ということは、これらをうにょうにょすると、宇宙っぽくできるかな?Perfumeっぽい音が出せるかな?○タヤスタカ的な音をasだけで出す事ができるのかな?

 

次は他のタイプの波形をいじってみようと思います。

 

あ、それぞれのサンプルASも.txtとしてリンク貼っておくのでよかったらいじって下さいね。(ごめんなさい。コメントつけれてないです)

  1. サンプル1(普通の矩形波)
  2. サンプル2(半分の矩形波)
  3. サンプル3(周期を動かしたやつ)

[flash astro]Dynamic Sound Generation 2.

またまたですが、Flash Player10 astroのDynamic Sound Generationです。

ボタンを押すと、音が流れます。

パルス波の長さを時間で変えています。

注意:音を止める方法がないので、音を消したい場合はリロードして下さい。

 

これがasだけでできるってのが素晴らしい!!

今、個人的にはこの辺の機能が楽しいなあ。

 

コードはこんなです。

main.as

<code>

package
{
import flash.net.*;
import flash.display.*;
import flash.media.*;
import flash.events.*;
[SWF(backgroundColor="0xeeeeee", frameRate="50", stageHeight="200")]
public class main extends Sprite
{
private var snd:Sound;
private var square:Sprite;
private var sh:Number = 200;
private var btn1:Sprite;
private var btn2:Sprite;
private var btn3:Sprite;
private var btn4:Sprite;
private var btn5:Sprite;
private var btn6:Sprite;
public function main()
{
initBtn();
}
private function initBtn():void
{
btn = new Sprite();
drawBtn(btn);
btn.buttonMode = true;
addChild(btn);
btn.width = btn.height = 20;
btn.x = 0;
btn.y = 0;
btn.addEventListener(MouseEvent.CLICK, click1);
}
private function drawBtn(sp:Sprite):void
{
sp.graphics.beginFill(0xff0000,1);
sp.graphics.drawRect(0, 0, 20, 20);
sp.graphics.endFill();
}
private function click1(e:MouseEvent):void
{
init();
doSamplesCallbackHandler(1);
}
private function init():void
{
snd = new Sound();
if( snd.hasEventListener(”samplesCallback”)) snd.removeEventListener(”samplesCallback”, samplesCallbackHandler);
snd.addEventListener(”samplesCallback”, samplesCallbackHandler);
snd.play();
}
private function samplesCallbackHandler(e:SamplesCallbackEvent):void
{
doSamplesCallbackHandler(1);
}
private var rate:Number = 44100;
private var freq:Number = 440;
private var phase:Number = 0;
private var count:Number = 1;
/**
* generate wave data.
*/
private function doSamplesCallbackHandler(type:int):void
{
//Voice.beep1();
var freq:Number = 220;
for( var i:uint=0; i < 512; i++ )
{
phase += freq/(rate);
var arrange:Number = 1;
var a:Number = 1;
if( i%2==0 ) a = 1;
arrange = a*count;
var phaseAngle:Number = phase * arrange;
var sample:Number = Math.sin(phaseAngle);
//ここで波形をつくってます。
sample = beep1(i);
//左右チャンネルともに同じ波形。
snd.samplesCallbackData.writeFloat(sample);
snd.samplesCallbackData.writeFloat(sample);
}
delim++;
if( delim > 256 ) delim = 0;
}
private var delim:Number = 0;
/**
* generate beep1
* @param i:uint wave counter.
* @return Number
*/
private function beep1(i:uint):Number
{
var res:Number =0;
//delim++;
//if( delim > 256 ) delim = 0;
//if( i < 256 ) res = 50;
//else res = 0;
if( i < delim ) res = 50;
else res = 0;
return res;
}
}
}

</code>

RSS変更のお知らせ

ブログの移転にともない、RSSがかわりました。
http://blog.hi-farm.net/?feed=rss2
wordpressになりました。
  • 0 Comments
  • Filed under: 未分類
  • えっと、ほんとは今日はパラグライダーで空を飛ぶ予定でしたが、天候により中止。

    で、代わりにastroのdynamic sound generationやってました。
    参考サイトはこちら:
    http://www.kaourantin.net/2008/05/adobe-is-making-some-noise-part-3.html
    http://memo.kappa-lab.com/2008/06/astroflash10_singing_do-re-mi–.html

    取りあえずソースは後ほどということで、サンプルだけ。

    http://www.hi-farm.net/astro/dynamicsound1.swf

    つまらないやつですが、マウスを押している間、音が高くなっていきます。
    マウスを放すと、音が低くなります。

    これをasのみでできるのは楽しいですね。
    デジタルシンセとか作れそう。

    もうちょっとソース整理したら改めて書きます!

    あー、デジタルシンセってか、サイン波の音とか、色々勉強したい事がふえるなあ。

    2008年6月9日00:53

    えっと、実はすごい前に作っていたので今は誰か作っているのかもですが、
    adobeのcorelibにある、JpgEncoderの非同期版を作ってみました。

    http://www.hi-farm.net/labs/modJPGEncoder.as.zip

    ライセンス的に大丈夫だという判断で公開ですが、まずそうでしたらすぐに取り下げますのですみませんが、ご連絡下さい。

    使い方は、
    1. corelibのJpgEncoder.asを解凍したファイルに差し替えて下さい。

    コードではこんな風にして下さい(サンプル:画像保存のAIRアプリ)

    <?xml version=”1.0″ encoding=”utf-8″?>
    <mx:WindowedApplication xmlns:mx=”http://www.adobe.com/2006/mxml”; layout=”absolute” creationComplete=”initApp()”>
    <mx:Script>
    <![CDATA[

    import com.adobe.images.JPGEncoder;
    import flash.events.*;

    private var jpg:JPGEncoder;
    private function initApp():void
    {
    btn.addEventListener(MouseEvent.CLICK, clickHandler);
    }

    private function clickHandler(e:MouseEvent):void
    {
    //--- 
    jpg = new JPGEncoder(100);
    //--- 処理中のイベント
    jpg.addEventListener("progressing", progressHandler);
    //--- 処理完了のイベント
    jpg.addEventListener("finished", finishedHandler);

    var bmpdata:BitmapData = new BitmapData(stage.stageWidth, stage.stageHeight, false);
    bmpdata.draw(stage);
    jpg.encodeAsync(bmpdata);
    }

    private function progressHandler(e:Event):void
    {
    var percent:String = new int((jpg.cur/jpg.maxCur)*100).toString() + "%";
    ti.text = percent;
    }
    private function finishedHandler(e:Event):void
    {
    ti.text = "convert finished.";

    //-- 終了したら、ファイルに保存する。
    var f:File = File.desktopDirectory.resolvePath("out.jpg");
    var fs:FileStream = new FileStream();
    fs.open(f, FileMode.WRITE);
    fs.writeBytes( jpg.ba, 0, jpg.ba.length);
    fs.close();
    }

    ]]>
    </mx:Script>
    <mx:VBox>
    <mx:TextInput id=”ti” width=”400″ text=”jpg export test” />
    <mx:Button width=”300″ height=”40″ id=”btn” label=”generate desktop/out.jpg” />
    </mx:VBox>
    </mx:WindowedApplication>

    内部的に行っていることは、bytearray形式でBitmapDataを作るときに、同期バージョンはforループでまわしてたのですが、timerでのまわし方に変えた、簡単に言えばそういう事です。

    2008年6月1日04:14

    astro練習

    取りあえず、flash player10 astroの練習をしてみました。
    標準で3Dの機能がついたので、ひとまずちょっとしたサンプルを作成しました.

    http://www.hi-farm.net/astro/main.swf

    処理がかるくなるのかな?と思ってたのですが、Macのアクティビティモニタで見てみると、
    今までの様にPapervision3Dを作った時と、重さがあまりかわらない気がしたんですけど、どうなんでしょう?

    ソースはこれ。

    main.as—————————————-

    package
    {

    import flash.events.*;
    import flash.display.*;
    import flash.ui.*;

    [SWF(backgroundColor="0x000000", frameRate="50")]
    public class main extends MovieClip
    {

    private var container:Sprite;
    private var rect_vc:Vector.<Rect>;
    private var len:uint = 6;
    private var radius:Number = 100;
    private var container_vc:Vector.<Sprite>;
    private var innerLen:uint=15;

    public function main ()
    {
    init();
    }

    private function init():void
    {
    container_vc = new Vector.<Sprite>();

    container = new Sprite();
    container.x = 150;
    container.y = 10;

    addChild(container);
    rect_vc = new Vector.<Rect>();
    for( var i:uint=0; i < innerLen; i++ )
    {
    container_vc[i] = genCircle(0, 30*i+10,15*i);
    container_vc[i].rotationY = 30 * i;
    }
    addEventListener(Event.ENTER_FRAME, enterframeHandler);
    }

    private function genCircle(cX:Number, cY:Number, ra:Number):Sprite
    {
    var innerContainer:Sprite = new Sprite();

    for( var i:uint=0; i < len; i++ )
    {
    var rect:Rect = new Rect(0xffffff, 10, 10);
    innerContainer.addChild(rect);

    var rad:Number = (Math.PI/180) * ( (360/len)*i);
    rect.x = (Math.cos(rad) – Math.sin(rad)) * ra;
    rect.y = 0;
    rect.z = (Math.sin(rad) + Math.cos(rad)) * ra;
    rect_vc[i] = rect;
    }

    innerContainer.x = 0;
    innerContainer.y = 0;

    innerContainer.x = cX;
    innerContainer.y = cY;

    container.addChild(innerContainer);

    return innerContainer;
    }

    private function enterframeHandler(e:Event):void
    {
    for( var i:uint=0; i < innerLen; i++ )
    {
    container_vc[i].rotationY++;
    }
    }
    }
    }

    Rect.as—————————————-

    package
    {
    import flash.display.*;
    import flash.events.*;

    public class Rect extends Sprite
    {
    function Rect(col:uint, w:Number, h:Number)
    {
    this.graphics.beginFill( 0xffffff, 1);
    this.graphics.drawRect( 0, 0, w, h);
    this.graphics.endFill();
    }
    }
    }

    2008年6月1日02:36

  • 1 Comment
  • Filed under: Actionscript3, astro
  • ほんと久しぶりですが。

    記事書くのをほっぽらかしていました。

    僕はというと、3月から東京へ引越して、会社員はじめたのですが、そこでは今までやっていた、ASに加えて、WPFとかSilverlightも始めました。

    で、会社のことはなかなかかけなかったので、更新できなかったですが、最近はVisual Studioも手に入り、CocoaとかOpenGLとか始めたのでその辺の事を書いて行こうと思います。

    生存確認的な意味合いを込めて、エントリー。

    2008年5月12日03:53

  • 0 Comments
  • Filed under: 未分類
  • 履歴とheader(”Location: —”);

    最近(というか昨日)、名古屋ちょい絶発表会 vol.2があり、AIRのHTML使ってみましょー、ってなことをやってたのですが、
    その後触ってて、ちょっとメモ。

    mx:HTMLのid=”browsing”
    とすると、

    履歴を取るんだったらこんなんでしょうか?

    <?xml version=”1.0″ encoding=”utf-8″?>
    <mx:WindowedApplication xmlns:mx=”http://www.adobe.com/2006/mxml”; layout=”absolute”>
    <mx:Script>
    <![CDATA[
    import mx.events.FlexEvent;

    private function init():void
    {
    //履歴をtrace()で出力してみる
    browsing.addEventListener(Event.LOCATION_CHANGE, function():void{
    trace(browsing.location);
    });
    }

    private function changeLoc(e:FlexEvent):void
    {
    browsing.location = e.target.text;
    }
    ]]>
    </mx:Script>
    <mx:VBox>
    <mx:HBox>
    <mx:Button label=”&lt;” click=”browsing.historyBack()” />
    <mx:Button label=”&gt;” click=”browsing.historyForward()” />
    <mx:Button label=”reload” click=”browsing.reload()” />
    <mx:TextInput id=”urls” enter=”changeLoc(event)” />
    </mx:HBox>
    <mx:HTML id=”browsing” width=”500″ height=”700″ />
    </mx:VBox>
    </mx:WindowedApplication>

    で、僕の経験不足+知識不足なのでしょうけど、ブラウザに履歴を残さずに移動するには、PHPなら、
    header(”Location: http://sample.com” ;) ;

    とか書いておけばいいってきいたんですけど、AIRで作れば、上の方法で履歴をとれば、headerでも履歴を残せます。
    例えば、試しに。

    http://www.hi-farm.net/labs/location.php

    これは
    <?php
    header(”Location: http://www.hi-farm.net” ;) ;
    ?>

    ってだけ書いているファイルで、
    上にかいたコードを使ってみると、

    http://www.hi-farm.net/labs/location.php
    http://www.hi-farm.net/

    って出力されます!!

    これって普通ですか?

    2008年2月17日01:01

  • 0 Comments
  • Filed under: AIR