bero1985

IT Sample pack stuff

Mar 7th, 2013
122
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Delphi 14.58 KB | None | 0 0
  1. function TEngineSample.SchreibePackedITSample(Daten:TEngineStream;IT215:boolean):boolean;
  2. type PITCompressionTable=^TITCompressionType;
  3.      TITCompressionTable=array[0..16] of longint;
  4.      PITCompressionType=^TITCompressionType;
  5.      TITCompressionType=record
  6.       Mask:longint;
  7.       FetchA:longint;
  8.       LowerB:longint;
  9.       UpperB:longint;
  10.       DefaultWidth:longint;
  11.       LowerTable:TITCompressionTable;
  12.       UpperTable:TITCompressionTable;
  13.      end;
  14. const ITCompressionType8Bit:TITCompressionType=
  15.        (
  16.         Mask:$ff;
  17.         FetchA:3;
  18.         LowerB:-4;
  19.         UpperB:3;
  20.         DefaultWidth:9;
  21.         LowerTable:(0,-1,-3,-7,-15,-31,-60,-124,-128,0,0,0,0,0,0,0,0);
  22.         UpperTable:(0,1,3,7,15,31,59,123,127,0,0,0,0,0,0,0,0);
  23.        );
  24.       ITCompressionType16Bit:TITCompressionType=
  25.        (
  26.         Mask:$ffff;
  27.         FetchA:4;
  28.         LowerB:-8;
  29.         UpperB:7;
  30.         DefaultWidth:17;
  31.         LowerTable:(0,-1,-3,-7,-15,-31,-56,-120,-248,-504,-1016,-2040,-4088,-8184,-16376,-32760,-32768);
  32.         UpperTable:(0,1,3,7,15,31,55,119,247,503,1015,2039,4087,8183,16375,32759,32767);
  33.        );
  34.       ITWidthChangeSize:array[0..16] of longint=(4,5,6,7,8,9,7,8,9,10,11,12,13,14,15,16,17);
  35.       ITBufferSize=$ffff+2;
  36.       ITBlockSize=$8000;
  37. type PBuffer=^TBuffer;
  38.      TBuffer=array[0..ITBufferSize-1] of byte;
  39.      PBlock=^TBlock;
  40.      TBlock=array[0..ITBlockSize-1] of byte;
  41. var PackedData:PBuffer;
  42.     SampleData:PBlock;
  43.     Channel:longint;
  44.     Position:longint;
  45.     Offset:longint;
  46.     Remain:longint;
  47.     PackedLength:longint;
  48.     BitPosition:longint;
  49.     RemainBits:longint;
  50.     ByteValue:longint;
  51.     BaseLength:longint;
  52.     Source:array of array of longint;
  53.     OutData:array of array of longint;
  54.     BitWidthTable:array of longint;
  55.     Data:array of longint;
  56.     TwoBytes:array[0..1] of byte;
  57.     CompressionType:PITCompressionType;
  58.     NewValue:longint;
  59.     OldValue:longint;
  60.     IT215Loop:boolean;
  61.     OK:boolean;
  62.  function ConvertWidth(CurrentWidth,NewWidth:longint):longint;
  63.  begin
  64.   dec(CurrentWidth);
  65.   dec(NewWidth);
  66.   if NewWidth>CurrentWidth then begin
  67.    dec(NewWidth);
  68.   end;
  69.   result:=NewWidth;
  70.  end;
  71.  procedure WriteByte(Value:longint);
  72.  begin
  73.   if PackedLength<ITBufferSize then begin
  74.    PackedData^[PackedLength]:=Value;
  75.    inc(PackedLength);
  76.   end else begin
  77.    OK:=false;
  78.   end;
  79.  end;
  80.  procedure WriteBits(Width,Value:longint);
  81.  begin
  82.   while Width>RemainBits do begin
  83.    ByteValue:=ByteValue or (Value shl BitPosition);
  84.    dec(Width,RemainBits);
  85.    Value:=SARLongint(Value,RemainBits);
  86.    BitPosition:=0;
  87.    RemainBits:=8;
  88.    WriteByte(ByteValue);
  89.    ByteValue:=0;
  90.   end;
  91.   if Width>0 then begin
  92.    ByteValue:=ByteValue or ((Value and (((1 shl Width)-1))) shl BitPosition);
  93.    dec(RemainBits,Width);
  94.    inc(BitPosition,Width);
  95.   end;
  96.  end;
  97.  procedure VerifyITSamplePacked(Daten:TEngineStream;bIT215:boolean);
  98.  type psmallint=^smallint;
  99.       pshortint=^shortint;
  100.  var RemainBits,DataBlockPosition,DataBlockSize,BitPosition,RemainSamples,TotalSamples:longint;
  101.      DataBlock:array of byte;
  102.      Error:boolean;
  103.   function ReadBits(Width:longint):longint;
  104.   var Position,Mask:longint;
  105.   begin
  106.    result:=0;
  107.    Position:=0;
  108.    Mask:=(1 shl Width)-1;
  109.    while (Width>=RemainBits) and (DataBlockPosition<DataBlockSize) do begin
  110.     result:=result or ((DataBlock[DataBlockPosition] shr BitPosition) shl Position);
  111.     inc(Position,RemainBits);
  112.     dec(Width,RemainBits);
  113.     inc(DataBlockPosition);
  114.     RemainBits:=8;
  115.     BitPosition:=0;
  116.    end;
  117.    if (Width>0) and (DataBlockPosition<DataBlockSize) then begin
  118.     result:=(result or ((DataBlock[DataBlockPosition] shr BitPosition) shl Position)) and Mask;
  119.     dec(RemainBits,Width);
  120.     inc(BitPosition,Width);
  121.    end;
  122.   end;
  123.  var Channel,Mem1,Mem2,Remain,Width,DefaultWidth,Value,TopBit,FetchA,LowerB,UpperB,
  124.      Position:longint;
  125.      TwoBytes:array[0..1] of byte;
  126.  begin
  127.   DataBlock:=nil;
  128.   try
  129.    Error:=false;
  130.    TotalSamples:=Laenge;
  131.    if Bits=16 then begin
  132.     DefaultWidth:=17;
  133.     FetchA:=4;
  134.     LowerB:=-8;
  135.     UpperB:=7;
  136.    end else begin
  137.     DefaultWidth:=9;
  138.     FetchA:=3;
  139.     LowerB:=-4;
  140.     UpperB:=3;
  141.    end;
  142.    SetLength(OutData,Kaenale,Laenge);
  143.    for Channel:=0 to Kaenale-1 do begin
  144.     for Position:=0 to Laenge-1 do begin
  145.      OutData[Channel,Position]:=0;
  146.     end;
  147.    end;
  148.    SetLength(DataBlock,65536);
  149.    for Channel:=0 to Kaenale-1 do begin
  150.     Position:=0;
  151.     RemainSamples:=TotalSamples;
  152.     while (RemainSamples>0) and (Daten.Position<Daten.Size) do begin
  153.      if Daten.Read(TwoBytes,SizeOf(TwoBytes))<>SizeOf(TwoBytes) then begin
  154.       Error:=true;
  155.       break;
  156.      end;
  157.      DataBlockSize:=(TwoBytes[0] and $ff) or (TwoBytes[1] shl 8);
  158.      if DataBlockSize=0 then begin
  159.       Error:=true;
  160.       break;
  161.      end;
  162.      if Daten.Read(DataBlock[0],DataBlockSize)<>DataBlockSize then begin
  163.       Error:=true;
  164.       break;
  165.      end;
  166.      DataBlockPosition:=0;
  167.      BitPosition:=0;
  168.      RemainBits:=8;
  169.      Mem1:=0;
  170.      Mem2:=0;
  171.      if Bits=16 then begin
  172.       Remain:=$4000;
  173.      end else begin
  174.       Remain:=$8000;
  175.      end;
  176.      if Remain>RemainSamples then begin
  177.       Remain:=RemainSamples;
  178.      end;
  179.      Width:=DefaultWidth;
  180.      while Remain>0 do begin
  181.       if (Width<1) or (Width>DefaultWidth) or (DataBlockPosition>=DataBlockSize) then begin
  182.        Error:=true;
  183.        break;
  184.       end;
  185.       Value:=ReadBits(Width);
  186.       TopBit:=1 shl (Width-1);
  187.       if Width<=6 then begin
  188.        if Value=TopBit then begin
  189.         Value:=ReadBits(FetchA)+1;
  190.         if Value<Width then begin
  191.          Width:=Value;
  192.         end else begin
  193.          Width:=Value+1;
  194.         end;
  195.         continue;
  196.        end;
  197.       end else if Width<DefaultWidth then begin
  198.        if (Value>=(TopBit+LowerB)) and (Value<=(TopBit+UpperB)) then begin
  199.         Value:=(Value-(TopBit+LowerB))+1;
  200.         if Value<Width then begin
  201.          Width:=Value;
  202.         end else begin
  203.          Width:=Value+1;
  204.         end;
  205.         continue;
  206.        end;
  207.       end else begin
  208.        if (Value and TopBit)<>0 then begin
  209.         Width:=(Value and not TopBit)+1;
  210.         continue;
  211.        end else begin
  212.         Value:=Value and not TopBit;
  213.         TopBit:=0;
  214.        end;
  215.       end;
  216.       if (Value and TopBit)<>0 then begin
  217.        dec(Value,TopBit shl 1);
  218.       end;
  219.       inc(Mem1,Value);
  220.       inc(Mem2,Mem1);
  221.       if bIT215 then begin
  222.        Value:=Mem2;
  223.       end else begin
  224.        Value:=Mem1;
  225.       end;
  226.       if Bits=16 then begin
  227.        OutData[Channel,Position]:=smallint(word(Value and $ffff));
  228.       end else begin
  229.        OutData[Channel,Position]:=shortint(byte(Value and $ff));
  230.       end;
  231.       inc(Position);
  232.       dec(RemainSamples);
  233.       dec(Remain);
  234.      end;
  235.      if Error then begin
  236.       OK:=false;
  237.       break;
  238.      end;
  239.     end;
  240.     if Error then begin
  241.      OK:=false;
  242.      break;
  243.     end;
  244.    end;
  245.    if OK then begin
  246.     for Channel:=0 to Kaenale-1 do begin
  247.      for Position:=0 to Laenge-1 do begin
  248.       if OutData[Channel,Position]<>Source[Channel,Position] then begin
  249.        OK:=false;
  250.        break;
  251.       end;
  252.      end;
  253.      if not OK then begin
  254.       break;
  255.      end;
  256.     end;
  257.    end;
  258.    if Error then begin
  259.     OK:=false;
  260.    end;
  261.   finally
  262.    SetLength(DataBlock,0);
  263.   end;
  264.  end;
  265.  function GetWidthChangeSize(w:longint):longint;
  266.  begin
  267.   if (w<1) or (w>17) then begin
  268.    OK:=false;
  269.   end;
  270.   result:=ITWidthChangeSize[w-1];
  271.   if (w<=6) and (Bits=16) then begin
  272.    inc(result);
  273.   end;
  274.  end;
  275.  procedure Squish(sWidth,lWidth,rWidth,Width,Offset,Len:longint);
  276.  var i,s,e,BlockLen,xlWidth,xrWidth,wcsl,wcss,wcsw,KeepDown,LevelLeft:longint;
  277.  begin
  278.   if (Width+1)<1 then begin
  279.    for i:=Offset to (Offset+Len)-1 do begin
  280.     BitWidthTable[i]:=sWidth;
  281.    end;
  282.   end else begin
  283.    if Width>=CompressionType^.DefaultWidth then begin
  284.     OK:=false;
  285.    end;
  286.    i:=Offset;
  287.    e:=Offset+Len;
  288.    while i<e do begin
  289.     if (Data[i]>=CompressionType^.LowerTable[Width]) and (Data[i]<=CompressionType^.UpperTable[Width]) then begin
  290.      s:=i;
  291.      while (i<e) and ((Data[i]>=CompressionType^.LowerTable[Width]) and (Data[i]<=CompressionType^.UpperTable[Width])) do begin
  292.       inc(i);
  293.      end;
  294.      BlockLen:=i-s;
  295.      if s=Offset then begin
  296.       xlWidth:=lWidth;
  297.      end else begin
  298.       xlWidth:=sWidth;
  299.      end;
  300.      if i=e then begin
  301.       xrWidth:=rWidth;
  302.      end else begin
  303.       xrWidth:=sWidth;
  304.      end;
  305.      wcsl:=GetWidthChangeSize(xlWidth);
  306.      wcss:=GetWidthChangeSize(sWidth);
  307.      wcsw:=GetWidthChangeSize(Width+1);
  308.      if i=BaseLength then begin
  309.       KeepDown:=wcsl+((Width+1)*BlockLen);
  310.       LevelLeft:=wcsl+(sWidth*BlockLen);
  311.       if xlWidth=sWidth then begin
  312.        dec(LevelLeft,wcsl);
  313.       end;
  314.      end else begin
  315.       KeepDown:=wcsl+(((Width+1)*BlockLen)+wcsw);
  316.       LevelLeft:=wcsl+((sWidth*BlockLen)+wcss);
  317.       if xlWidth=sWidth then begin
  318.        dec(LevelLeft,wcsl);
  319.       end;
  320.       if xrWidth=sWidth then begin
  321.        dec(LevelLeft,wcss);
  322.       end;
  323.      end;
  324.      if KeepDown<=LevelLeft then begin
  325.       Squish(Width+1,xlWidth,xrWidth,Width-1,s,BlockLen);
  326.      end else begin
  327.       Squish(sWidth,xlWidth,xrWidth,Width-1,s,BlockLen);
  328.      end;
  329.     end else begin
  330.      BitWidthTable[i]:=sWidth;
  331.      inc(i);
  332.     end;
  333.    end;
  334.   end;
  335.  end;
  336. var Width,NewWidth,TopBit,Value:longint;
  337. begin
  338.  OK:=false;
  339.  PackedData:=nil;
  340.  SampleData:=nil;
  341.  Source:=nil;
  342.  OutData:=nil;
  343.  Data:=nil;
  344.  BitWidthTable:=nil;
  345.  try
  346.   GetMem(PackedData,SizeOf(TBuffer));
  347.   GetMem(SampleData,SizeOf(TBlock));
  348.   SetLength(Source,Kaenale,Laenge);
  349.   SetLength(Data,ITBufferSize*4);
  350.   SetLength(BitWidthTable,ITBufferSize*4);
  351.   case Bits of
  352.    8:begin
  353.     CompressionType:=@ITCompressionType8Bit;
  354.     for Channel:=0 to Kaenale-1 do begin
  355.      for Position:=0 to Laenge-1 do begin
  356.       Source[Channel,Position]:=shortint(byte(pointer(@PAnsiChar(DataPointer)[((Position*Kaenale)+Channel)*SizeOf(Byte)])^));
  357.      end;
  358.     end;
  359.    end;
  360.    16:begin
  361.     CompressionType:=@ITCompressionType16Bit;
  362.     for Channel:=0 to Kaenale-1 do begin
  363.      for Position:=0 to Laenge-1 do begin
  364.       Source[Channel,Position]:=smallint(word(pointer(@PAnsiChar(DataPointer)[((Position*Kaenale)+Channel)*SizeOf(word)])^));
  365.      end;
  366.     end;
  367.    end;
  368.    else begin
  369.     CompressionType:=nil;
  370.    end;
  371.   end;
  372.   if assigned(CompressionType) then begin
  373.    OK:=true;
  374.    for Channel:=0 to Kaenale-1 do begin
  375.     Offset:=0;
  376.     Remain:=Laenge;
  377.     while Remain>0 do begin
  378.      PackedLength:=0;
  379.      BitPosition:=0;
  380.      RemainBits:=8;
  381.      ByteValue:=0;
  382.      BaseLength:=ITBlockSize shr ((Bits shr 3)-1);
  383.      if BaseLength>Remain then begin
  384.       BaseLength:=Remain;
  385.      end;
  386.      for Position:=0 to BaseLength-1 do begin
  387.       Data[Position]:=Source[Channel,Offset+Position];
  388.      end;
  389.      for IT215Loop:=false to IT215 do begin
  390.       case Bits of
  391.        8:begin
  392.         OldValue:=0;
  393.         for Position:=0 to BaseLength-1 do begin
  394.          NewValue:=Data[Position];
  395.          Data[Position]:=shortint(byte(shortint(byte(byte(NewValue)-byte(OldValue)))));
  396.          OldValue:=NewValue;
  397.         end;
  398.        end;
  399.        16:begin
  400.         OldValue:=0;
  401.         for Position:=0 to BaseLength-1 do begin
  402.          NewValue:=Data[Position];
  403.          Data[Position]:=smallint(word(smallint(word(word(NewValue)-word(OldValue)))));
  404.          OldValue:=NewValue;
  405.         end;
  406.        end;
  407.       end;
  408.      end;
  409.      for Position:=0 to BaseLength-1 do begin
  410.       BitWidthTable[Position]:=CompressionType^.DefaultWidth;
  411.      end;
  412.      Squish(CompressionType^.DefaultWidth,CompressionType^.DefaultWidth,CompressionType^.DefaultWidth,CompressionType^.DefaultWidth-2,0,BaseLength);
  413. {    for Position:=0 to BaseLength-1 do begin
  414.       NewWidth:=CompressionType^.DefaultWidth;
  415.       for Width:=CompressionType^.DefaultWidth-1 downto 2 do begin
  416.        Value:=Data[Position];
  417.        if (Value>=CompressionType^.LowerTable[Width]) and (Value<=CompressionType^.UpperTable[Width]) then begin
  418.         if (Value<0) or (Value>=(1 shl (Width-1))) then begin
  419.          NewWidth:=Width+1;
  420.         end else begin
  421.          NewWidth:=Width;
  422.         end;
  423.        end else begin
  424.         break;
  425.        end;
  426.       end;
  427.       BitWidthTable[Position]:=NewWidth;
  428.      end;}
  429.      Width:=CompressionType^.DefaultWidth;
  430.      for Position:=0 to BaseLength-1 do begin
  431.       TopBit:=1 shl (Width-1);
  432.       if Width<>BitWidthTable[Position] then begin
  433.        if Width<=6 then begin
  434.         if Width<=0 then begin
  435.          OK:=false;
  436.          break;
  437.         end;
  438.         WriteBits(Width,TopBit);
  439.         WriteBits(CompressionType^.FetchA,ConvertWidth(Width,BitWidthTable[Position]));
  440.        end else if Width<CompressionType^.DefaultWidth then begin
  441.         WriteBits(Width,(TopBit+CompressionType^.LowerB)+ConvertWidth(Width,BitWidthTable[Position]));
  442.        end else begin
  443.         if (BitWidthTable[Position]-1)<0 then begin
  444.          OK:=false;
  445.          break;
  446.         end;
  447.         WriteBits(Width,TopBit+(BitWidthTable[Position]-1));
  448.        end;
  449.        Width:=BitWidthTable[Position];
  450.       end;
  451.       case Bits of
  452.        8:begin
  453. {       if (byte(Data[Position]) and $ff)>=(1 shl Width) then begin
  454.          OK:=false;
  455.          break;
  456.         end;}
  457.         WriteBits(Width,shortint(byte(byte(Data[Position]) and $ff)) and $ff);
  458.        end;
  459.        16:begin
  460. {       if (word(Data[Position]) and $ffff)>=(1 shl Width) then begin
  461.          OK:=false;
  462.          break;
  463.         end;}
  464.         WriteBits(Width,smallint(word(word(Data[Position]) and $ffff)) and $ffff);
  465.        end;
  466.       end;
  467.      end;
  468.      if RemainBits<>8 then begin
  469.       WriteByte(ByteValue);
  470.      end;
  471.      NewValue:=PackedLength;
  472.      TwoBytes[0]:=NewValue and $ff;
  473.      TwoBytes[1]:=(NewValue shr 8) and $ff;
  474.      if Daten.Write(TwoBytes,SizeOf(TwoBytes))<>SizeOf(TwoBytes) then begin
  475.       OK:=false;
  476.       break;
  477.      end;
  478.      if Daten.Write(PackedData^,PackedLength)<>PackedLength then begin
  479.       OK:=false;
  480.       break;
  481.      end;
  482.      inc(Offset,BaseLength);
  483.      dec(Remain,BaseLength);
  484.     end;
  485.    end;
  486.   end;
  487.   if OK then begin
  488.    Daten.Seek(0,soFromBeginning);
  489.    VerifyITSamplePacked(Daten,IT215);
  490.    if OK then begin
  491.     if Daten.Size>=(Laenge*Kaenale*(Bits shr 3)) then begin
  492.      OK:=false;
  493.     end;
  494.    end;
  495.   end;
  496.   Daten.Seek(0,soFromBeginning);
  497.  finally
  498.   if assigned(PackedData) then begin
  499.    FreeMem(PackedData);
  500.   end;
  501.   if assigned(SampleData) then begin
  502.    FreeMem(SampleData);
  503.   end;
  504.   SetLength(Source,0);
  505.   SetLength(OutData,0);
  506.   SetLength(Data,0);
  507.   SetLength(BitWidthTable,0);
  508.  end;
  509.  result:=OK;
  510. end;
Advertisement
Add Comment
Please, Sign In to add comment