root/lang/actionscript/flmml/trunk/src/com/txt_nifty/sketch/flmml/MChannel.as @ 27840

Revision 27840, 15.5 kB (checked in by tekisuke, 6 years ago)

lang/actionscript/flmml/: @11、@12のGBノイズを追加。

Line 
1package com.txt_nifty.sketch.flmml {
2    import __AS3__.vec.Vector;
3
4    public class MChannel {
5        private var m_noteNo:int;
6        private var m_detune:int;
7        private var m_freqNo:int;
8        private var m_envelope1:MEnvelope;     // for VCO
9        private var m_envelope2:MEnvelope;     // for VCF
10        private var m_oscSet1:MOscillator;         // for original wave
11        private var m_oscMod1:MOscMod;
12        private var m_oscSet2:MOscillator;         // for Pitch LFO
13        private var m_oscMod2:MOscMod;
14        private var m_osc2Connect:int;
15        private var m_osc2Sign:Number;
16        private var m_filter:MFilter;
17        private var m_filterConnect:int;
18        private var m_formant:MFormant;
19        private var m_velocity:Number;    // velocity (max:1.0)
20        private var m_panL:Number;
21        private var m_panR:Number;
22        private var m_onCounter:int;
23        private var m_lfoDelay:int;
24        private var m_lfoDepth:Number;
25        private var m_lfoEnd:int;
26        private var m_lpfAmt:Number;
27        private var m_lpfFrq:Number;
28        private var m_lpfRes:Number;
29        private var m_volMode:int;
30        private var m_inSens:Number;
31        private var m_inPipe:int;
32        private var m_outMode:int;
33        private var m_outPipe:int;
34        public    static var PITCH_RESOLUTION:int = 100;
35        protected static var s_init:int = 0;
36        protected static var s_frequencyMap:Vector.<Number> = new Vector.<Number>(128 * PITCH_RESOLUTION);
37        protected static var s_frequencyLen:int;
38        protected static var s_volumeMap:Vector.<Number> = new Vector.<Number>(128);
39        protected static var s_volumeLen:int;
40        protected static var s_samples:Vector.<Number>;            // mono
41        protected static var s_pipeArr:Vector.<Vector.<Number>>;
42
43        public function MChannel() {
44            m_noteNo = 0;
45            m_detune = 0;
46            m_freqNo = 0;
47            m_envelope1 = new MEnvelope(0.0, 60.0/127.0, 30.0/127.0, 1.0/100.0);
48            m_envelope2 = new MEnvelope(0.0, 30.0/127.0, 0.0, 1.0);
49            m_oscSet1 = new MOscillator();
50            m_oscMod1 = m_oscSet1.getCurrent();
51            m_oscSet2 = new MOscillator();
52            m_oscSet2.setForm(MOscillator.SINE);
53            m_oscMod2 = m_oscSet2.getCurrent();
54            m_osc2Connect = 0;
55            m_filter = new MFilter();
56            m_filterConnect = 0;
57            m_formant = new MFormant();
58            m_velocity = 100.0 / 127.0;
59            setPan(64);
60            m_onCounter = 0;
61            m_lfoDelay = 0;
62            m_lfoDepth = 0.0;
63            m_lfoEnd   = 0;
64            m_lpfAmt   = 0;
65            m_lpfFrq   = 0;
66            m_lpfRes   = 0;
67            m_volMode  = 0;
68            setInput(0, 0);
69            setOutput(0, 0);
70        }
71        public static function boot(numSamples:int):void {
72            if (!s_init) {
73                var i:int;
74                s_frequencyLen = s_frequencyMap.length;
75                for(i = 0; i < s_frequencyLen; i++) {
76                    s_frequencyMap[i] = 440.0 * Math.pow(2.0, (i-69*PITCH_RESOLUTION)/(12*PITCH_RESOLUTION));
77                }
78                s_volumeLen = s_volumeMap.length;
79                s_volumeMap[0] = 0.0;
80                for(i = 1; i < s_volumeLen; i++) {
81                    s_volumeMap[i] = Math.pow(10.0, (i-127.0)*(48.0/(127.0*20.0))); // min:-48db
82                    //trace(i+","+s_volumeMap[i]);
83                }
84                s_init = 1;
85            }
86            s_samples = new Vector.<Number>(numSamples);
87            s_samples.fixed = true;
88        }
89        public static function createPipes(num:int):void {
90            s_pipeArr = new Vector.<Vector.<Number>>(num);
91            for (var i:int = 0; i < num; i++) {
92                s_pipeArr[i] = new Vector.<Number>(s_samples.length);
93                for (var j:int = 0; j < s_samples.length; j++) {
94                    s_pipeArr[i][j] = 0;
95                }
96            }
97        }
98        public static function getFrequency(freqNo:int):Number {
99            freqNo = (freqNo < 0) ? 0 : (freqNo >= s_frequencyLen) ? s_frequencyLen-1 : freqNo;
100            return s_frequencyMap[freqNo];
101        }
102        public function setNoteNo(noteNo:int):void {
103            m_noteNo = noteNo;
104            m_freqNo = m_noteNo * PITCH_RESOLUTION + m_detune;
105            m_oscMod1.setFrequency(getFrequency(m_freqNo));
106        }
107        public function setDetune(detune:int):void {
108            m_detune = detune;
109            m_freqNo = m_noteNo * PITCH_RESOLUTION + m_detune;
110            m_oscMod1.setFrequency(getFrequency(m_freqNo));
111        }
112        public function noteOn(noteNo:int, velocity:int):void {
113            setNoteNo(noteNo);
114            m_envelope1.triggerEnvelope();
115            m_envelope2.triggerEnvelope(1);
116            m_oscMod1.resetPhase();
117            m_oscMod2.resetPhase();
118            m_filter.reset();
119            m_velocity = (m_volMode) ? s_volumeMap[velocity] : velocity / 127.0;
120            m_onCounter = 0;
121
122            var modFcNoise:MOscFcNoise = (MOscFcNoise)(m_oscSet1.getMod(MOscillator.FC_NOISE));
123            modFcNoise.setNoiseFreq(noteNo);
124            var modGbLNoise:MOscGbLNoise = (MOscGbLNoise)(m_oscSet1.getMod(MOscillator.GB_NOISE));
125            modGbLNoise.setNoiseFreq(noteNo);
126            var modGbSNoise:MOscGbSNoise = (MOscGbSNoise)(m_oscSet1.getMod(MOscillator.GB_S_NOISE));
127            modGbSNoise.setNoiseFreq(noteNo);
128        }
129        public function noteOff():void {
130            m_envelope1.releaseEnvelope();
131            m_envelope2.releaseEnvelope();
132        }
133        public function close():void {
134            noteOff();
135            m_filter.setSwitch(0);
136        }
137        public function setNoiseFreq(frequency:Number):void {
138            var modNoise:MOscNoise = (MOscNoise)(m_oscSet1.getMod(MOscillator.NOISE));
139            modNoise.setNoiseFreq(1.0 - frequency * (1.0 / 128.0));
140        }
141        public function setForm(form:int):void {
142            m_oscMod1 = m_oscSet1.setForm(form);
143        }
144        public function setEnvelope1AD(attack:int, decay:int):void {
145            m_envelope1.setAD(attack * (1.0 / 127.0), decay * (1.0 / 127.0));
146        }
147        public function setEnvelope1SR(sustain:int, release:int):void {
148            m_envelope1.setSR(sustain * (1.0 / 127.0), release * (1.0 / 127.0));
149        }
150        public function setEnvelope2AD(attack:int, decay:int):void {
151            m_envelope2.setAD(attack * (1.0 / 127.0), decay * (1.0 / 127.0));
152        }
153        public function setEnvelope2SR(sustain:int, release:int):void {
154            m_envelope2.setSR(sustain * (1.0 / 127.0), release * (1.0 / 127.0));
155        }
156        public function setPWM(pwm:int):void {
157            if (m_oscSet1.getForm() != MOscillator.FC_PULSE) {
158                var modPulse:MOscPulse = (MOscPulse)(m_oscSet1.getMod(MOscillator.PULSE));
159                modPulse.setPWM(pwm * (1.0 / 100.0));
160            }
161            else {
162                var modFcPulse:MOscPulse = (MOscPulse)(m_oscSet1.getMod(MOscillator.FC_PULSE));
163                modFcPulse.setPWM(0.125 * Number(pwm));
164            }
165        }
166        public function setPan(pan:int):void {
167            // left 0 - 64 - 127 right
168            // master_vol = 0.25
169            m_panR = (pan - 1) * (0.25 / 63.0);
170            if (m_panR < 0) m_panR = 0;
171            m_panL = (2.0 * 0.25) - m_panR;
172        }
173        public function setFormant(vowel:int):void {
174            if (vowel >= 0) m_formant.setVowel(vowel);
175            else m_formant.disable();
176        }
177        public function setLFODPCN(depth:int, connect:int):void {
178            m_lfoDepth = depth;
179            m_osc2Connect = (depth == 0) ? 0 : 1;
180        }
181        public function setLFOWDFM(freq:Number, form:int):void {
182            m_oscMod2 = m_oscSet2.setForm((form >= 0) ? form-1 : -form-1);
183            m_oscMod2.setFrequency(freq);
184            m_oscMod2.resetPhase();
185            m_osc2Sign = (form >= 0) ? 1.0 : -1.0;
186            if (form >= 5 || form <= -5) m_osc2Connect = 0;
187        }
188        public function setLFODLTM(delay:int, time:int):void {
189            m_lfoDelay = delay;
190            m_lfoEnd = (time > 0) ? m_lfoDelay + time : 0;
191        }
192        public function setLpfSwtAmt(swt:int, amt:int):void {
193            if (-3 < swt && swt < 3 && swt != m_filterConnect) {
194                m_filterConnect = swt;
195                m_filter.setSwitch(swt);
196            }
197            m_lpfAmt = ((amt < -127) ? -127 : (amt < 127) ? amt : 127) * PITCH_RESOLUTION;
198        }
199        public function setLpfFrqRes(frq:int, res:int):void {
200            if (frq < 0) frq = 0;
201            if (frq > 127) frq = 127;
202            m_lpfFrq = frq * PITCH_RESOLUTION;
203            m_lpfRes = res * (1.0 / 127.0);
204            if (m_lpfRes < 0.0) m_lpfRes = 0.0;
205            if (m_lpfRes > 1.0) m_lpfRes = 1.0;
206        }
207        public function setVolMode(m:int):void {
208            m_volMode = m;
209        }
210        public function setInput(i:int, p:int):void {
211            m_inSens = (1<<(i-1)) * (1.0 / 8.0) * MOscMod.PHASE_LEN;
212            m_inPipe = p;
213        }
214        public function setOutput(o:int, p:int):void {
215            m_outMode = o;
216            m_outPipe = p;
217        }
218        protected function getNextSampleLinear():Number {
219            return m_oscMod1.getNextSample() * m_envelope1.getNextAmplitudeLinear() * m_velocity;
220        }
221        protected function getNextSampleNonLinear():Number {
222            return m_oscMod1.getNextSample() * m_envelope1.getNextAmplitudeNonLinear() * m_velocity;
223        }
224        protected function getNextSampleLinearOfs(ofs:Number):Number {
225            return m_oscMod1.getNextSampleOfs(ofs) * m_envelope1.getNextAmplitudeLinear() * m_velocity;
226        }
227        protected function getNextSampleNonLinearOfs(ofs:Number):Number {
228            return m_oscMod1.getNextSampleOfs(ofs) * m_envelope1.getNextAmplitudeNonLinear() * m_velocity;
229        }
230        protected function getNextCutoff():Number {
231            var cut:Number = m_lpfFrq + m_lpfAmt * m_envelope2.getNextAmplitudeLinear();
232            cut = getFrequency(cut) * m_oscMod1.getFrequency() * (2.0 * Math.PI / (MSequencer.RATE44100 * 440.0));
233            if (cut < (1.0/127.0)) cut = 0.0;
234            return cut;
235         }
236        public function getSamples(samples:Vector.<Number>, max:int, start:int, delta:int):void {
237            var end:int = start + delta;
238            var amplitude:Number;
239            var freqNo:int;
240            var i:int;
241            if (end >= max) end = max;
242            var key:Number = m_oscMod1.getFrequency();
243            if (!m_envelope1.isPlaying()) {
244                for(i = start; i < end; i++) s_samples[i] = 0.0;
245            }
246            else if (m_inSens < 0.000001) {
247                if (m_osc2Connect == 0) {
248                    // no input, no LFO
249                    m_oscMod1.getSamples(s_samples, start, end);
250                    if (m_volMode == 0) m_envelope1.ampSamplesLinear(s_samples, start, end, m_velocity);
251                    else m_envelope1.ampSamplesNonLinear(s_samples, start, end, m_velocity);
252                }
253                else {
254                    // no input, with LFO
255                    var lfoDelta:int = 245;
256                    var s:int = start;
257                    var e:int;
258                    do {
259                        e = s + lfoDelta;
260                        if (e > end) e = end;
261                        freqNo = m_freqNo;
262                        if (m_onCounter >= m_lfoDelay && (m_lfoEnd == 0 || m_onCounter < m_lfoEnd)) {
263                            freqNo += m_oscMod2.getNextSample() * m_osc2Sign * m_lfoDepth;
264                            m_oscMod2.addPhase(e - s - 1);
265                        }
266                        m_oscMod1.setFrequency(getFrequency(freqNo));
267                        m_oscMod1.getSamples(s_samples, s, e);
268                        if (m_volMode == 0) m_envelope1.ampSamplesLinear(s_samples, s, e, m_velocity);
269                        else m_envelope1.ampSamplesNonLinear(s_samples, s, e, m_velocity);
270                        m_onCounter += e - s;
271                        s = e;
272                    } while(s < end)
273                }
274            }
275            // with input
276            else {
277                //trace("input "+m_inPipe);
278                if (m_osc2Connect == 0) {
279                    // with input, no LFO
280                    freqNo = getFrequency(m_freqNo);
281                    if (m_volMode == 0) {
282                        m_oscMod1.setFrequency(freqNo);
283                        for(i = start; i < end; i++) {
284                            s_samples[i] = getNextSampleLinearOfs(s_pipeArr[m_inPipe][i] * m_inSens);
285                        }
286                    }
287                    else {
288                        m_oscMod1.setFrequency(freqNo);
289                        for(i = start; i < end; i++) {
290                            s_samples[i] = getNextSampleNonLinearOfs(s_pipeArr[m_inPipe][i] * m_inSens);
291                        }
292                    }
293                }
294                else {
295                    // with input, with LFO, linear
296                    if (m_volMode == 0) {
297                        for(i = start; i < end; i++) {
298                            freqNo = m_freqNo;
299                            if (m_onCounter >= m_lfoDelay && (m_lfoEnd == 0 || m_onCounter < m_lfoEnd)) {
300                                freqNo += m_oscMod2.getNextSample() * m_osc2Sign * m_lfoDepth;
301                            }
302                            m_oscMod1.setFrequency(getFrequency(freqNo));
303                            s_samples[i] = getNextSampleLinearOfs(s_pipeArr[m_inPipe][i] * m_inSens);
304                            m_onCounter++;
305                        }
306                    }
307                    // with input, with LFO, non linear
308                    else {
309                        for(i = start; i < end; i++) {
310                            freqNo = m_freqNo;
311                            if (m_onCounter >= m_lfoDelay && (m_lfoEnd == 0 || m_onCounter < m_lfoEnd)) {
312                                freqNo += m_oscMod2.getNextSample() * m_osc2Sign * m_lfoDepth;
313                            }
314                            m_oscMod1.setFrequency(getFrequency(freqNo));
315                            s_samples[i] = getNextSampleNonLinearOfs(s_pipeArr[m_inPipe][i] * m_inSens);
316                            m_onCounter++;
317                        }
318                    }
319                }
320            }
321            m_formant.run(s_samples, start, end);
322            m_filter.run(s_samples, start, end, m_envelope2, m_lpfFrq, m_lpfAmt, m_lpfRes, key);
323            switch(m_outMode) {
324            case 0:
325                //trace("output audio");
326                for(i = start; i < end; i++) {
327                    amplitude = s_samples[i];
328                    samples[i+i]   += amplitude * m_panL;
329                    samples[i+i+1] += amplitude * m_panR;
330                }
331                break;
332            case 1: // overwrite
333                //trace("output "+m_outPipe);
334                for(i = start; i < end; i++) {
335                    s_pipeArr[m_outPipe][i] = s_samples[i];
336                }
337                break;
338            case 2: // add
339                for(i = start; i < end; i++) {
340                    s_pipeArr[m_outPipe][i] += s_samples[i];
341                }
342                break;
343            default:
344                break;
345            }
346        }
347    }
348}
Note: See TracBrowser for help on using the browser.