1 (*
2  * The contents of this file are subject to the Mozilla Public License
3  * Version 1.1 (the "License"); you may not use this file except in
4  * compliance with the License. You may obtain a copy of the License at
5  * http://www.mozilla.org/MPL/
6  *
7  * Software distributed under the License is distributed on an "AS IS"
8  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
9  * License for the specific language governing rights and limitations
10  * under the License.
11  *
12  * The Initial Developer of this code is John Hansen.
13  * Portions created by John Hansen are Copyright (C) 2009 John Hansen.
14  * All Rights Reserved.
15  *
16  *)
17 unit uCommonUtils;
18 
19 interface
20 
21 uses
22   Classes;
23 
24 const
25   DEFAULT_CHARSET = 1;
26   SW_SHOWMINNOACTIVE = 7;
27   HKEY_CLASSES_ROOT  = LongWord($80000000);
28   HKEY_CURRENT_USER  = LongWord($80000001);
29   HKEY_LOCAL_MACHINE = LongWord($80000002);
30 
31 type
32   HWND = type LongWord;
33 
34 type
35   TWaveFormatEx = packed record
36     wFormatTag: Word;         { format type }
37     nChannels: Word;          { number of channels (i.e. mono, stereo, etc.) }
38     nSamplesPerSec: Cardinal;  { sample rate }
39     nAvgBytesPerSec: Cardinal; { for buffer estimation }
40     nBlockAlign: Word;      { block size of data }
41     wBitsPerSample: Word;   { number of bits per sample of mono data }
42     cbSize: Word;           { the count in bytes of the size of }
43   end;
44 
45 type
46   _mthd = record
47     id : array[0..3] of Char;
48     len : Cardinal;
49     fmt : Word;
50     track : Word;
51     div_ : Word;
52   end;
53   MTHD = _mthd;
54 
55 type
56   _mtrk = record
57     id : array[0..3] of Char;
58     len : Cardinal;
59   end;
60   MTRK = _mtrk;
61 
62 
63 procedure WriteSmallIntToStream(aStream : TStream; value : SmallInt; bLittleEndian : Boolean = True);
64 procedure ReadSmallIntFromStream(aStream : TStream; var value : SmallInt; bLittleEndian : Boolean = True);
65 procedure WriteWordToStream(aStream : TStream; value : Word; bLittleEndian : Boolean = True);
66 procedure ReadWordFromStream(aStream : TStream; var value : Word; bLittleEndian : Boolean = True);
67 procedure WriteCardinalToStream(aStream : TStream; value : Cardinal; bLittleEndian : Boolean = True);
68 procedure ReadCardinalFromStream(aStream : TStream; var value : Cardinal; bLittleEndian : Boolean = True);
69 procedure WriteWaveFormatToStream(aStream : TStream; fmt : TWaveFormatEx);
ReadMIDIMTHDFromStreamnull70 function ReadMIDIMTHDFromStream(aStream : TStream; var head : MTHD) : boolean;
ReadMIDIMTRKFromStreamnull71 function ReadMIDIMTRKFromStream(aStream : TStream; var head : MTRK) : boolean;
HiWordnull72 function HiWord(L: Cardinal): Word;
HiBytenull73 function HiByte(W: Word): Byte;
GetBytenull74 function GetByte(val : Cardinal; idx : integer) : Byte;
BytesToCardinalnull75 function BytesToCardinal(b1 : byte; b2 : byte = 0; b3 : byte = 0; b4 : Byte = 0) : Cardinal; {overload;}
BytesToCardinalnull76 //function BytesToCardinal(b : array of byte) : Cardinal; overload;
77 procedure GetFileList(const Directory : string; const Pattern : string; List : TStringlist);
78 procedure GetSubDirectories(const Directory : string; List : TStringlist);
79 procedure OSSleep(const ms : Cardinal);
80 procedure PostWindowMessage(aHwnd : HWND; aMsg : Cardinal; wParam, lParam : Integer);
MulDivnull81 function MulDiv(const x, num, den : integer) : integer;
CardinalToSinglenull82 function CardinalToSingle(const cVal : Cardinal) : Single;
SingleToCardinalnull83 function SingleToCardinal(const sVal : Single) : Cardinal;
StripTrailingZerosnull84 function StripTrailingZeros(const aNum : string) : string;
85 
86 implementation
87 
88 uses
89 {$IFNDEF FPC}
90   Windows,
91 {$ENDIF}
92   SysUtils;
93 
94 procedure WriteWordToStream(aStream : TStream; value : Word; bLittleEndian : Boolean);
95 var
96   B1, B2 : byte;
97 begin
98   if bLittleEndian then
99   begin
100     B1 := Lo(value);
101     B2 := Hi(value);
102   end
103   else
104   begin
105     B1 := Hi(value);
106     B2 := Lo(value);
107   end;
108   aStream.Write(B1, 1);
109   aStream.Write(B2, 1);
110 end;
111 
112 procedure WriteSmallIntToStream(aStream : TStream; value : SmallInt; bLittleEndian : Boolean);
113 begin
114   WriteWordToStream(aStream, Word(value), bLittleEndian);
115 end;
116 
117 procedure ReadWordFromStream(aStream : TStream; var value : Word; bLittleEndian : Boolean);
118 var
119   B1, B2 : byte;
120 begin
121   B1 := 0;
122   B2 := 0;
123   aStream.Read(B1, 1);
124   aStream.Read(B2, 1);
125   if bLittleEndian then
126   begin
127     value := Word(Word(B1) + (Word(B2) shl 8));
128   end
129   else
130   begin
131     value := Word(Word(B2) + (Word(B1) shl 8));
132   end;
133 end;
134 
135 procedure ReadSmallIntFromStream(aStream : TStream; var value : SmallInt; bLittleEndian : Boolean);
136 var
137   w : word;
138 begin
139   w := 0;
140   ReadWordFromStream(aStream, w, bLittleEndian);
141   value := SmallInt(w);
142 end;
143 
144 procedure WriteCardinalToStream(aStream : TStream; value : Cardinal; bLittleEndian : Boolean);
145 var
146   b1, b2, b3, b4 : byte;
147 begin
148   if bLittleEndian then
149   begin
150     b1 := GetByte(value, 0);
151     b2 := GetByte(value, 1);
152     b3 := GetByte(value, 2);
153     b4 := GetByte(value, 3);
154   end
155   else
156   begin
157     b1 := GetByte(value, 3);
158     b2 := GetByte(value, 2);
159     b3 := GetByte(value, 1);
160     b4 := GetByte(value, 0);
161   end;
162   aStream.Write(b1, 1);
163   aStream.Write(b2, 1);
164   aStream.Write(b3, 1);
165   aStream.Write(b4, 1);
166 end;
167 
168 procedure ReadCardinalFromStream(aStream : TStream; var value : Cardinal; bLittleEndian : Boolean);
169 var
170   b1, b2, b3, b4 : byte;
171 begin
172   b1 := 0; b2 := 0; b3 := 0; b4 := 0;
173   aStream.Read(b1, 1);
174   aStream.Read(b2, 1);
175   aStream.Read(b3, 1);
176   aStream.Read(b4, 1);
177   if bLittleEndian then
178   begin
179     value := BytesToCardinal(b1, b2, b3, b4);
180   end
181   else
182   begin
183     value := BytesToCardinal(b4, b3, b2, b1);
184   end;
185 end;
186 
187 procedure WriteWaveFormatToStream(aStream : TStream; fmt : TWaveFormatEx);
188 begin
189   WriteWordToStream(aStream, fmt.wFormatTag);
190   WriteWordToStream(aStream, fmt.nChannels);
191   WriteCardinalToStream(aStream, fmt.nSamplesPerSec);
192   WriteCardinalToStream(aStream, fmt.nAvgBytesPerSec);
193   WriteWordToStream(aStream, fmt.nBlockAlign);
194   WriteWordToStream(aStream, fmt.wBitsPerSample);
195   WriteWordToStream(aStream, fmt.cbSize);
196 end;
197 
ReadMIDIMTHDFromStreamnull198 function ReadMIDIMTHDFromStream(aStream : TStream; var head : MTHD) : boolean;
199 begin
200   try
201     aStream.Read(head.id, 4);
202     ReadCardinalFromStream(aStream, head.len, False);
203     ReadWordFromStream(aStream, head.fmt, False);
204     ReadWordFromStream(aStream, head.track, False);
205     ReadWordFromStream(aStream, head.div_, False);
206     Result := True;
207   except
208     Result := False;
209   end;
210 end;
211 
ReadMIDIMTRKFromStreamnull212 function ReadMIDIMTRKFromStream(aStream : TStream; var head : MTRK) : boolean;
213 begin
214   try
215     aStream.Read(head.id, 4);
216     ReadCardinalFromStream(aStream, head.len, False);
217     Result := True;
218   except
219     Result := False;
220   end;
221 end;
222 
HiWordnull223 function HiWord(L: Cardinal): Word;
224 begin
225   Result := Word(L shr 16);
226 end;
227 
HiBytenull228 function HiByte(W: Word): Byte;
229 begin
230   Result := Byte(W shr 8);
231 end;
232 
GetBytenull233 function GetByte(val : Cardinal; idx : integer) : Byte;
234 begin
235   case idx of
236     0 : Result := Lo(Word(val));
237     1 : Result := Hi(Word(val));
238     2 : Result := Lo(HiWord(val));
239     3 : Result := Hi(HiWord(val));
240   else
241     Result := 0;
242   end;
243 end;
244 
245 procedure OSSleep(const ms : Cardinal);
246 begin
247 {$IFDEF FPC}
248 // not sure what to do here yet
249 {$ELSE}
250   Windows.Sleep(ms);
251 {$ENDIF}
252 end;
253 
254 procedure PostWindowMessage(aHwnd : HWND; aMsg : Cardinal; wParam, lParam : Integer);
255 begin
256 {$IFDEF FPC}
257 //  ;
258 {$ELSE}
259   PostMessage(aHwnd, aMsg, wParam, lParam);
260 {$ENDIF}
261 end;
262 
MulDivnull263 function MulDiv(const x, num, den : integer) : integer;
264 begin
265   Result := (x * num) div den;
266 end;
267 
BytesToCardinalnull268 function BytesToCardinal(b1 : byte; b2 : byte = 0; b3 : byte = 0; b4 : Byte = 0) : Cardinal;
269 begin
270   Result := Cardinal(b1) + (Cardinal(b2) shl 8) + (Cardinal(b3) shl 16) + (Cardinal(b4) shl 24);
271 end;
272 
273 {
274 function BytesToCardinal(b : array of byte) : Cardinal;
275 var
276   i : integer;
277 begin
278   Result := 0;
279   for i := Low(b) to High(b) do
280     Result := (Result shl 8) + b[i];
281 end;
282 }
283 
284 {$ifdef FPC}
CardinalToSinglenull285 function CardinalToSingle(const cVal : Cardinal) : Single;
286 begin
287   Result := Single(cVal);
288 end;
289 
SingleToCardinalnull290 function SingleToCardinal(const sVal : Single) : Cardinal;
291 begin
292   Result := Cardinal(sVal);
293 end;
294 {$else}
CardinalToSinglenull295 function CardinalToSingle(const cVal : Cardinal) : Single;
296 begin
297   Result := Single(Pointer(cVal));
298 end;
299 
SingleToCardinalnull300 function SingleToCardinal(const sVal : Single) : Cardinal;
301 begin
302   Result := Cardinal(Pointer(sVal));
303 end;
304 {$endif}
305 
StripTrailingZerosnull306 function StripTrailingZeros(const aNum : string) : string;
307 begin
308   Result := aNum;
309   while Result[Length(Result)] = '0' do
310     System.Delete(Result, Length(Result), 1);
311   if Result[Length(Result)] in ['.', ','] then
312     System.Delete(Result, Length(Result), 1);
313 end;
314 
315 procedure GetFileList(const Directory : string; const Pattern : string; List : TStringlist);
316 var
317   SearchRec : TSearchRec;
318   iRes : Integer;
319 begin
320   iRes := FindFirst(IncludeTrailingPathDelimiter(Directory) + Pattern, faAnyFile, SearchRec);
321   try
322     while iRes = 0 do
323     begin
324       if (SearchRec.Attr and faDirectory) <> faDirectory then
325         List.Add(SearchRec.Name);
326       iRes := FindNext(SearchRec);
327     end;
328 
329   finally
330     FindClose(SearchRec);
331   end;
332 end;
333 
334 procedure GetSubDirectories(const Directory : string; List : TStringlist);
335 var
336   SearchRec : TSearchRec;
337   iRes : Integer;
338 begin
339   iRes := FindFirst(IncludeTrailingPathDelimiter(Directory) + '*.*', faDirectory, SearchRec);
340   try
341     while iRes = 0 do
342     begin
343       if (SearchRec.Attr and faDirectory) = faDirectory then
344         if (SearchRec.Name <> '.') and (SearchRec.Name <> '..') then
345           List.Add(SearchRec.Name);
346       iRes := FindNext(SearchRec);
347     end;
348   finally
349     FindClose(SearchRec);
350   end;
351 end;
352 
353 end.
354