forked from LeenkxTeam/LNXSDK
		
	
		
			
	
	
		
			128 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			Haxe
		
	
	
	
	
	
		
		
			
		
	
	
			128 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			Haxe
		
	
	
	
	
	
| 
								 | 
							
								package kha.audio2.ogg.vorbis.data;
							 | 
						||
| 
								 | 
							
								import haxe.ds.Vector;
							 | 
						||
| 
								 | 
							
								import haxe.io.Input;
							 | 
						||
| 
								 | 
							
								import kha.audio2.ogg.tools.MathTools;
							 | 
						||
| 
								 | 
							
								import kha.audio2.ogg.vorbis.VorbisDecodeState;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class Mapping
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    public var couplingSteps:Int; // uint16 
							 | 
						||
| 
								 | 
							
								    public var chan:Vector<MappingChannel>;
							 | 
						||
| 
								 | 
							
								    public var submaps:Int;            // uint8 
							 | 
						||
| 
								 | 
							
								    public var submapFloor:Vector<Int>;   // uint8 varies
							 | 
						||
| 
								 | 
							
								    public var submapResidue:Vector<Int>; // uint8 varies
							 | 
						||
| 
								 | 
							
								    public function new() {
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    public static function read(decodeState:VorbisDecodeState, channels:Int):Mapping
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        var m = new Mapping();
							 | 
						||
| 
								 | 
							
								        var mappingType = decodeState.readBits(16);
							 | 
						||
| 
								 | 
							
								        if (mappingType != 0) {
							 | 
						||
| 
								 | 
							
								            throw new ReaderError(INVALID_SETUP, "mapping type " + mappingType);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        m.chan = new Vector(channels);
							 | 
						||
| 
								 | 
							
								        for (j in 0...channels) {
							 | 
						||
| 
								 | 
							
								            m.chan[j] = new MappingChannel();
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        if (decodeState.readBits(1) != 0) {
							 | 
						||
| 
								 | 
							
								            m.submaps = decodeState.readBits(4)+1;
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								            m.submaps = 1;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        //if (m.submaps > maxSubmaps) {
							 | 
						||
| 
								 | 
							
								        //    maxSubmaps = m.submaps;
							 | 
						||
| 
								 | 
							
								        //}
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        if (decodeState.readBits(1) != 0) {
							 | 
						||
| 
								 | 
							
								            m.couplingSteps = decodeState.readBits(8)+1;
							 | 
						||
| 
								 | 
							
								            for (k in 0...m.couplingSteps) {
							 | 
						||
| 
								 | 
							
								                m.chan[k].magnitude = decodeState.readBits(MathTools.ilog(channels-1));
							 | 
						||
| 
								 | 
							
								                m.chan[k].angle = decodeState.readBits(MathTools.ilog(channels-1));
							 | 
						||
| 
								 | 
							
								                if (m.chan[k].magnitude >= channels) {
							 | 
						||
| 
								 | 
							
								                    throw new ReaderError(INVALID_SETUP);
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								                if (m.chan[k].angle >= channels) {
							 | 
						||
| 
								 | 
							
								                    throw new ReaderError(INVALID_SETUP);
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								                if (m.chan[k].magnitude == m.chan[k].angle) {
							 | 
						||
| 
								 | 
							
								                    throw new ReaderError(INVALID_SETUP);
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								            m.couplingSteps = 0;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // reserved field
							 | 
						||
| 
								 | 
							
								        if (decodeState.readBits(2) != 0) {
							 | 
						||
| 
								 | 
							
								            throw new ReaderError(INVALID_SETUP);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        if (m.submaps > 1) {
							 | 
						||
| 
								 | 
							
								            for (j in 0...channels) {
							 | 
						||
| 
								 | 
							
								                m.chan[j].mux = decodeState.readBits(4);
							 | 
						||
| 
								 | 
							
								                if (m.chan[j].mux >= m.submaps) {
							 | 
						||
| 
								 | 
							
								                    throw new ReaderError(INVALID_SETUP);
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								            for (j in 0...channels) {
							 | 
						||
| 
								 | 
							
								                m.chan[j].mux = 0;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        m.submapFloor = new Vector(m.submaps);
							 | 
						||
| 
								 | 
							
								        m.submapResidue = new Vector(m.submaps);
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        for (j in 0...m.submaps) {
							 | 
						||
| 
								 | 
							
								            decodeState.readBits(8); // discard
							 | 
						||
| 
								 | 
							
								            m.submapFloor[j] = decodeState.readBits(8);
							 | 
						||
| 
								 | 
							
								            m.submapResidue[j] = decodeState.readBits(8);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        return m;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    public function doFloor(floors:Vector<Floor>, i:Int, n:Int, target:Vector<Float>, finalY:Array<Int>, step2Flag:Vector<Bool>) 
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        var n2 = n >> 1;
							 | 
						||
| 
								 | 
							
								        var s = chan[i].mux, floor;
							 | 
						||
| 
								 | 
							
								        var floor = floors[submapFloor[s]];
							 | 
						||
| 
								 | 
							
								        if (floor.type == 0) {
							 | 
						||
| 
								 | 
							
								            throw new ReaderError(INVALID_STREAM);
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								            var g = floor.floor1;
							 | 
						||
| 
								 | 
							
								            var lx = 0, ly = finalY[0] * g.floor1Multiplier;
							 | 
						||
| 
								 | 
							
								            for (q in 1...g.values) {
							 | 
						||
| 
								 | 
							
								                var j = g.sortedOrder[q];
							 | 
						||
| 
								 | 
							
								                if (finalY[j] >= 0)
							 | 
						||
| 
								 | 
							
								                {
							 | 
						||
| 
								 | 
							
								                    var hy = finalY[j] * g.floor1Multiplier;
							 | 
						||
| 
								 | 
							
								                    var hx = g.xlist[j];
							 | 
						||
| 
								 | 
							
								                    VorbisTools.drawLine(target, lx, ly, hx, hy, n2);
							 | 
						||
| 
								 | 
							
								                    lx = hx;
							 | 
						||
| 
								 | 
							
								                    ly = hy;
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            if (lx < n2) {
							 | 
						||
| 
								 | 
							
								                // optimization of: drawLine(target, lx,ly, n,ly, n2);
							 | 
						||
| 
								 | 
							
								                for (j in lx...n2) {
							 | 
						||
| 
								 | 
							
								                    target[j] *= VorbisTools.INVERSE_DB_TABLE[ly];
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class MappingChannel
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    public var magnitude:Int; // uint8 
							 | 
						||
| 
								 | 
							
								    public var angle:Int;     // uint8 
							 | 
						||
| 
								 | 
							
								    public var mux:Int;       // uint8 
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    public function new() {
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 |