PageRenderTime 20ms CodeModel.GetById 2ms app.highlight 14ms RepoModel.GetById 1ms app.codeStats 1ms

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

https://github.com/watashiwatonydes/ring
ActionScript | 182 lines | 127 code | 26 blank | 29 comment | 35 complexity | 7c192ba5ef5e7a53f70a29bcbc8ce966 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 buffer by Vector.&lt;Number&gt; */
105        public function writeVectorNumber(pointer:Vector.<Number>, startPointer:int, startBuffer:int, len:int, vol:Number, pan:int, sampleChannelCount:int) : void
106        {
107            var i:int, j:int, n:Number, jmax:int, volL:Number, volR:Number;
108            
109            if (channels == 2) {
110                if (sampleChannelCount == 2) {
111                    // stereo data to stereo buffer
112                    vol *= 1.4142135623730951;
113                    volL = _panTable[128-pan] * vol;
114                    volR = _panTable[pan]     * vol;
115                    jmax = (startPointer + len)<<1;
116                    for (j=startPointer<<1, i=startBuffer<<1; j<jmax;) {
117                        buffer[i] += pointer[j] * volL; j++; i++;
118                        buffer[i] += pointer[j] * volR; j++; i++;
119                    }
120                } else {
121                    // monoral data to stereo buffer
122                    volL = _panTable[128-pan] * vol;
123                    volR = _panTable[pan]     * vol;
124                    jmax = startPointer + len;
125                    for (j=startPointer, i=startBuffer<<1; j<jmax; j++) {
126                        n = pointer[j];
127                        buffer[i] += n * volL;  i++;
128                        buffer[i] += n * volR;  i++;
129                    }
130                }
131            } else 
132            if (channels == 1) {
133                if (sampleChannelCount == 2) {
134                    // stereo data to monoral buffer
135                    jmax = (startPointer + len)<<1;
136                    vol  *= 0.6;
137                    for (j=startPointer<<1, i=startBuffer<<1; j<jmax;) {
138                        n  = pointer[j]; j++;
139                        n += pointer[j]; j++;
140                        n *= vol;
141                        buffer[i] += n; i++;
142                        buffer[i] += n; i++;
143                    }
144                } else {
145                    // monoral data to monoral buffer
146                    jmax = startPointer + len;
147                    for (j=startPointer, i=startBuffer<<1; j<jmax; j++) {
148                        n = pointer[j] * vol;
149                        buffer[i] += n; i++;
150                        buffer[i] += n; i++;
151                    }
152                }
153            }
154        }
155        
156        
157        /** write buffer by ByteArray (stereo only). */
158        public function writeByteArray(bytes:ByteArray, start:int, len:int, vol:Number) : void
159        {
160            var i:int, n:Number, imax:int = (start + len)<<1;
161            var initPosition:int = bytes.position;
162
163            if (channels == 2) {
164                for (i=start<<1; i<imax; i++) {
165                    buffer[i] += bytes.readFloat() * vol;
166                }
167            } else 
168            if (channels == 1) {
169                // stereo data to monoral buffer
170                vol  *= 0.6;
171                for (i=start<<1; i<imax;) {
172                    n = (bytes.readFloat() + bytes.readFloat()) * vol;
173                    buffer[i] += n; i++;
174                    buffer[i] += n; i++;
175                }
176            }
177            
178            bytes.position = initPosition;
179        }
180    }
181}
182