PageRenderTime 324ms CodeModel.GetById 161ms app.highlight 18ms RepoModel.GetById 143ms app.codeStats 0ms

/src/org/si/sion/module/SiOPMStream.as

https://github.com/rustleson/MotIL
ActionScript | 211 lines | 151 code | 28 blank | 32 comment | 42 complexity | fafedaa3dcf70355a2c4b179ac2c2c5f MD5 | raw file
  1//----------------------------------------------------------------------------------------------------
  2// Stream buffer class
  3//  Copyright (c) 2008 keim All rights reserved.
  4//  Distributed under BSD-style license (see org.si.license.txt).
  5//----------------------------------------------------------------------------------------------------
  6
  7package org.si.sion.module {
  8    import flash.utils.ByteArray;
  9    import org.si.utils.SLLint;
 10    
 11    
 12    /** Stream buffer class */
 13    public class SiOPMStream {
 14        // valiables
 15        //--------------------------------------------------
 16        /** number of channels */
 17        public var channels:int = 2;
 18        /** stream buffer */
 19        public var buffer:Vector.<Number> = new Vector.<Number>();
 20
 21        // coefficient of volume/panning
 22        private var _panTable:Vector.<Number>;
 23        private var _i2n:Number;
 24
 25        
 26        
 27        
 28        // constructor
 29        //--------------------------------------------------
 30        /** constructor */
 31        function SiOPMStream()
 32        {
 33            var st:SiOPMTable = SiOPMTable.instance;
 34            _panTable = st.panTable;
 35            _i2n = st.i2n;
 36        }
 37        
 38        
 39        
 40        
 41        // operation
 42        //--------------------------------------------------
 43        /** clear buffer */
 44        public function clear() : void
 45        {
 46            var i:int, imax:int = buffer.length;
 47            for (i=0; i<imax; i++) {
 48                buffer[i] = 0;
 49            }
 50        }
 51        
 52        
 53        /** limit buffered signals between -1 and 1 */
 54        public function limit() : void
 55        {
 56            var n:Number, i:int, imax:int = buffer.length;
 57            for (i=0; i<imax; i++) {
 58                n = buffer[i];
 59                     if (n < -1) buffer[i] = -1;
 60                else if (n >  1) buffer[i] =  1;
 61            }
 62        }
 63        
 64        
 65        /** Quantize buffer by bit rate. */
 66        public function quantize(bitRate:int) : void
 67        {
 68            var i:int, imax:int = buffer.length,
 69                r:Number = 1<<bitRate, ir:Number = 2/r;
 70            for (i=0; i<imax; i++) {
 71                buffer[i] = ((buffer[i] * r) >> 1) * ir;
 72            }
 73        }
 74        
 75        
 76        /** write buffer by org.si.utils.SLLint */
 77        public function write(pointer:SLLint, start:int, len:int, vol:Number, pan:int) : void 
 78        {
 79            var i:int, n:Number, imax:int = (start + len)<<1;
 80            vol *= _i2n;
 81            if (channels == 2) {
 82                // stereo
 83                var volL:Number = _panTable[128-pan] * vol,
 84                    volR:Number = _panTable[pan] * vol;
 85                for (i=start<<1; i<imax;) {
 86                    n = Number(pointer.i);
 87                    buffer[i] += n * volL;  i++;
 88                    buffer[i] += n * volR;  i++;
 89                    pointer = pointer.next;
 90                }
 91            } else 
 92            if (channels == 1) {
 93                // monoral
 94                for (i=start<<1; i<imax;) {
 95                    n = Number(pointer.i) * vol;
 96                    buffer[i] += n; i++;
 97                    buffer[i] += n; i++;
 98                    pointer = pointer.next;
 99                }
100            }
101        }
102        
103        
104        /** write stereo buffer by 2 pipes */
105        public function writeStereo(pointerL:SLLint, pointerR:SLLint, start:int, len:int, vol:Number, pan:int) : void 
106        {
107            var i:int, n:Number, imax:int = (start + len)<<1;
108            vol *= _i2n;
109            if (channels == 2) {
110                // stereo
111                var volL:Number = _panTable[128-pan] * vol,
112                    volR:Number = _panTable[pan] * vol;
113                for (i=start<<1; i<imax;) {
114                    buffer[i] += Number(pointerL.i) * volL;  i++;
115                    buffer[i] += Number(pointerR.i) * volR;  i++;
116                    pointerL = pointerL.next;
117                    pointerR = pointerR.next;
118                }
119            } else 
120            if (channels == 1) {
121                // monoral
122                vol *= 0.5;
123                for (i=start<<1; i<imax;) {
124                    n = Number(pointerL.i + pointerR.i) * vol;
125                    buffer[i] += n; i++;
126                    buffer[i] += n; i++;
127                    pointerL = pointerL.next;
128                    pointerR = pointerR.next;
129                }
130            }
131        }
132        
133        
134        /** write buffer by Vector.&lt;Number&gt; */
135        public function writeVectorNumber(pointer:Vector.<Number>, startPointer:int, startBuffer:int, len:int, vol:Number, pan:int, sampleChannelCount:int) : void
136        {
137            var i:int, j:int, n:Number, jmax:int, volL:Number, volR:Number;
138            
139            if (channels == 2) {
140                if (sampleChannelCount == 2) {
141                    // stereo data to stereo buffer
142                    volL = _panTable[128-pan] * vol;
143                    volR = _panTable[pan]     * vol;
144                    jmax = (startPointer + len)<<1;
145                    for (j=startPointer<<1, i=startBuffer<<1; j<jmax;) {
146                        buffer[i] += pointer[j] * volL; j++; i++;
147                        buffer[i] += pointer[j] * volR; j++; i++;
148                    }
149                } else {
150                    // monoral data to stereo buffer
151                    volL = _panTable[128-pan] * vol * 0.707;
152                    volR = _panTable[pan]     * vol * 0.707;
153                    jmax = startPointer + len;
154                    for (j=startPointer, i=startBuffer<<1; j<jmax; j++) {
155                        n = pointer[j];
156                        buffer[i] += n * volL;  i++;
157                        buffer[i] += n * volR;  i++;
158                    }
159                }
160            } else 
161            if (channels == 1) {
162                if (sampleChannelCount == 2) {
163                    // stereo data to monoral buffer
164                    jmax = (startPointer + len)<<1;
165                    vol  *= 0.5;
166                    for (j=startPointer<<1, i=startBuffer<<1; j<jmax;) {
167                        n  = pointer[j]; j++;
168                        n += pointer[j]; j++;
169                        n *= vol;
170                        buffer[i] += n; i++;
171                        buffer[i] += n; i++;
172                    }
173                } else {
174                    // monoral data to monoral buffer
175                    jmax = startPointer + len;
176                    for (j=startPointer, i=startBuffer<<1; j<jmax; j++) {
177                        n = pointer[j] * vol;
178                        buffer[i] += n; i++;
179                        buffer[i] += n; i++;
180                    }
181                }
182            }
183        }
184        
185        
186        /** write buffer by ByteArray (stereo only). */
187        public function writeByteArray(bytes:ByteArray, start:int, len:int, vol:Number) : void
188        {
189            var i:int, n:Number, imax:int = (start + len)<<1;
190            var initPosition:int = bytes.position;
191
192            if (channels == 2) {
193                for (i=start<<1; i<imax; i++) {
194                    buffer[i] += bytes.readFloat() * vol;
195                }
196            } else 
197            if (channels == 1) {
198                // stereo data to monoral buffer
199                vol  *= 0.6;
200                for (i=start<<1; i<imax;) {
201                    n = (bytes.readFloat() + bytes.readFloat()) * vol;
202                    buffer[i] += n; i++;
203                    buffer[i] += n; i++;
204                }
205            }
206            
207            bytes.position = initPosition;
208        }
209    }
210}
211