root/as3/SiOPM/trunk/src/org/si/sound/Arpeggiator.as

リビジョン 3825, 7.7 kB (コミッタ: keim, コミット時期: 2 年 前)

SiON ver0.60 updated

Line 
1 //----------------------------------------------------------------------------------------------------
2 // Arpeggiator class
3 //  Copyright (c) 2009 keim All rights reserved.
4 //  Distributed under BSD-style license (see org.si.license.txt).
5 //----------------------------------------------------------------------------------------------------
6
7
8 package org.si.sound {
9     import org.si.sion.*;
10     import org.si.sion.utils.Scale;
11     import org.si.sound.patterns.Note;
12     import org.si.sound.patterns.Sequencer;
13     import org.si.sound.namespaces._sound_object_internal;
14    
15     /** @eventType org.si.sound.events.SoundObjectEvent.ENTER_FRAME */
16     [Event(name="enterFrame",   type="org.si.sound.events.SoundObjectEvent")]
17     /** @eventType org.si.sound.events.SoundObjectEvent.ENTER_SEGMENT */
18     [Event(name="enterSegment", type="org.si.sound.events.SoundObjectEvent")]
19    
20     /** Arpeggiator provides monophonic arpeggio pattern sound. */
21     public class Arpeggiator extends PatternSequencer
22     {
23     // namespace
24     //----------------------------------------
25         use namespace _sound_object_internal;
26        
27        
28        
29        
30     // variables
31     //----------------------------------------
32         /** @private [protected] Table of notes on scale */
33         protected var _scale:Scale;
34         /** @private [protected] scale index */
35         protected var _scaleIndex:int;
36
37         /** @private [protected] Current arpeggio pattern. */
38         protected var _currentPattern:Array;
39         /** @private [protected] Next arpeggio pattern to change while playing. */
40         protected var _nextPattern:Array;
41         /** @private [protected] Change bass line pattern at the head of segment. */
42         protected var _changePatternOnSegment:Boolean;
43        
44                
45        
46        
47     // properties
48     //----------------------------------------
49         /** change root note of the scale */
50         override public function get note() : int {
51             return _scale.rootNote;
52         }
53         override public function set note(n:int) : void {
54             _scale.rootNote = n;
55             _scaleIndexUpdated();
56         }
57        
58        
59         /** scale instance */
60         public function get scale() : Scale { return _scale; }
61         public function set scale(s:Scale) : void {
62             _scale.copyFrom(s);
63             _scaleIndexUpdated();
64         }
65        
66        
67         /** specify scale by name */
68         public function get scaleName() : String { return _scale.name; }
69         public function set scaleName(str:String) : void {
70             _scale.name = str;
71             _scaleIndexUpdated();
72         }
73        
74        
75         /** index on scale */
76         public function get scaleIndex() : int { return _scaleIndex; }
77         public function set scaleIndex(i:int) : void {
78             _scaleIndex = i;
79             _note = _scale.getNote(i);
80             _scaleIndexUpdated();
81         }
82        
83        
84         /** note length in 16th beat. */
85         public function get noteLength() : Number { return _sequencer.defaultLength; }
86         public function set noteLength(l:Number) : void {
87             if (l<0.25) l=0.25;
88             else if (l>16) l=16;
89             _sequencer.defaultLength = l;
90             _sequencer.gridStep = l * 120;
91         }
92        
93        
94         /** Note index array of the arpeggio pattern. If the index is out of range, insert rest instead. */
95         public function get pattern() : Array { return _currentPattern || _nextPattern; }
96         public function set pattern(pat:Array) : void {
97             if (isPlaying && _changePatternOnSegment) _nextPattern = pat;
98             else _updateArpeggioPattern(pat);
99         }
100        
101        
102         /** True to change bass line pattern at the head of segment. @default true */
103         public function get changePatternOnNextSegment() : Boolean { return _changePatternOnSegment; }
104         public function set changePatternOnNextSegment(b:Boolean) : void {
105             _changePatternOnSegment = b;
106         }
107        
108        
109         /** [NOT RECOMENDED] Only for the compatibility before version 0.58, the getTime property can be used instead of this property. */
110         public function get noteQuantize() : int { return gateTime * 8; }
111         public function set noteQuantize(q:int) : void { gateTime = q * 0.125; }
112        
113                
114        
115        
116     // constructor
117     //----------------------------------------
118         /** constructor
119          *  @param scale Arpaggio scale, org.si.sion.utils.Scale instance, scale name String or null is suitable.
120          *  @param noteLength length for each note
121          *  @param pattern Note index array of the arpeggio pattern. If the index is out of range, insert rest instead.
122          *  @see org.si.sion.utils.Scale
123          */
124         function Arpeggiator(scale:*=null, noteLength:Number=2, pattern:Array=null)
125         {
126             super();
127             name = "Arpeggiator";
128            
129             _scale = new Scale();
130             if (scale is Scale) _scale.copyFrom(scale as Scale);
131             else if (scale is String) _scale.name = scale as String;
132            
133             _nextPattern = null;
134             _sequencer.defaultLength = 1;
135             _sequencer.pattern = new Vector.<Note>();
136             _sequencer.onEnterFrame = _onEnterFrame;
137             _sequencer.onEnterSegment = _onEnterSegment;
138            
139             _updateArpeggioPattern(pattern);
140         }
141        
142        
143        
144        
145     // operations
146     //----------------------------------------
147         /** @private */
148         override public function reset() : void
149         {
150             super.reset();
151             _scaleIndex = 0;
152         }
153        
154        
155        
156        
157     // internal
158     //----------------------------------------
159         /** @private [protected] call this after the update of note or scale index */
160         protected function _scaleIndexUpdated() : void {
161             var i:int, imax:int = _sequencer.pattern.length;
162             for (i=0; i<imax; i++) {
163                 _sequencer.pattern[i].note = _scale.getNote(_currentPattern[i] + _scaleIndex);
164             }
165         }
166        
167        
168         // set arpeggio pattern
169         private function _updateArpeggioPattern(indexPattern:Array) : void {
170             var i:int, imax:int, note:int, pattern:Vector.<Note>;
171            
172             _currentPattern = indexPattern;
173             if (_currentPattern) {
174                 imax = _currentPattern.length;
175                 _sequencer.pattern.length = imax;
176                 _sequencer.segmentFrameCount = imax;
177                 pattern = _sequencer.pattern;
178                 for (i=0; i<imax; i++) {
179                     if (pattern[i] == null) pattern[i] = new Note();
180                     note = _scale.getNote(_currentPattern[i] + _scaleIndex);
181                     if (note >= 0 && note < 128) {
182                         pattern[i].note = note;
183                         pattern[i].velocity = -1;
184                         pattern[i].length = Number.NaN;
185                     } else {
186                         pattern[i].setRest();
187                     }
188                 }
189             } else {
190                 _sequencer.pattern.length = 0;
191                 _sequencer.segmentFrameCount = 16;
192             }
193         }
194        
195        
196         /** @private [protected] handler on enter segment */
197         override protected function _onEnterSegment(seq:Sequencer) : void
198         {
199             if (_nextPattern != null) {
200                 _updateArpeggioPattern(_nextPattern);
201                 _nextPattern = null;
202             }
203             super._onEnterSegment(seq);
204         }
205     }
206 }
207
Note: リポジトリブラウザについてのヘルプは TracBrowser を参照してください。