123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897 |
- MODULE CDRecordUtils;
- IMPORT
- SYSTEM, Codecs, Strings, Streams, Files, SoundDevices, KernelLog, Disks, DiskVolumes, FATVolumes, ISO9660Volumes, ATADisks,
- WMWindowManager, WMComponents, WMStandardComponents, WMFileManager, WMSystemComponents, WMGrids, WMStringGrids, WMDialogs,
- WMEvents, WMTabComponents, WMProperties, WMGraphics, WMRectangles;
- CONST
- MaxLen = 256;
- ResOk=0; ResErr=1;
- (* mpeg *)
- MPEGVer1 = 3;
- MPEGVer2 = 2;
- MPEGVer25 = 0;
- (* wave compression *)
- CUnknown* = 0H;
- CPCM* = 1H;
- CMsADPCM* = 2H;
- (* Errors *)
- ErrFileNotFound* = 100;
- ErrNoISOImage* = 101;
- White = 0FFFFFFFFH;
- Black = 0000000FFH;
- LightGray = (0C8C8C8FFH);
- DarkGray = (0A0A0A0FFH);
- TYPE
- String = Strings.String;
- Status* = OBJECT END Status;
- ConvertingStatus* = OBJECT(Status)
- VAR
- bytesEncoded*: LONGINT;
- END ConvertingStatus;
- StatusProc* = PROCEDURE {DELEGATE} (status: Status);
- WAVInfo* = OBJECT
- VAR
- compression*, size*, nofchannels*, samplerate*, encoding* : LONGINT;
- PROCEDURE Open*(filename : Strings.String): LONGINT;
- VAR
- bytesRead: LONGINT;
- file: Files.File;
- r: Files.Reader;
- buf: ARRAY 8 OF CHAR;
- BEGIN
- file := Files.Old(filename^);
- IF file = NIL THEN
- RETURN 1;
- END;
- Files.OpenReader(r, file, 0);
- (* read first chunk and check if file is a wav file *)
- buf[4] := 0X;
- r.Bytes(buf, 0, 4, bytesRead);
- IF buf # "RIFF" THEN
- RETURN ResErr;
- END;
- r.Bytes(buf, 0, 4, bytesRead);
- size := ConvertLE32Int(buf);
- (* Bluebottle's Wave Encoder only sets the header size
- IF size # file.Length() - 8 THEN
- RETURN ResErr;
- END;
- *)
- IF size < 1024 THEN size := file.Length() - 8; END;
- r.Bytes(buf, 0, 4, bytesRead);
- IF buf # "WAVE" THEN
- RETURN ResErr;
- END;
- (* format chunk *)
- r.Bytes(buf, 0, 4, bytesRead);
- IF buf # "fmt " THEN
- RETURN ResErr;
- END;
- r.Bytes(buf, 0, 4, bytesRead);
- r.Bytes(buf, 0, 2, bytesRead);
- compression := ConvertLE16Int(buf);
- r.Bytes(buf, 0, 2, bytesRead);
- nofchannels := ConvertLE16Int(buf);
- r.Bytes(buf, 0, 4, bytesRead);
- samplerate := ConvertLE32Int(buf);
- r.Bytes(buf, 0, 6, bytesRead);
- r.Bytes(buf, 0, 2, bytesRead);
- encoding := ConvertLE16Int(buf);
- RETURN ResOk;
- END Open;
- END WAVInfo;
- Frame = RECORD
- mpegver, bitrate, samplerate, padding, layer, size : LONGINT
- END;
- ID3v1* = OBJECT
- VAR
- Title*, Artist*, Album: ARRAY 31 OF CHAR;
- END ID3v1;
- MP3Info* = OBJECT
- VAR
- nofframes*, playtime* : LONGINT;
- id3v1*: ID3v1;
- bitrateTable: ARRAY 6, 16 OF LONGINT;
- PROCEDURE &New*;
- BEGIN
- InitTable(bitrateTable);
- id3v1 := NIL;
- END New;
- PROCEDURE GetNextFrame(r: Files.Reader; VAR frame: Frame): LONGINT;
- VAR
- n, start, bytesRead, tmp: LONGINT;
- chr: CHAR;
- buf : ARRAY 4 OF CHAR;
- BEGIN
- start := -1; n := 0;
- (* find first frame in first 10k by comparing sync pattern *)
- REPEAT
- r.Bytes(buf, 0, 1, bytesRead);
- IF (bytesRead = 1) & (buf[0] = 0FFX) THEN
- chr := r.Peek();
- IF ASH(ORD(chr), -5) = 7 THEN
- start := n;
- r.Bytes(buf, 1, 3, bytesRead);
- END;
- END;
- INC(n, 1);
- UNTIL (n > 10000) OR (bytesRead < 1) OR (start # -1);
- IF start = -1 THEN
- RETURN ResErr;
- END;
- (* MPEG version *)
- tmp := ASH(ORD(buf[1]), -3) MOD 4;
- CASE tmp OF
- 0: frame.mpegver := MPEGVer25; (* 2.5 *)
- | 2: frame.mpegver := MPEGVer2;
- | 3: frame.mpegver := MPEGVer1;
- ELSE RETURN ResErr;
- END;
- (* MPEG Layer *)
- tmp := ASH(ORD(buf[1]), -1) MOD 4;
- CASE tmp OF
- 1: frame.layer := 3;
- | 2: frame.layer := 2;
- | 3: frame.layer := 1;
- ELSE RETURN ResErr;
- END;
- (* Bitrate *)
- tmp := ASH(ORD(buf[2]), -4);
- IF frame.mpegver = MPEGVer1 THEN
- CASE frame.layer OF
- 1: frame.bitrate := bitrateTable[0][tmp];
- | 2: frame.bitrate := bitrateTable[1][tmp];
- | 3: frame.bitrate := bitrateTable[2][tmp];
- ELSE RETURN ResErr;
- END;
- ELSE
- CASE frame.layer OF
- 1: frame.bitrate := bitrateTable[3][tmp];
- | 2: frame.bitrate := bitrateTable[4][tmp];
- | 3: frame.bitrate := bitrateTable[5][tmp];
- ELSE RETURN ResErr;
- END;
- END;
- (* samplerate *)
- tmp := ASH(ORD(buf[2]), -2) MOD 4;
- IF frame.mpegver = MPEGVer1 THEN
- CASE tmp OF
- 0: frame.samplerate := 44100;
- | 1: frame.samplerate := 48000;
- | 2: frame.samplerate := 32000;
- ELSE RETURN ResErr;
- END;
- ELSIF frame.mpegver = MPEGVer2 THEN
- CASE tmp OF
- 0: frame.samplerate := 22050;
- | 1: frame.samplerate := 24000;
- | 2: frame.samplerate := 16000;
- ELSE RETURN ResErr;
- END;
- ELSIF frame.mpegver = MPEGVer25 THEN
- CASE tmp OF
- 0: frame.samplerate := 11025;
- | 1: frame.samplerate := 12000;
- | 2: frame.samplerate := 8000;
- ELSE RETURN ResErr;
- END;
- END;
- frame.padding := ASH(ORD(buf[2]), -1) MOD 2;
- IF frame.mpegver = MPEGVer1 THEN
- IF frame.layer = 1 THEN
- tmp := 48000;
- ELSE
- tmp := 144000;
- END;
- ELSE
- IF frame.layer = 1 THEN
- tmp := 24000
- ELSE
- tmp := 72000;
- END;
- END;
- frame.size := tmp*frame.bitrate DIV frame.samplerate + frame.padding;
- RETURN ResOk;
- END GetNextFrame;
- PROCEDURE Open*(filename: String): LONGINT;
- VAR
- file : Files.File;
- r: Files.Reader;
- frame: Frame;
- BEGIN
- nofframes := 0; playtime := 0;
- file := Files.Old(filename^);
- IF file = NIL THEN
- RETURN ResErr;
- END;
- Files.OpenReader(r, file, 0);
- WHILE GetNextFrame(r, frame) = ResOk DO
- INC(nofframes);
- r.SkipBytes(frame.size-4);
- INC(playtime, (8*frame.size) DIV frame.bitrate); (* in ms *)
- END;
- IF nofframes < 1 THEN RETURN ResErr END;
- playtime := (playtime+1000-1) DIV 1000;
- NEW(id3v1);
- IF ReadID3v1(filename, id3v1) # ResOk THEN
- id3v1 := NIL;
- END;
- RETURN ResOk;
- END Open;
- PROCEDURE InitTable(VAR table: ARRAY OF ARRAY OF LONGINT);
- BEGIN
- table[0][0] := 0; table[1][0] := 0; table[2][0] := 0; table[3][0] := 0; table[4][0] := 0; table[5][0] := 0;
- table[0][1] :=32; table[1][1] := 32; table[2][1] := 32; table[3][1] := 32; table[4][1] := 8; table[5][1] := 8;
- table[0][2] :=64; table[1][2] := 48; table[2][2] := 40; table[3][2] := 48; table[4][2] := 16; table[5][2] := 16;
- table[0][3] :=96; table[1][3] := 56; table[2][3] := 48; table[3][3] := 56; table[4][3] := 24; table[5][3] := 24;
- table[0][4] :=128; table[1][4] := 64; table[2][4] := 56; table[3][4] := 64; table[4][4] := 32; table[5][4] := 32;
- table[0][5] :=160; table[1][5] := 80; table[2][5] := 64; table[3][5] := 80; table[4][5] := 40; table[5][5] := 64;
- table[0][6] :=192; table[1][6] := 96; table[2][6] := 80; table[3][6] := 96; table[4][6] := 48 ; table[5][6] := 80;
- table[0][7] :=224; table[1][7] := 112; table[2][7] := 96; table[3][7] := 112; table[4][7] := 56; table[5][7] := 56;
- table[0][8] :=256; table[1][8] := 128; table[2][8] := 112; table[3][8] := 128; table[4][8] := 64; table[5][8] := 64;
- table[0][9] :=288; table[1][9] := 160; table[2][9] := 128; table[3][9] := 144; table[4][9] := 80; table[5][9] := 128;
- table[0][10] := 320; table[1][10] := 192; table[2][10] := 160; table[3][10] := 160; table[4][10] := 96; table[5][10] := 160;
- table[0][11] := 352; table[1][11] := 224; table[2][11] := 192; table[3][11] := 176; table[4][11] := 112; table[5][11] := 112;
- table[0][12] := 384; table[1][12] := 256; table[2][12] := 224; table[3][12] := 192; table[4][12] := 128; table[5][12] := 128;
- table[0][13] := 416; table[1][13] := 320; table[2][13] := 256; table[3][13] := 224; table[4][13] := 144; table[5][13] := 256;
- table[0][14] := 448; table[1][14] := 384; table[2][14] := 320; table[3][14] := 256; table[4][14] := 160; table[5][14] := 320;
- table[0][15] := -1; table[1][15] := -1; table[2][15] := -1; table[3][15] := -1; table[4][15] := -1; table[5][15] := -1;
- END InitTable;
- END MP3Info;
- (* Window Components *)
- StandardDialog* = OBJECT(WMDialogs.Dialog);
- VAR
- width*, height*: LONGINT;
- ok*, abort*: WMStandardComponents.Button;
- content*: WMComponents.VisualComponent;
- buttonPanel*: WMStandardComponents.Panel;
- PROCEDURE &New*(title: String; bounds: WMRectangles.Rectangle; width, height: LONGINT);
- BEGIN
- x := bounds.l + ((bounds.r - bounds.l - width) DIV 2); IF x < 0 THEN x := 0 END;
- y := bounds.t + ((bounds.b - bounds.t - height) DIV 2); IF y < 20 THEN y := 20 END;
- SELF.width := width; SELF.height := height;
- SetTitle(title);
- errors := FALSE;
- CreateDialog;
- WireDialog;
- Init(content.bounds.GetWidth(), content.bounds.GetHeight(), FALSE);
- SetContent(content);
- END New;
- PROCEDURE Show*;
- BEGIN
- result := -1;
- manager := WMWindowManager.GetDefaultManager();
- manager.Add(x, y, SELF, {WMWindowManager.FlagFrame, WMWindowManager.FlagStayOnTop});
- manager.SetFocus(SELF);
- content.Reset(NIL, NIL);
- BEGIN {EXCLUSIVE}
- AWAIT(result >= 0)
- END;
- manager.Remove(SELF)
- END Show;
- PROCEDURE ShowNonModal*;
- BEGIN
- result := -1;
- manager := WMWindowManager.GetDefaultManager();
- manager.Add(x, y, SELF, {WMWindowManager.FlagFrame, WMWindowManager.FlagStayOnTop});
- manager.SetFocus(SELF);
- END ShowNonModal;
- PROCEDURE CreateDialog*;
- VAR
- panel: WMStandardComponents.Panel;
- manager: WMWindowManager.WindowManager;
- windowStyle: WMWindowManager.WindowStyle;
- BEGIN
- manager := WMWindowManager.GetDefaultManager();
- windowStyle := manager.GetStyle();
- NEW(panel); panel.bounds.SetExtents(width, height);
- panel.fillColor.Set(windowStyle.bgColor);
- panel.takesFocus.Set(FALSE);
- NEW(buttonPanel); buttonPanel.bounds.SetHeight(30); buttonPanel.alignment.Set(WMComponents.AlignBottom);
- panel.AddContent(buttonPanel);
- NEW(abort);
- abort.bounds.SetExtents(60,30);
- abort.alignment.Set(WMComponents.AlignRight);
- abort.caption.SetAOC("Abort");
- buttonPanel.AddContent(abort);
- NEW(ok);
- ok.bounds.SetExtents(60,30);
- ok.alignment.Set(WMComponents.AlignRight);
- ok.caption.SetAOC("Ok");
- buttonPanel.AddContent(ok);
- content := panel
- END CreateDialog;
- PROCEDURE WireDialog;
- BEGIN
- ok.onClick.Add(Ok);
- abort.onClick.Add(Abort);
- END WireDialog;
- END StandardDialog;
- FileDialog* = OBJECT(StandardDialog);
- VAR
- path*: WMProperties.StringProperty;
- explorer: ExplorerPanel;
- PROCEDURE CreateDialog*;
- VAR
- bearing: WMRectangles.Rectangle;
- BEGIN
- CreateDialog^;
- NEW(path, NIL, NIL, NIL);
- path.Set(Strings.NewString(""));
- bearing := WMRectangles.MakeRect(3, 3, 3, 3);
- NEW(explorer);
- explorer.alignment.Set(WMComponents.AlignClient);
- content.AddContent(explorer);
- END CreateDialog;
- PROCEDURE Ok(sender, data: ANY);
- VAR
- dirEntries: WMSystemComponents.DirEntries;
- str: ARRAY MaxLen OF CHAR;
- BEGIN
- dirEntries := explorer.list.list.GetSelection();
- IF (LEN(dirEntries) > 0) & (dirEntries[0] # NIL) &(dirEntries[0].name # NIL) & (dirEntries[0].path # NIL) THEN
- COPY(dirEntries[0].path^, str);
- Strings.Append(str, "/");
- Strings.Append(str, dirEntries[0].name^);
- path.Set(Strings.NewString(str));
- END;
- Ok^(sender, data);
- END Ok;
- END FileDialog;
- PropertyPage* = OBJECT(WMComponents.VisualComponent);
- VAR
- tab: WMTabComponents.Tab;
- owner*: PropertySheet;
- PROCEDURE UpdateData*(save: BOOLEAN);
- END UpdateData;
- END PropertyPage;
- PropertySheet* = OBJECT(StandardDialog);
- VAR
- tabs: WMTabComponents.Tabs;
- curPage: PropertyPage;
- PROCEDURE CreateDialog*;
- VAR
- topPanel: WMStandardComponents.Panel;
- BEGIN
- CreateDialog^;
- NEW(topPanel);
- topPanel.bounds.SetHeight(20); topPanel.alignment.Set(WMComponents.AlignTop); topPanel.fillColor.Set(LightGray);
- content.AddContent(topPanel);
- NEW(tabs);
- tabs.alignment.Set(WMComponents.AlignTop); tabs.bounds.SetExtents(width,20);
- tabs.onSelectTab.Add(TabSelected);
- topPanel.AddContent(tabs);
- END CreateDialog;
- PROCEDURE TabSelected(sender, data: ANY);
- VAR
- tab: WMTabComponents.Tab;
- BEGIN
- IF (data # NIL) THEN
- tab := data(WMTabComponents.Tab);
- IF tab.data # NIL THEN
- IF curPage # NIL THEN
- content.RemoveContent(curPage);
- END;
- curPage := tab.data(PropertyPage);
- content.AddContent(curPage);
- curPage.Reset(NIL, NIL);
- curPage.Invalidate();
- curPage.Resized;
- END;
- END;
- END TabSelected;
- PROCEDURE AddPage*(page: PropertyPage; name: String);
- VAR
- tab: WMTabComponents.Tab;
- BEGIN
- page.owner := SELF;
- tab := tabs.NewTab();
- tabs.SetTabCaption(tab, name);
- tabs.SetTabData(tab, page);
- page.tab := tab;
- tabs.AddTab(tab);
- END AddPage;
- PROCEDURE SelectPage*(page: PropertyPage);
- BEGIN
- tabs.Select(page.tab);
- curPage := page;
- IF curPage # NIL THEN
- content.RemoveContent(page);
- END;
- content.AddContent(page);
- END SelectPage;
- END PropertySheet;
- ProgressBar* = OBJECT(WMComponents.VisualComponent)
- VAR
- start*, end*, cur*: WMProperties.Int32Property;
- color*: WMProperties.ColorProperty;
- borderColor*: WMProperties.ColorProperty;
- PROCEDURE &Init*;
- VAR
- BEGIN
- Init^();
- NEW(color, NIL, NIL, NIL);
- NEW(borderColor, NIL, NIL, NIL);
- NEW(start, NIL, NIL, NIL);
- NEW(end, NIL, NIL, NIL);
- NEW(cur, NIL, NIL, NIL);
- END Init;
- PROCEDURE SetPos*(pos: Streams.Position);
- BEGIN
- IF pos < start.Get() THEN
- pos := start.Get();
- ELSIF pos > end.Get() THEN
- pos := end.Get();
- END;
- cur.Set(pos);
- Invalidate();
- END SetPos;
- PROCEDURE GetPos*(): Streams.Position;
- BEGIN
- RETURN cur.Get();
- END GetPos;
- PROCEDURE SetRange*(start, end: LONGINT);
- BEGIN
- SELF.start.Set(start);
- SELF.end.Set(end);
- cur.Set(start);
- END SetRange;
- PROCEDURE StepIt*;
- BEGIN
- IF cur.Get() < end.Get() THEN
- cur.Set(cur.Get() + 1);
- Invalidate;
- END;
- END StepIt;
- PROCEDURE DrawBackground*(canvas: WMGraphics.Canvas);
- VAR
- rect: WMRectangles.Rectangle;
- width: LONGINT;
- pt: ARRAY 4 OF WMGraphics.Point2d;
- BEGIN
- IF end.Get() > start.Get() THEN
- width := (cur.Get()-start.Get()) * bounds.GetWidth() DIV (end.Get()-start.Get());
- END;
- rect := WMRectangles.MakeRect(0, 0, width, bounds.GetHeight());
- canvas.Fill(rect, color.Get(), WMGraphics.ModeCopy);
- rect := GetClientRect();
- rect.l := width;
- canvas.Fill(rect, fillColor.Get(), WMGraphics.ModeCopy);
- pt[0].x := 0; pt[0].y := 0;
- pt[1].x := bounds.GetWidth()-1; pt[1].y := 0;
- pt[2].x := bounds.GetWidth()-1; pt[2].y := bounds.GetHeight()-1;
- pt[3].x := 0; pt[3].y := bounds.GetHeight()-1;
- canvas.PolyLine(pt, 4, TRUE, borderColor.Get(), WMGraphics.ModeCopy);
- END DrawBackground;
- END ProgressBar;
- ListBox* = OBJECT(WMComponents.VisualComponent);
- VAR
- grid: WMStringGrids.StringGrid;
- nofRows: LONGINT;
- caption*: WMProperties.StringProperty;
- label: WMStandardComponents.Label;
- selected*: WMProperties.Int32Property;
- onSelectionChanged* : WMEvents.EventSource;
- PROCEDURE &Init*;
- VAR
- leftPanel, rightPanel: WMStandardComponents.Panel;
- BEGIN
- Init^();
- NEW(caption, NIL, NIL, NIL); properties.Add(caption);
- NEW(selected, NIL, NIL, NIL); properties.Add(selected);
- NEW(onSelectionChanged, SELF, NIL, NIL, NIL);
- NEW(leftPanel); leftPanel.bounds.SetWidth(80); leftPanel.alignment.Set(WMComponents.AlignLeft);
- AddContent(leftPanel);
- NEW(label); label.bounds.SetHeight(14); label.alignment.Set(WMComponents.AlignTop); label.textColor.Set(Black);
- leftPanel.AddContent(label);
- NEW(rightPanel); rightPanel.alignment.Set(WMComponents.AlignClient);
- AddContent(rightPanel);
- NEW(grid);
- grid.alignment.Set(WMComponents.AlignClient);
- rightPanel.AddContent(grid);
- grid.onSelect.Add(SelectionHandler);
- grid.model.Acquire;
- grid.model.SetNofCols(1);
- grid.SetSelectionMode(WMGrids.GridSelectSingleRow);
- grid.model.Release;
- END Init;
- PROCEDURE Update*;
- BEGIN
- Reset(NIL, NIL);
- Invalidate();
- Resized;
- END Update;
- PROCEDURE Clear*;
- BEGIN
- nofRows := 0;
- grid.model.Acquire;
- grid.model.SetNofRows(nofRows);
- grid.model.Release;
- END Clear;
- PROCEDURE SelectionHandler*(sender, data: ANY);
- VAR
- scol, srow, ecol, erow: LONGINT;
- BEGIN
- grid. GetSelection(scol, srow, ecol, erow );
- selected.Set(srow);
- END SelectionHandler;
- PROCEDURE RecacheProperties;
- BEGIN
- label.caption.Set(caption.Get());
- grid.SetSelection(0, selected.Get(), 0, selected.Get());
- onSelectionChanged.Call(selected);
- RecacheProperties^;
- END RecacheProperties;
- PROCEDURE PropertyChanged(sender, property: ANY);
- BEGIN
- IF property = caption THEN
- label.caption.Set(caption.Get());
- ELSIF property = selected THEN
- grid.SetSelection(0, selected.Get(), 0, selected.Get());
- onSelectionChanged.Call(selected);
- ELSE
- PropertyChanged^(sender, property);
- END;
- END PropertyChanged;
- PROCEDURE Add*(name: String; data: ANY);
- BEGIN
- grid.model.Acquire;
- INC(nofRows);
- grid.model.SetNofRows(nofRows);
- grid.model.SetCellText(0, nofRows-1, name);
- grid.model.SetCellData(0, nofRows-1, data);
- grid.model.Release;
- END Add;
- END ListBox;
- ExplorerPanel* = OBJECT(WMComponents.VisualComponent);
- VAR
- tree*: WMSystemComponents.DirectoryTree;
- list: WMFileManager.FileListPanel;
- PROCEDURE &Init*;
- VAR
- panel, sidePanel: WMStandardComponents.Panel;
- resizer: WMStandardComponents.Resizer;
- BEGIN
- Init^();
- NEW(panel);
- panel.alignment.Set(WMComponents.AlignClient);
- panel.fillColor.Set(White);
- AddContent(panel);
- NEW(sidePanel);
- sidePanel.alignment.Set(WMComponents.AlignLeft);
- sidePanel.bounds.SetWidth(200);
- NEW(resizer);
- resizer.alignment.Set(WMComponents.AlignRight);
- resizer.bounds.SetWidth(4);
- sidePanel.AddContent(resizer);
- NEW(tree);
- tree.alignment.Set(WMComponents.AlignClient);
- sidePanel.AddContent(tree);
- panel.AddContent(sidePanel);
- tree.onPathChanged.Add(PathChanged);
- NEW(list);
- list.alignment.Set(WMComponents.AlignClient);
- panel.AddContent(list);
- END Init;
- PROCEDURE PathChanged(sender, data: ANY);
- BEGIN
- list.pathProp.Set(tree.currentPath.Get());
- END PathChanged;
- END ExplorerPanel;
- PROCEDURE ReadID3v1(VAR filename: String; VAR id3v1: ID3v1): LONGINT;
- VAR
- file: Files.File;
- r: Files.Reader;
- id, buf: ARRAY 128 OF CHAR;
- len, bytesRead: LONGINT;
- BEGIN
- file := Files.Old(filename^);
- IF file = NIL THEN
- RETURN ResErr;
- END;
- Files.OpenReader(r, file, 0);
- len := file.Length();
- r.SkipBytes(len-128);
- r.Bytes(buf, 0, 128, bytesRead);
- Strings.Copy(buf, 0, 3, id);
- IF id # "TAG" THEN RETURN ResErr; END;
- Strings.Copy(buf, 3, 30, id3v1.Title);
- Strings.Copy(buf, 33, 30, id3v1.Artist);
- Strings.Copy(buf, 63, 30, id3v1.Album);
- RETURN ResOk;
- END ReadID3v1;
- PROCEDURE ConvertLE16Int*(CONST buf : ARRAY OF CHAR): LONGINT;
- BEGIN
- RETURN ASH(ORD(buf[1]), 8) + ORD(buf[0]);
- END ConvertLE16Int;
- PROCEDURE ConvertLE32Int*(CONST buf : ARRAY OF CHAR): LONGINT;
- BEGIN
- RETURN ASH(ORD(buf[3]), 24) + ASH(ORD(buf[2]), 16) + ASH(ORD(buf[1]), 8) + ORD(buf[0]);
- END ConvertLE32Int;
- PROCEDURE ConvertBE16Int*(CONST buf : ARRAY OF CHAR): LONGINT;
- BEGIN
- RETURN ASH(ORD(buf[0]), 8) + ORD(buf[1]);
- END ConvertBE16Int;
- PROCEDURE ConvertBE32Int*(CONST buf : ARRAY OF CHAR): LONGINT;
- BEGIN
- RETURN ASH(ORD(buf[0]), 24) + ASH(ORD(buf[1]), 16) + ASH(ORD(buf[2]), 8) + ORD(buf[3]);
- END ConvertBE32Int;
- PROCEDURE SetLE16*(x: INTEGER; VAR dst : ARRAY OF CHAR);
- BEGIN
- dst[0] := CHR(x MOD 100H);
- dst[1] := CHR(x DIV 100H MOD 100H);
- END SetLE16;
- PROCEDURE SetLE32*(x: LONGINT; VAR dst: ARRAY OF CHAR);
- BEGIN
- dst[0] := CHR(x MOD 100H);
- dst[1] := CHR(x DIV 100H MOD 100H);
- dst[2] := CHR(x DIV 10000H MOD 100H);
- dst[3] := CHR(x DIV 1000000H MOD 100H);
- END SetLE32;
- PROCEDURE SetBE16*(x: INTEGER; VAR dst : ARRAY OF CHAR);
- BEGIN
- dst[1] := CHR(x MOD 100H);
- dst[0] := CHR(x DIV 100H MOD 100H);
- END SetBE16;
- PROCEDURE SetBE32*(x: LONGINT; VAR dst: ARRAY OF CHAR);
- BEGIN
- dst[3] := CHR(x MOD 100H);
- dst[2] := CHR(x DIV 100H MOD 100H);
- dst[1] := CHR(x DIV 10000H MOD 100H);
- dst[0] := CHR(x DIV 1000000H MOD 100H);
- END SetBE32;
- PROCEDURE Mp3ToWave*(srcFileName, destFileName : Strings.String; onConvertStatusChanged: StatusProc) : LONGINT;
- VAR
- res: WORD;
- srcFile, destFile : Files.File;
- decoder: Codecs.AudioDecoder;
- encoder: Codecs.AudioEncoder;
- in : Streams.Reader;
- out : Files.Writer;
- buffer : SoundDevices.Buffer;
- convertStatus: ConvertingStatus;
- bytesEncoded: LONGINT;
- BEGIN
- NEW(convertStatus);
- decoder := Codecs.GetAudioDecoder("MP3");
- IF decoder = NIL THEN
- KernelLog.String("Could not open MP3DEcoder");
- RETURN ResErr;
- END;
- encoder := Codecs.GetAudioEncoder("WAV");
- IF encoder = NIL THEN
- KernelLog.String("Could not open WAV Encoder");
- RETURN ResErr;
- END;
- srcFile := Files.Old(srcFileName^);
- destFile := Files.New(destFileName^);
- IF destFile = NIL THEN
- RETURN ResErr;
- END;
- Files.Register(destFile);
- Files.OpenWriter(out, destFile, 0);
- in := Codecs.OpenInputStream(srcFileName^);
- IF (in = NIL) OR (out = NIL) THEN
- RETURN ResErr;
- END;
- decoder.Open(in, res);
- decoder.SetStreamLength(srcFile.Length());
- NEW(buffer);
- buffer.len := 4096;
- NEW(buffer.data, 4096);
- encoder.Open(out, 44100, 16, 2, res);
- WHILE decoder.HasMoreData() & (res = ResOk) DO
- decoder.FillBuffer(buffer);
- encoder.Write(buffer, res);
- INC(bytesEncoded, buffer.len);
- IF onConvertStatusChanged # NIL THEN
- convertStatus.bytesEncoded := bytesEncoded;
- onConvertStatusChanged(convertStatus);
- END;
- END;
- encoder.Close(res);
- RETURN res;
- END Mp3ToWave;
- PROCEDURE GetFreeSpace*(CONST destination: ARRAY OF CHAR; VAR freeSpace: LONGINT): LONGINT;
- VAR
- fs: Files.FileSystem;
- prefix, name: ARRAY MaxLen OF CHAR;
- res: WORD;
- BEGIN
- res := ResErr;
- Files.SplitName(destination, prefix, name);
- fs := Files.This(prefix);
- IF fs # NIL THEN
- freeSpace := (fs.vol.Available() DIV 1024) * fs.vol.blockSize;
- res := ResOk;
- END;
- RETURN res;
- END GetFreeSpace;
- PROCEDURE IsReadOnly*(CONST destination: ARRAY OF CHAR; VAR readOnly: BOOLEAN): LONGINT;
- VAR
- fs: Files.FileSystem;
- prefix, name: ARRAY MaxLen OF CHAR;
- res: WORD;
- BEGIN
- res := ResErr;
- Files.SplitName(destination, prefix, name);
- fs := Files.This(prefix);
- IF (fs # NIL) & (fs.vol # NIL) THEN
- readOnly := Files.ReadOnly IN fs.vol.flags;
- res := ResOk;
- END;
- RETURN res;
- END IsReadOnly;
- PROCEDURE GetDevice*(file: Files.File; VAR device: Disks.Device): LONGINT;
- VAR
- fs: Files.FileSystem;
- res: WORD;
- BEGIN
- res := ResErr;
- fs := file.fs;
- IF (fs # NIL) & (fs.vol # NIL) THEN
- IF fs.vol IS DiskVolumes.Volume THEN
- device := fs.vol(DiskVolumes.Volume).dev;
- res := ResOk;
- ELSIF fs.vol IS FATVolumes.Volume THEN
- device := fs.vol(FATVolumes.Volume).dev;
- res := ResOk;
- ELSIF fs.vol IS ISO9660Volumes.Volume THEN
- device := fs.vol(FATVolumes.Volume).dev;
- res := ResOk;
- END;
- END;
- RETURN res;
- END GetDevice;
- PROCEDURE IsOnSameController*(device1, device2: Disks.Device): BOOLEAN;
- BEGIN
- IF (device1 IS ATADisks.Device) & (device2 IS ATADisks.Device) THEN
- RETURN device1(ATADisks.Device).controller = device2(ATADisks.Device).controller;
- END;
- RETURN FALSE;
- END IsOnSameController;
- PROCEDURE ClearBuffer*(VAR buf: ARRAY OF CHAR; ofs, len: LONGINT);
- VAR
- adr: ADDRESS;
- rem: SIZE;
- BEGIN
- ASSERT((ofs+len) <= LEN(buf));
- adr := ADDRESSOF(buf);
- INC(adr, ofs);
- rem := adr MOD 4;
- WHILE rem > 0 DO
- SYSTEM.PUT8(adr, 0X);
- DEC(rem); INC(adr); DEC(len);
- END;
- WHILE len >= 4 DO
- SYSTEM.PUT32(adr, 0H);
- INC(adr, 4); DEC(len, 4);
- END;
- WHILE len > 0 DO
- SYSTEM.PUT8(adr, 0X);
- INC(adr); DEC(len);
- END;
- END ClearBuffer;
- END CDRecordUtils.
|