initial commit
[rofl0r-KOL.git] / units / mp3 / KolSubBand1.pas
blobd17894ee0a4176a6752adb02d59bc24b1c46f73b
1 (*
2 * File: $RCSfile: SubBand1.pas,v $
3 * Revision: $Revision: 1.1.1.1 $
4 * Version : $Id: SubBand1.pas,v 1.1.1.1 2002/04/21 12:57:23 fobmagog Exp $
5 * Author: $Author: fobmagog $
6 * Homepage: http://delphimpeg.sourceforge.net/
7 * Kol translation by Thaddy de Koning
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 unit KolSubBand1;
25 interface
27 uses
28 Windows, kol, kolShared, kolBitStream, kolHeader, kolSynthFilter, kolSubBand, kolCRC;
30 type
31 // class for layer I subbands in single channel mode:
32 PSubBandLayer1 = ^TSubbandlayer1;
33 TSubBandLayer1 = object(TSubBand)
34 protected
35 FSubBandNumber: cardinal;
36 FSampleNumber: cardinal;
37 FAllocation: cardinal;
38 FScaleFactor: single;
39 FSampleLength: cardinal;
40 FSample: single;
41 FFactor, FOffset: single;
43 public
44 // constructor Create(SubBandNumber: Cardinal); virtual;
46 procedure ReadAllocation(Stream: PBitStream; Header: PHeader; CRC: PCRC16); virtual;
47 procedure ReadScaleFactor(Stream: PBitStream; Header: PHeader); virtual;
48 function ReadSampleData(Stream: PBitStream): boolean; virtual;
49 function PutNextSample(Channels: TChannels;
50 Filter1, Filter2: PSynthesisFilter): boolean; virtual;
51 end;
53 // class for layer I subbands in joint stereo mode:
54 PSubBandLayer1IntensityStereo = ^TSubBandLayer1IntensityStereo;
55 TSubBandLayer1IntensityStereo = object(TSubBandLayer1)
56 protected
57 FChannel2ScaleFactor: single;
59 public
60 procedure ReadScaleFactor(Stream: PBitStream; Header: PHeader); virtual;
61 function PutNextSample(Channels: TChannels;
62 Filter1, Filter2: PSynthesisFilter): boolean; virtual;
63 end;
65 // class for layer I subbands in stereo mode:
66 PSubbandlayer1Stereo = ^TSubbandlayer1Stereo;
67 TSubBandLayer1Stereo = object(TSubBandLayer1)
68 protected
69 FChannel2Allocation: cardinal;
70 FChannel2ScaleFactor: single;
71 FChannel2SampleLength: cardinal;
72 FChannel2Sample: single;
73 FChannel2Factor: single;
74 FChannel2Offset: single;
76 public
77 procedure ReadAllocation(Stream: PBitStream; Header: PHeader; CRC: PCRC16); virtual;
78 procedure ReadScaleFactor(Stream: PBitStream; Header: PHeader); virtual;
79 function ReadSampleData(Stream: PBitStream): boolean; virtual;
80 function PutNextSample(Channels: TChannels;
81 Filter1, Filter2: PSynthesisFilter): boolean; virtual;
82 end;
83 function newSubBandLayer1(SubBandNumber: cardinal): PSubBandLayer1;
84 function newSubBandLayer1Stereo(SubBandNumber: cardinal): PSubBandLayer1Stereo;
85 function newSubBandLayer1Intensitystereo(SubBandNumber: cardinal)
86 : PSubBandLayer1Intensitystereo;
88 implementation
90 uses
91 kolScaleFac;
93 const
94 // factors and offsets for sample requantization:
95 TableFactor: array[0..14] of single = (0.0, (1.0 / 2.0) * (4.0 / 3.0),
96 (1.0 / 4.0) * (8.0 / 7.0), (1.0 / 8.0) * (16.0 / 15.0),
97 (1.0 / 16.0) * (32.0 / 31.0), (1.0 / 32.0) * (64.0 / 63.0),
98 (1.0 / 64.0) * (128.0 / 127.0),
99 (1.0 / 128.0) * (256.0 / 255.0), (1.0 / 256.0) * (512.0 / 511.0),
100 (1.0 / 512.0) * (1024.0 / 1023.0), (1.0 / 1024.0) * (2048.0 / 2047.0),
101 (1.0 / 2048.0) * (4096.0 / 4095.0), (1.0 / 4096.0) * (8192.0 / 8191.0),
102 (1.0 / 8192.0) * (16384.0 / 16383.0), (1.0 / 16384.0) * (32768.0 / 32767.0));
104 TableOffset: array[0..14] of single = (0.0, ((1.0 / 2.0) - 1.0) * (4.0 / 3.0),
105 ((1.0 / 4.0) - 1.0) * (8.0 / 7.0), ((1.0 / 8.0) - 1.0) * (16.0 / 15.0),
106 ((1.0 / 16.0) - 1.0) * (32.0 / 31.0), ((1.0 / 32.0) - 1.0) * (64.0 / 63.0),
107 ((1.0 / 64.0) - 1.0) * (128.0 / 127.0),
108 ((1.0 / 128.0) - 1.0) * (256.0 / 255.0), ((1.0 / 256.0) - 1.0) * (512.0 / 511.0),
109 ((1.0 / 512.0) - 1.0) * (1024.0 / 1023.0),
110 ((1.0 / 1024.0) - 1.0) * (2048.0 / 2047.0),
111 ((1.0 / 2048.0) - 1.0) * (4096.0 / 4095.0),
112 ((1.0 / 4096.0) - 1.0) * (8192.0 / 8191.0),
113 ((1.0 / 8192.0) - 1.0) * (16384.0 / 16383.0),
114 ((1.0 / 16384.0) - 1.0) * (32768.0 / 32767.0));
116 { TSubBandLayer1 }
118 function newSubBandLayer1Intensitystereo(SubBandNumber: cardinal)
119 : PSubBandLayer1Intensitystereo;
120 begin
121 New(Result, Create);
122 Result.FSubBandNumber := SubBandNumber;
123 Result.FSampleNumber := 0;
124 end;
126 function newSubBandLayer1(SubBandNumber: cardinal): PSubBandLayer1;
127 begin
128 New(Result, Create);
129 Result.FSubBandNumber := SubBandNumber;
130 Result.FSampleNumber := 0;
131 end;
133 function newSubBandLayer1Stereo(SubBandNumber: cardinal): PSubBandLayer1Stereo;
134 begin
135 New(Result, Create);
136 Result.FSubBandNumber := SubBandNumber;
137 Result.FSampleNumber := 0;
138 end;
140 function TSubBandLayer1.PutNextSample(Channels: TChannels; Filter1,
141 Filter2: PSynthesisFilter): boolean;
142 var
143 ScaledSample: single;
144 begin
145 if (FAllocation <> 0) and (Channels <> Right) then
146 begin
147 ScaledSample := (FSample * FFactor + FOffset) * FScalefactor;
148 Filter1.InputSample(ScaledSample, FSubBandNumber);
149 end;
151 Result := True;
152 end;
154 procedure TSubBandLayer1.ReadAllocation(Stream: PBitStream;
155 Header: PHeader; CRC: PCRC16);
156 begin
157 FAllocation := Stream.GetBits(4);
158 if (FAllocation = 15) then;
159 // cerr << "WARNING: stream contains an illegal allocation!\n"; // MPEG-stream is corrupted!
161 if (CRC <> nil) then
162 CRC.AddBits(FAllocation, 4);
164 if (FAllocation <> 0) then
165 begin
166 FSampleLength := FAllocation + 1;
167 FFactor := TableFactor[FAllocation];
168 FOffset := TableOffset[FAllocation];
169 end;
170 end;
172 function TSubBandLayer1.ReadSampleData(Stream: PBitStream): boolean;
173 begin
174 if (FAllocation <> 0) then
175 FSample := Stream.GetBitsFloat(FSampleLength);
177 inc(FSampleNumber);
178 if (FSampleNumber = 12) then
179 begin
180 FSampleNumber := 0;
181 Result := True;
182 end
183 else
184 Result := False;
185 end;
187 procedure TSubBandLayer1.ReadScaleFactor(Stream: PBitStream;
188 Header: PHeader);
189 begin
190 if (FAllocation <> 0) then
191 FScalefactor := ScaleFactors[Stream.GetBits(6)];
192 end;
194 { TSubBandLayer1IntensityStereo }
196 function TSubBandLayer1IntensityStereo.PutNextSample(Channels: TChannels;
197 Filter1, Filter2: PSynthesisFilter): boolean;
198 var
199 Sample1, Sample2: single;
200 begin
201 if (FAllocation <> 0) then
202 begin
203 FSample := FSample * FFactor + FOffset; // requantization
204 if (Channels = Both) then
205 begin
206 Sample1 := FSample * FScalefactor;
207 Sample2 := FSample * FChannel2ScaleFactor;
208 Filter1.InputSample(Sample1, FSubBandNumber);
209 Filter2.InputSample(Sample2, FSubBandNumber);
210 end
211 else if (Channels = Left) then
212 begin
213 Sample1 := FSample * FScaleFactor;
214 Filter1.InputSample(Sample1, FSubBandNumber);
215 end
216 else
217 begin
218 Sample2 := FSample * FChannel2ScaleFactor;
219 Filter2.InputSample(Sample2, FSubBandNumber);
220 end;
221 end;
223 Result := True;
224 end;
226 procedure TSubBandLayer1IntensityStereo.ReadScaleFactor(Stream: PBitStream;
227 Header: PHeader);
228 begin
229 if (FAllocation <> 0) then
230 begin
231 FScaleFactor := ScaleFactors[Stream.GetBits(6)];
232 FChannel2ScaleFactor := ScaleFactors[Stream.GetBits(6)];
233 end;
234 end;
236 { TSubBandLayer1Stereo }
238 function TSubBandLayer1Stereo.PutNextSample(Channels: TChannels; Filter1,
239 Filter2: PSynthesisFilter): boolean;
240 var
241 Sample2: single;
242 begin
243 inherited PutNextSample(Channels, Filter1, Filter2);
244 if (FChannel2Allocation <> 0) and (Channels <> Left) then
245 begin
246 Sample2 := (FChannel2Sample * FChannel2Factor + FChannel2Offset) * FChannel2ScaleFactor;
247 if (Channels = Both) then
248 Filter2.InputSample(Sample2, FSubBandNumber)
249 else
250 Filter1.InputSample(Sample2, FSubBandNumber);
251 end;
253 Result := True;
254 end;
256 procedure TSubBandLayer1Stereo.ReadAllocation(Stream: PBitStream;
257 Header: PHeader; CRC: PCRC16);
258 begin
259 FAllocation := Stream.GetBits(4);
260 FChannel2Allocation := Stream.GetBits(4);
261 if (CRC <> nil) then
262 begin
263 CRC.AddBits(FAllocation, 4);
264 CRC.AddBits(FChannel2Allocation, 4);
265 end;
267 if (FAllocation <> 0) then
268 begin
269 FSamplelength := FAllocation + 1;
270 FFactor := TableFactor[FAllocation];
271 FOffset := TableOffset[FAllocation];
272 end;
274 if (FChannel2Allocation <> 0) then
275 begin
276 FChannel2SampleLength := FChannel2Allocation + 1;
277 FChannel2Factor := TableFactor[FChannel2Allocation];
278 FChannel2Offset := TableOffset[FChannel2Allocation];
279 end;
280 end;
282 function TSubBandLayer1Stereo.ReadSampleData(Stream: PBitStream): boolean;
283 begin
284 Result := inherited ReadSampleData(Stream);
286 if (FChannel2Allocation <> 0) then
287 FChannel2Sample := Stream.GetBitsFloat(FChannel2SampleLength);
288 end;
290 procedure TSubBandLayer1Stereo.ReadScaleFactor(Stream: PBitStream;
291 Header: PHeader);
292 begin
293 if (FAllocation <> 0) then
294 FScaleFactor := ScaleFactors[Stream.GetBits(6)];
296 if (FChannel2Allocation <> 0) then
297 FChannel2ScaleFactor := ScaleFactors[Stream.GetBits(6)];
298 end;
300 end.