守望者--AIR技术交流

 找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

搜索
热搜: ANE FlasCC 炼金术
查看: 724|回复: 0

[经典案例] 高人做的电子琴,声音控制

[复制链接]
  • TA的每日心情
    擦汗
    2018-4-10 15:18
  • 签到天数: 447 天

    [LV.9]以坛为家II

    1742

    主题

    2094

    帖子

    13万

    积分

    超级版主

    Rank: 18Rank: 18Rank: 18Rank: 18Rank: 18

    威望
    562
    贡献
    29
    金币
    51691
    钢镚
    1422

    开源英雄守望者

    发表于 2015-7-15 16:35:59 | 显示全部楼层 |阅读模式






    1. // SiON Keyborad WF1 ver0.58
    2. package {
    3.     import flash.display.Sprite;
    4.     import flash.events.*;
    5.     import flash.system.System;
    6.     import com.bit101.components.*;
    7.    
    8.     public class main extends Sprite {
    9.         function main() {
    10.             graphics.beginFill(0);
    11.             graphics.drawRect(0,0,465,465);
    12.             graphics.endFill();
    13.             
    14.             addChild(keyboard = new Sprite());
    15.             keyboard.x = 0;
    16.             keyboard.y = 120;
    17.             
    18.             keys = new KeyDisplay(keyboard, 32, 54);
    19.             Style.BACKGROUND = 0x606060;
    20.             Style.BUTTON_FACE = 0x404040;
    21.             Style.LABEL_TEXT = 0xaaaaaa;
    22.             Style.DROPSHADOW = 0;
    23.             Style.PANEL = 0x202020;
    24.             Style.PROGRESS_BAR = 0x404040;
    25.             selector = new VoiceSelector(keyboard, 32, -16);
    26.             volume = new VolumePanel(keyboard, 32, 78);
    27.             stage.addEventListener("keyDown", _onKeyDown);
    28.             stage.addEventListener("keyUp", _onKeyUp);

    29.             var disc:String = "[ UP / DOWN ] = Change Voice      ";
    30.             disc += "[ LEFT / RIGHT ] = Change Categoly      ";
    31.             disc += "[ Q / W ] = Octave Shift";
    32.             new Label(keyboard, 16, 204, disc);
    33.             
    34.             disc = "[ P ] = Send parameters to clipboard";
    35.             clipboard = new Text(keyboard, 16, 230, disc);
    36.             clipboard.setSize(433, 96);
    37.             
    38.             initializeSiON();
    39.         }
    40.         
    41.         private function _onKeyDown(e:KeyboardEvent) : void {
    42.             var i:int, c:String, mml:String;
    43.             switch (e.keyCode) {
    44.             case 40: updateVoice(voiceIndex-1); break;
    45.             case 38: updateVoice(voiceIndex+1); break;
    46.             case 37: updateCategoly(categolyIndex-1); break;
    47.             case 39: updateCategoly(categolyIndex+1); break;
    48.             default:
    49.                 switch (c = String.fromCharCode(e.charCode)) {
    50.                 case 'q': keys.octDown(); break;
    51.                 case 'w': keys.octUp();   break;
    52.                 case 'p':
    53.                     mml = voiceList[voiceIndex].getMML(voiceIndex);
    54.                     clipboard.text = "[ P ] = Send parameters to clipboard \n" + mml.replace(/\r/g, '');
    55.                     System.setClipboard(mml);
    56.                     break;
    57.                 default:  if ((i="zsxdcvgbhnjm,l.;/".indexOf(c)) >= 0) keyOn(i); break;
    58.                 }
    59.             }
    60.         }
    61.         
    62.         private function _onKeyUp(e:KeyboardEvent) : void {
    63.             var i:int, c:String = String.fromCharCode(e.charCode);
    64.             if ((i="zsxdcvgbhnjm,l.;/".indexOf(c)) >= 0) keyOff(i);
    65.         }
    66.     }
    67. }



    68. import flash.display.*;
    69. import flash.events.*;
    70. import flash.filters.*;
    71. import flash.text.*;
    72. import flash.geom.*;
    73. import com.bit101.components.*;
    74. import org.si.sion.*;
    75. import org.si.sion.effector.*;
    76. import org.si.sion.sequencer.SiMMLTrack;
    77. import org.si.sion.utils.SiONPresetVoice;

    78. // SiON variables
    79. var driver:SiONDriver = new SiONDriver();
    80. var presetVoice:SiONPresetVoice = new SiONPresetVoice();
    81. var voiceList:Array = presetVoice.categolies[0];
    82. var voiceIndex:int = 0;
    83. var categolyIndex:int = 0;
    84. var delaySendLevel:Number = 0.2;
    85. var chorusSendLevel:Number = 0;
    86. var lpf:SiCtrlFilterLowPass = new SiCtrlFilterLowPass();
    87. var cutoff:Number = 1;
    88. var resonance:Number = 0;

    89. // UIs
    90. var keyboard:Sprite;
    91. var keys:KeyDisplay;
    92. var selector:VoiceSelector;
    93. var volume:VolumePanel;
    94. var keyFlag:int;
    95. var clipboard:Text;

    96. // Global Functions
    97. function initializeSiON() : void {
    98.     // effector setting
    99.     lpf.control(1, 0);
    100.     driver.effector.slot0 = [lpf];
    101.     driver.effector.slot1 = [new SiEffectStereoDelay(200,0.2,false)];
    102.     driver.effector.slot2 = [new SiEffectStereoChorus(20,0.2,4,20)];
    103.    
    104.     // start stream without initializing effectors
    105.     driver.play(null, false);
    106. }

    107. function updateCategoly(index:int) : void {
    108.     var imax:int = presetVoice.categolies.length;
    109.     if (index < 0) index = imax - 1;
    110.     else if (index >= imax) index = 0;
    111.     categolyIndex = index;
    112.     voiceList = presetVoice.categolies[index];
    113.     selector.onUpdateCategoly();
    114.     volume.onUpdateCategoly();
    115.     updateVoice(voiceIndex);
    116. }

    117. function updateVoice(index:int, callFromKnob:Boolean=false) : void {
    118.     if (voiceList) {
    119.         if (index < 0) index = 0;
    120.         else if (index >= voiceList.length) index = voiceList.length - 1;
    121.         voiceIndex = index;
    122.         selector.updateName();
    123.         if (!callFromKnob) volume.updateVoiceIndex();
    124.     }
    125. }

    126. function keyOn(index:int) : void {
    127.     if ((keyFlag & (1<<index)) == 0) {
    128.         keyFlag |= 1<<index;
    129.         var trk:SiMMLTrack = driver.noteOn(index + keys.octave*12, voiceList[voiceIndex], 0);
    130.         trk.channel.setStreamSend(1, delaySendLevel);
    131.         trk.channel.setStreamSend(2, chorusSendLevel);
    132.         keys.keyOn(index);
    133.     }
    134. }

    135. function keyOff(index:int) : void {
    136.     keyFlag &= ~(1<<index);
    137.     driver.noteOff(index + keys.octave*12);
    138.     keys.keyOff(index);
    139. }

    140. function allNoteOff() : void {
    141.     for each (var trk:SiMMLTrack in driver.sequencer.tracks) trk.keyOff();
    142. }

    143. class KeyDisplay extends Sprite {
    144.     private var _screenBitmap:Bitmap;
    145.     private var _screen:BitmapData = new BitmapData(400, 144, false, 0);
    146.     private var _cls:BitmapData = new BitmapData(400, 144, false, 0x202020);
    147.     private var _bkeyBase:BitmapData = new BitmapData(320, 120, true, 0);
    148.     private var _wkeyPos:Array = [100,120,140,160,180,200,220,240,260,280];
    149.     private var _bkeyPos:Array = [112,136,172,194,216,252,276];
    150.     private var _wkeyIndex:Array = [0,2,4,5,7,9,11,12,14,16];
    151.     private var _bkeyIndex:Array = [1,3,6,8,10,13,15];
    152.     private var _wkeyPushed:BitmapData = new BitmapData(20, 120, true, 0x808080ff);
    153.     private var _bkeyPushed:BitmapData = new BitmapData(12, 80, true, 0x408080ff);
    154.     private var _light:BitmapData = new BitmapData(12, 12, true, 0);
    155.     private var _keyFlag:int = 0, _newKeyFlag:int = 0x3000000, _padUpdated:Boolean = false;
    156.    
    157.     public function get octave() : int { return (_keyFlag>>24)+2; }
    158.    
    159.     function KeyDisplay(parent:DisplayObjectContainer, x:Number, y:Number) {
    160.         this.x = x;
    161.         this.y = y;
    162.         parent.addChild(this);
    163.         _createBitmap();
    164.         addEventListener("enterFrame", _onEnterFrame);
    165.         addChild(_screenBitmap = new Bitmap(_screen));
    166.         stage.addEventListener("mouseDown", _onMouseDown);
    167.         stage.addEventListener("mouseUp",   _onMouseUp);
    168.         stage.addEventListener("mouseMove", _onMouseMove);
    169.     }
    170.    
    171.     public function keyOn(index:int)  : void { _newKeyFlag = _newKeyFlag | (1<<index); }
    172.     public function keyOff(index:int) : void { _newKeyFlag = _newKeyFlag &~(1<<index); }
    173.     public function octUp() : void {
    174.         var oct:int = _newKeyFlag >> 24;
    175.         if (++oct > 6) oct=6;
    176.         _newKeyFlag = (oct<<24) | (_newKeyFlag & 0xffffff);
    177.         allNoteOff();
    178.     }
    179.     public function octDown() : void {
    180.         var oct:int = _newKeyFlag >> 24;
    181.         if (--oct < 0) oct=0;
    182.         _newKeyFlag = (oct<<24) | (_newKeyFlag & 0xffffff);
    183.         allNoteOff();
    184.     }
    185.    
    186.     private function _createBitmap() : void {
    187.         var canvas:Shape = new Shape(), g:Graphics = canvas.graphics, chars:String,
    188.             i:int, mat:Matrix = new Matrix(), rc:Rectangle = new Rectangle(0,8,8,4), label:Label;
    189.         parent.addChild(canvas);
    190.         // white keys
    191.         g.clear();
    192.         g.lineStyle(2, 0);
    193.         mat.createGradientBox(8, 8, Math.PI/2);
    194.         g.beginGradientFill("linear", [0x404040,0xf0f0f0], [1,1], [0,255], mat);
    195.         g.drawRoundRect(0,-4,20,124,8);
    196.         g.endFill();
    197.         g.lineStyle(4, 0x808080, 0.25);
    198.         g.drawPath(Vector.<int>([1,2]), Vector.<Number>([0,-4, 0,120]));
    199.         Style.LABEL_TEXT = 0x666666;
    200.         label = new Label(null,0,0,"");
    201.         chars = "Q  ZXCVBNM,./  W";
    202.         for (i=0; i<16; i++) {
    203.             mat.identity();
    204.             mat.translate(i*20+40, 20);
    205.             _cls.draw(canvas, mat);
    206.             label.text = chars.charAt(i);
    207.             label.draw();
    208.             mat.translate(4, 96);
    209.             _cls.draw(label, mat);
    210.         }
    211.         // board
    212.         g.clear();
    213.         mat.createGradientBox(20, 20, Math.PI/2);
    214.         g.beginGradientFill("linear", [0,0x404040,0x202020], [1,1,1], [0,192,255], mat);
    215.         g.drawRect(0,0,400,20);
    216.         g.endFill();
    217.         _cls.draw(canvas);
    218.         // octave
    219.         label.text = "oct.";
    220.         label.draw();
    221.         mat.identity();
    222.         mat.translate(4, 0);
    223.         _cls.draw(label, mat);
    224.         for (rc.x=30; rc.x<136; rc.x+=16) _cls.fillRect(rc, 0);
    225.         g.clear();
    226.         mat.createGradientBox(8, 8, 0);
    227.         g.beginGradientFill("radial", [0xff8040,0x800000], [1,0], [0,255], mat);
    228.         g.drawCircle(6, 6, 8);
    229.         g.endFill();
    230.         _light.draw(canvas);
    231.         // logo
    232.         label.text = "SiON FM Synthesizer WF-1";
    233.         label.draw();
    234.         mat.identity();
    235.         mat.translate(280, -2);
    236.         _cls.draw(label, mat);
    237.         // black keys
    238.         g.clear();
    239.         g.beginFill(0x808080, 0.25);
    240.         g.drawPath(Vector.<int>([1,2,2,2]), Vector.<Number>([12,0, 16,0, 18,75, 12,82]));
    241.         g.endFill();
    242.         g.lineStyle(2, 0);
    243.         g.beginFill(0x303030);
    244.         g.drawRoundRect(0,0,12,80,3);
    245.         g.endFill();
    246.         g.lineStyle(3, 0x606060, 0.5);
    247.         g.drawPath(Vector.<int>([1,2,2]), Vector.<Number>([2,0, 2,73, 8,73]));
    248.         g.lineStyle(1, 0xc0c0c0, 0.5);
    249.         g.drawPath(Vector.<int>([1,2,2]), Vector.<Number>([2,0, 2,71, 7,71]));
    250.         Style.LABEL_TEXT = 0xaaaaaa;
    251.         label = new Label(null,0,0,"");
    252.         var pos:Array = [-8,14,36,72,96,132,154,176,212,236,272,294,316];
    253.         chars = "   SDGHJL;   ";
    254.         for (i=0; i<pos.length; i++) {
    255.             mat.identity();
    256.             mat.translate(pos[i], 0);
    257.             _bkeyBase.draw(canvas, mat);
    258.             label.text = chars.charAt(i);
    259.             label.draw();
    260.             mat.translate(1, 50);
    261.             _bkeyBase.draw(label, mat);
    262.         }
    263.         // Filter pad
    264.         label.text = "Filter";
    265.         label.draw();
    266.         mat.identity();
    267.         mat.translate(6, 84);
    268.         _cls.draw(label, mat);
    269.         _cls.fillRect(new Rectangle(8,104,24,24), 0);
    270.         
    271.         parent.removeChild(canvas);
    272.     }
    273.    
    274.     private function _onEnterFrame(e:Event) : void {
    275.         if (_keyFlag != _newKeyFlag || _padUpdated) {
    276.             _keyFlag = _newKeyFlag;
    277.             _padUpdated = false;
    278.             _screen.copyPixels(_cls, _cls.rect, _cls.rect.topLeft);
    279.             var i:int, mat:Matrix = new Matrix(1,0,0,1,0,20), pt:Point = new Point(40, 20);
    280.             for  (i=0; i<_wkeyIndex.length; i++) {
    281.                 if (_keyFlag & (1<<_wkeyIndex[i])) {
    282.                     mat.tx = _wkeyPos[i];
    283.                     _screen.draw(_wkeyPushed, mat);
    284.                 }
    285.             }
    286.             _screen.copyPixels(_bkeyBase, _bkeyBase.rect, pt);
    287.             for  (i=0; i<_bkeyIndex.length; i++) {
    288.                 if (_keyFlag & (1<<_bkeyIndex[i])) {
    289.                     mat.tx = _bkeyPos[i];
    290.                     _screen.draw(_bkeyPushed, mat);
    291.                 }
    292.             }
    293.             pt.x = octave*16-2;
    294.             pt.y = 6;
    295.             _screen.copyPixels(_light, _light.rect, pt);
    296.             pt.x = int(resonance*23) + 4;
    297.             pt.y = 123 - int(cutoff*23);
    298.             _screen.copyPixels(_light, _light.rect, pt);
    299.         }
    300.     }
    301.    
    302.     private var _draggingStart:Point;
    303.     private function _onMouseDown(e:MouseEvent) : void {
    304.         if (mouseX>4 && mouseX<36 && mouseY>104 && mouseY<136) {
    305.             _draggingStart = new Point(mouseX-resonance*50, mouseY+cutoff*50);
    306.         }
    307.     }
    308.     private function _onMouseUp(e:MouseEvent) : void { _draggingStart = null; }
    309.     private function _onMouseMove(e:MouseEvent) : void {
    310.         if (_draggingStart) {
    311.             resonance = (mouseX - _draggingStart.x) * 0.02;
    312.             if (resonance < 0) resonance = 0;
    313.             else if (resonance > 0.9) resonance = 0.9;
    314.             cutoff = (_draggingStart.y - mouseY) * 0.02;
    315.             if (cutoff < 0) cutoff = 0;
    316.             else if (cutoff > 1) cutoff = 1;
    317.             _padUpdated = true;
    318.             lpf.control(cutoff, resonance);
    319.         }
    320.     }
    321. }

    322. class VoiceSelector extends Sprite {
    323.     private var _cursor:Bitmap = new Bitmap(new BitmapData(48, 14, true, 0x408080ff));
    324.     private var _categolies:Sprite = new Sprite();
    325.     private var _voiceName:Label;
    326.    
    327.     function VoiceSelector(parent:DisplayObjectContainer, x:Number, y:Number) {
    328.         this.x = x;
    329.         this.y = y;
    330.         parent.addChild(this);
    331.         _categolies.x = 1;
    332.         _categolies.y = 18;
    333.         addChild(_categolies);
    334.         var imax:int = presetVoice.categolies.length, button:PushButton;
    335.         for (var i:int=0; i<imax; i++) {
    336.             var list:Array = presetVoice.categolies[i],
    337.                 label:String = (list.name.charAt() == "v") ? list.name.substr(9) : list.name;
    338.             button = new PushButton(_categolies, (i&7)*50, (i>>3)*16, label, _onCategolyPushed);
    339.             button.setSize(48, 14);
    340.         }
    341.    
    342.         (new PushButton(this,  1, 2, "-", function(e:Event) : void { updateVoice(voiceIndex-1); })).setSize(14, 14);
    343.         (new PushButton(this, 17, 2, "+", function(e:Event) : void { updateVoice(voiceIndex+1); })).setSize(14, 14);
    344.         _categolies.addChild(_cursor);
    345.         _voiceName = new Label(this, 33, 0, "SiON preset voices are from VAL-SOUND");
    346.         _voiceName.setSize(200, 18);
    347.     }
    348.    
    349.     private function _onCategolyPushed(e:Event) : void {
    350.         _cursor.x = e.target.x;
    351.         _cursor.y = e.target.y;
    352.         updateCategoly(int((_cursor.x+10)*0.02) + (int(_cursor.y>8)<<3));
    353.     }

    354.     public function updateName() : void {
    355.         var str:String = ("00"+String(voiceIndex+1)).substr(-3,3) + "; ";
    356.         str += voiceList[voiceIndex].name;
    357.         _voiceName.text = str;
    358.     }
    359.    
    360.     public function onUpdateCategoly() : void {
    361.         _cursor.x = (categolyIndex&7)*50;
    362.         _cursor.y = (categolyIndex>>3)*16;
    363.     }
    364. }

    365. class VolumePanel extends Sprite {
    366.     private var _rev:Knob, _cho:Knob, _prg:Knob;
    367.     function VolumePanel(parent:DisplayObjectContainer, x:Number, y:Number) {
    368.         this.x = x;
    369.         this.y = y;
    370.         parent.addChild(this);
    371.         _prg = _newKnob(this, 12,   0, "Voice",  _onChangeVoice);
    372.         _rev = _newKnob(this, 372,  0, "Delay",  _onChangeEffect);
    373.         _cho = _newKnob(this, 372, 60, "Chorus", _onChangeEffect);
    374.         _prg.showValue = false;
    375.         _rev.value = 20;
    376.         
    377.         function _newKnob(cont:DisplayObjectContainer, x:Number, y:Number, label:String, cb:Function) : Knob {
    378.             var ret:Knob = new Knob(cont, x, y, label, cb);
    379.             ret.radius = 8;
    380.             return ret;
    381.         }
    382.     }
    383.    
    384.     public function onUpdateCategoly() : void {
    385.         _prg.minimum = 0;
    386.         _prg.maximum = voiceList.length;
    387.         _prg.value = voiceIndex;
    388.         _prg.mouseRange = (voiceList.length<20) ? 100 : 200;
    389.     }
    390.    
    391.     public function updateVoiceIndex() : void {
    392.         _prg.value = voiceIndex;
    393.     }
    394.    
    395.     private function _onChangeVoice(e:Event) : void {
    396.         updateVoice(int(_prg.value), true);
    397.     }
    398.    
    399.     private function _onChangeEffect(e:Event) : void {
    400.         delaySendLevel  = _rev.value * 0.01;
    401.         chorusSendLevel = _cho.value * 0.01;
    402.     }
    403. }
    复制代码





    本文来自:http://wonderfl.net/c/fbIa

    本帖子中包含更多资源

    您需要 登录 才可以下载或查看,没有帐号?立即注册

    x
    守望者AIR技术交流社区(www.airmyth.com)
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    
    关闭

    站长推荐上一条 /4 下一条

    QQ|手机版|Archiver|网站地图|小黑屋|守望者 ( 京ICP备14061876号

    GMT+8, 2019-8-19 02:22 , Processed in 0.049529 second(s), 45 queries .

    守望者AIR

    守望者AIR技术交流社区

    本站成立于 2014年12月31日

    快速回复 返回顶部 返回列表