Advertisement
YellowAfterlife

AS3: Sound wave scripting experiment

Jun 25th, 2012
145
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. package
  2. {
  3.     import flash.display.Bitmap;
  4.     import flash.display.BitmapData;
  5.     import flash.display.Sprite;
  6.     import flash.display.StageAlign;
  7.     import flash.display.StageScaleMode;
  8.     import flash.events.Event;
  9.     import flash.events.MouseEvent;
  10.     import flash.events.SampleDataEvent;
  11.     import flash.geom.Rectangle;
  12.     import flash.media.Sound;
  13.     import flash.media.SoundChannel;
  14.     import flash.text.TextField;
  15.     import flash.text.TextFieldAutoSize;
  16.     import flash.text.TextFieldType;
  17.     import flash.text.TextFormat;
  18.     import flash.utils.ByteArray;
  19.    
  20.     /**
  21.      * ...
  22.      * @author YellowAfterlife
  23.      */
  24.     public class Main extends Sprite
  25.     {
  26.         public var sb:ByteArray; // soundBytes
  27.         public var so:Sound; // soundObject
  28.         public var sc:SoundChannel; // soundChannel
  29.         //
  30.         public function Main():void {
  31.             if (stage) init();
  32.             else addEventListener(Event.ADDED_TO_STAGE, init);
  33.         }
  34.         // listener for sound.SampleData, for writing data into sound
  35.         public function so_bytes(event:SampleDataEvent):void {
  36.             var bytes:ByteArray = new ByteArray();
  37.             sb.readBytes(bytes, 0, Math.min(sb.bytesAvailable, 8 * 8192));
  38.             event.data.writeBytes(bytes, 0, bytes.length);
  39.         }
  40.         // event handler for sound.COMPLETE
  41.         public function so_complete(event:Event):void {
  42.             dispatchEvent(event);
  43.         }
  44.         // different types of sound generation
  45.         // l is length in seconds, f is frequency
  46.         public function so_add(l:Number, f:Number):void {
  47.             if (f == 0) { so_sil(l); return; }
  48.             var i:int, v:Number, m:Number;
  49.             m = l * 44100;
  50.             for (i = 0; i < m; i++) {
  51.                 v = Math.sin(i / f) * 0.5;
  52.                 sb.writeFloat(v);
  53.                 sb.writeFloat(v);
  54.             }
  55.         }
  56.         // fade-in
  57.         public function so_addu(l:Number, f:Number):void {
  58.             if (f == 0) { so_sil(l); return; }
  59.             var i:int, v:Number, m:Number;
  60.             m = l * 44100;
  61.             for (i = 0; i < m; i++) {
  62.                 v = Math.sin(i / f) * 0.5 * (i / m);
  63.                 sb.writeFloat(v);
  64.                 sb.writeFloat(v);
  65.             }
  66.         }
  67.         // fade-out
  68.         public function so_addl(l:Number, f:Number):void {
  69.             if (f == 0) { so_sil(l); return; }
  70.             var i:int, v:Number, m:Number;
  71.             m = l * 44100;
  72.             for (i = 0; i < m; i++) {
  73.                 v = Math.sin(i / f) * 0.5 * (1 - i / m);
  74.                 sb.writeFloat(v);
  75.                 sb.writeFloat(v);
  76.             }
  77.         }
  78.         // smoothed
  79.         public function so_adds(l:Number, f:Number):void {
  80.             if (f == 0) { so_sil(l); return; }
  81.             var i:int, v:Number, m:Number, t:Number;
  82.             m = l * 44100;
  83.             for (i = 0; i < m; i++) {
  84.                 t = i / m;
  85.                 v = Math.sin(i / f) * 0.5;
  86.                 if (t < 0.1) v *= t * t * 100;
  87.                 if (t > 0.9) v *= (1 - t) * (1 - t) * 100;
  88.                 sb.writeFloat(v);
  89.                 sb.writeFloat(v);
  90.             }
  91.         }
  92.         // silence
  93.         public function so_sil(l:Number):void
  94.         {
  95.             var i:int, m:Number;
  96.             m = l * 44100;
  97.             for (i = 0; i < m; i++)
  98.             {
  99.                 sb.writeFloat(0);
  100.                 sb.writeFloat(0);
  101.             }
  102.         }
  103.         private var tt:uint = 1; // time passed
  104.         private var ts:Number = 0; // total time
  105.         // handler for onFrame event of stage, increments time
  106.         private function tick(e:Event = null):void {
  107.             tt++;
  108.             ts = tt / stage.frameRate;
  109.         }
  110.         // parses string and converts it into sound
  111.         private function psound(s:String = null):void
  112.         {
  113.             sb = new ByteArray();
  114.             var i:int, z:String, l:Number, f:Number, c:String;
  115.             for (i = 0; i < s.length; i++)
  116.             {
  117.                 if (s.charAt(i) == "#") for (i++; s.charCodeAt(i) != 13 && i < s.length; i++) { }
  118.                 if (s.charAt(i) == "{")
  119.                 {
  120.                     l = 0;
  121.                     for (i++; (s.charAt(i) != "}" || l != 0) && i < s.length; i++) l += (s.charAt(i) == "{" ? 1 : (s.charAt(i) == "}" ? -1 : 0));
  122.                 }
  123.                 c = s.charAt(i);
  124.                 if (c == "~" || c == "*" || c == "=" || c == "/" || c == "\\")
  125.                 {
  126.                     z = "";
  127.                     for (i++; s.charAt(i) != "," && s.charAt(i) != "{" && s.charAt(i) != "#" && s.charCodeAt(i) != 13 && i < s.length; i++) z += s.charAt(i);
  128.                     l = parseFloat(z);
  129.                     z = "";
  130.                     for (i++; s.charAt(i) != ";" && s.charAt(i) != "{" && s.charAt(i) != "#" && s.charCodeAt(i) != 13 && i < s.length; i++) z += s.charAt(i);
  131.                     f = parseFloat(z);
  132.                     switch(c)
  133.                     {
  134.                         case "*": so_adds(l, f); break;
  135.                         case "~": so_adds(l, f); break;
  136.                         case "=": so_add(l, f); break;
  137.                         case "/": so_addu(l, f); break;
  138.                         case "\\": so_addl(l, f); break;
  139.                     }
  140.                 }
  141.             }
  142.             // making the actual sound:
  143.             sb.position = 0;
  144.             so = new Sound();
  145.             so.addEventListener(SampleDataEvent.SAMPLE_DATA, so_bytes);
  146.             sc = so.play();
  147.             sc.addEventListener(Event.SOUND_COMPLETE, so_complete);
  148.         }
  149.         private function click(e:MouseEvent = null):void
  150.         {
  151.             if (e.stageY < 32 && e.stageX < 128)
  152.             {
  153.                 psound(ti.text);
  154.             }
  155.         }
  156.         public var ti:TextField = new TextField(), ty:TextField = new TextField();
  157.         // Slider stuff
  158.         public var sd_bmdt:BitmapData = new BitmapData(320, 8, false, 0x000000);
  159.         public var sd_bmdt0:BitmapData = new BitmapData(320, 8, false, 0x000000);
  160.         public var sd_bm:Bitmap = new Bitmap(sd_bmdt);
  161.         public var sd_bm0:Bitmap = new Bitmap(sd_bmdt0);
  162.         public var sd_v0:Number = 1, sd_v1:Number = 1;
  163.         public var sd_a0:Number = 0, sd_b0:Number = 4;
  164.         public var sd_a1:Number = 0, sd_b1:Number = 64;
  165.         public function sd_click(e:MouseEvent):void
  166.         {
  167.             var r:Rectangle = new Rectangle(), n:Number;
  168.             if (sd_bm0.hitTestPoint(e.stageX, e.stageY, false))
  169.             {
  170.                 n = e.stageX - sd_bm.x;
  171.                 sd_v0 = n / sd_bm.width;
  172.                 ty.text = "*" + (sd_a0 + sd_v0 * (sd_b0 - sd_a0)) + "," + (sd_a1 + sd_v1 * (sd_b1 - sd_a1)) + ";";
  173.                 psound(ty.text + "*0.1,0;");
  174.                 r.x = r.y = 0;
  175.                 r.height = 8;
  176.                 r.width = n;
  177.                 sd_bmdt0.fillRect(r, 0x000000);
  178.                 r.x = r.width;
  179.                 r.width = sd_bm.width - r.width;
  180.                 sd_bmdt0.fillRect(r, 0xCCCCCC);
  181.             }
  182.             if (sd_bm.hitTestPoint(e.stageX, e.stageY, false))
  183.             {
  184.                 n = e.stageX - sd_bm.x;
  185.                 sd_v1 = n / sd_bm.width;
  186.                 ty.text = "*" + (sd_a0 + sd_v0 * (sd_b0 - sd_a0)) + "," + (sd_a1 + sd_v1 * (sd_b1 - sd_a1)) + ";";
  187.                 psound(ty.text + "*0.1,0;");
  188.                 r.x = r.y = 0;
  189.                 r.height = 8;
  190.                 r.width = n;
  191.                 sd_bmdt.fillRect(r, 0x000000);
  192.                 r.x = r.width;
  193.                 r.width = sd_bm.width - r.width;
  194.                 sd_bmdt.fillRect(r, 0xCCCCCC);
  195.             }
  196.             if (ty.hitTestPoint(e.stageX, e.stageY, false))
  197.             {
  198.                 ti.appendText(ty.text);
  199.             }
  200.         }
  201.         public function sd_init():void
  202.         {
  203.             sd_bm.x = sd_bm0.x = 128;
  204.             sd_bm.y = 20; sd_bm0.y = 8;
  205.             stage.addEventListener(MouseEvent.CLICK, sd_click);
  206.             addChild(sd_bm);
  207.             addChild(sd_bm0);
  208.         }
  209.         private function init(e:Event = null):void
  210.         {
  211.             stage.scaleMode = StageScaleMode.NO_SCALE;
  212.             stage.align = StageAlign.TOP_LEFT;
  213.             removeEventListener(Event.ADDED_TO_STAGE, init);
  214.             stage.addEventListener(Event.ENTER_FRAME, tick);
  215.             stage.addEventListener(MouseEvent.CLICK, click);
  216.             stage.addEventListener(Event.RESIZE, function(e:Event = null):void { ti.width = stage.stageWidth - 32; ti.height = stage.stageHeight - 48; } );
  217.             // entry point
  218.             sd_init();
  219.             ty.autoSize = TextFieldAutoSize.LEFT;
  220.             ty.y = 8;
  221.             ty.x = 456;
  222.             ty.text = "*";
  223.             stage.addChild(ty);
  224.             var tj:TextField = new TextField();
  225.             tj.x = 24;
  226.             tj.y = 12;
  227.             tj.selectable = false;
  228.             tj.defaultTextFormat = ty.defaultTextFormat = ti.defaultTextFormat = new TextFormat("Courier New", 12, 0x333333);
  229.             tj.text = "[Play sound]";
  230.             stage.addChild(tj);
  231.             // main textfield:
  232.             ti.border = true;
  233.             ti.backgroundColor = 0xFEFEFE;
  234.             ti.background = true;
  235.             ti.x = 16;
  236.             ti.y = 32;
  237.             ti.width = stage.stageWidth - 32;
  238.             ti.height = stage.stageHeight - 48;
  239.             ti.type = TextFieldType.INPUT;
  240.             ti.multiline = true;
  241.             ti.tabEnabled = true;
  242.             ti.text =
  243.             "{" +
  244.             "\n SoundTest 0.0.1" +
  245.             "\n Sound format:" +
  246.             "\n  (type)(length),(freq)(;)" +
  247.             "\n   type : sound type" +
  248.             "\n    * Smooth" +
  249.             "\n    / Fade-in" +
  250.             "\n    = Plain" +
  251.             "\n    \\ Fade-out" +
  252.             "\n   length : sound length (in seconds)" +
  253.             "\n   freq : frequency. Range of [0.1 .. 23] can be heard." +
  254.             "\n   ; is required if placing several commands on one line"+
  255.             "\n Other:" +
  256.             "\n  { text } : multi-line comment." +
  257.             "\n  # text : single-line comment." +
  258.             "\n Example:" +
  259.             "\n  *1, 15 # play sound with freq. 15 for 1 second"+
  260.             "\n}\n"
  261.             stage.addChild(ti);
  262.         }
  263.        
  264.     }
  265.    
  266. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement