| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316 |
- {========================================================================}
- {= (c) 1995-98 SwiftSoft Ronald Dittrich =}
- {========================================================================}
- {= All Rights Reserved =}
- {========================================================================}
- {= D 01099 Dresden = Fax.: +49(0)351-8037944 =}
- {= Loewenstr.7a = info@swiftsoft.de =}
- {========================================================================}
- {= Actual versions on http://www.swiftsoft.de/index.html =}
- {========================================================================}
- {= This code is for reference purposes only and may not be copied or =}
- {= distributed in any format electronic or otherwise except one copy =}
- {= for backup purposes. =}
- {= =}
- {= No Delphi Component Kit or Component individually or in a collection=}
- {= subclassed or otherwise from the code in this unit, or associated =}
- {= .pas, .dfm, .dcu, .asm or .obj files may be sold or distributed =}
- {= without express permission from SwiftSoft. =}
- {= =}
- {= For more licence informations please refer to the associated =}
- {= HelpFile. =}
- {========================================================================}
- {= $Date: 17.09.98 - 16:28:36 $ =}
- {========================================================================}
- unit Unit1;
- interface
- uses
- Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
- MMUtils, MMHTimer, StdCtrls, MMObj, MMCstDlg, MMDIBCv, MMLevel, MMConect,
- MMDesign, MMRingBf, MMDSPObj, MMWavOut, MMWave, MMWMixer, ExtCtrls,
- MMHook, MMAudio;
- type
- PListItem = ^TListItem;
- TListItem = record
- FileName: string;
- Position: Longint;
- Length : Longint;
- end;
- TMainForm = class(TForm)
- WaveMixer: TMMWaveMixer;
- WaveOut: TMMWaveOut;
- RingBuffer: TMMRingBuffer;
- MMDesigner1: TMMDesigner;
- MMConnector1: TMMConnector;
- Level1: TMMLevel;
- Level2: TMMLevel;
- btnStart: TButton;
- btnStop: TButton;
- btnFile: TButton;
- Label1: TLabel;
- lblPosition: TLabel;
- Timer: TMMHiTimer;
- PlayListBox: TListBox;
- Header: THeader;
- AudioFile1: TMMAudioFile;
- AudioFile2: TMMAudioFile;
- TempFile: TMMAudioFile;
- OpenDialog: TOpenDialog;
- procedure TimerTimer(Sender: TObject);
- procedure btnStartClick(Sender: TObject);
- procedure btnStopClick(Sender: TObject);
- procedure WaveOutStart(Sender: TObject);
- procedure WaveOutStop(Sender: TObject);
- procedure FormCreate(Sender: TObject);
- procedure FormDestroy(Sender: TObject);
- procedure btnFileClick(Sender: TObject);
- procedure WaveMixerClosePort(Sender: TObject; index: Integer);
- procedure HeaderSized(Sender: TObject; ASection, AWidth: Integer);
- procedure PlayListBoxDrawItem(Control: TWinControl;
- Index: Integer; Rect: TRect;
- State: TOwnerDrawState);
- procedure FormClose(Sender: TObject; var Action: TCloseAction);
- public
- PlayList: TList;
- PlayIndex: integer;
- CurrentFile: integer;
- LastEndTime: int64;
- end;
- var
- MainForm: TMainForm;
- implementation
- {$R *.DFM}
- // NOTE: Maximal playbacktime of TMMWaveOut is ~3.5 hours, then it will stop.
- // The Windows MMSystem works with 32 bit positions and they will overflow
- // if the 32 bit value is wrapped so we stop the device. It's always a good
- // idea to close and restart the device every 2-3 hours.
- // This limitation is removed in the Delphi 4 version !
- {-- TMainForm -----------------------------------------------------------------}
- procedure TMainForm.FormCreate(Sender: TObject);
- begin
- PlayList := TList.Create;
- end;
- {-- TMainForm -----------------------------------------------------------------}
- procedure TMainForm.FormDestroy(Sender: TObject);
- var
- i: integer;
- begin
- for i := PlayList.Count-1 downto 0 do
- begin
- Dispose(PlayList[i]);
- PlayList.Delete(i);
- end;
- PlayList.Free;
- end;
- {-- TMainForm -----------------------------------------------------------------}
- procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction);
- begin
- WaveOut.Close;
- end;
- {-- TMainForm -----------------------------------------------------------------}
- procedure TMainForm.TimerTimer(Sender: TObject);
- begin
- lblPosition.Caption := TimeToString64(WaveOut.Position,WaveOut.PositionHigh,True);
- { update the ListBox }
- if PlayListBox.ItemIndex <> CurrentFile then PlayListBox.ItemIndex := CurrentFile;
- end;
- {-- TMainForm -----------------------------------------------------------------}
- procedure TMainForm.btnStartClick(Sender: TObject);
- begin
- PlayIndex := 0;
- if PlayIndex < PlayList.Count then
- begin
- // You can also set the maxPlayTime here if you know how much is to play
- { WaveMixer.MaxPlayTime := PListItem(PlayList[PlayList.Count-1]).Position+
- PListItem(PlayList[PlayList.Count-1]).Length;}
- AudioFile1.FileName := PListItem(PlayList[PlayIndex]).FileName;
- WaveMixer.StartPos1 := PListItem(PlayList[PlayIndex]).Position;
- { remember the end position for this file }
- LastEndTime := WaveMixer.StartPos1 + AudioFile1.FileLength;
- inc(PlayIndex);
- end;
- if PlayIndex < PlayList.Count then
- begin
- AudioFile2.FileName := PListItem(PlayList[PlayIndex]).FileName;
- WaveMixer.StartPos2 := PListItem(PlayList[PlayIndex]).Position;
- { remember the end position for this file }
- LastEndTime := WaveMixer.StartPos2 + AudioFile2.FileLength;
- inc(PlayIndex);
- end;
- if PlayIndex > 0 then PlayListBox.ItemIndex := 0;
- CurrentFile := 0;
- WaveOut.Start;
- end;
- {-- TMainForm -----------------------------------------------------------------}
- procedure TMainForm.btnStopClick(Sender: TObject);
- begin
- WaveOut.Close;
- end;
- {-- TMainForm -----------------------------------------------------------------}
- procedure TMainForm.WaveOutStart(Sender: TObject);
- begin
- Timer.Enabled := True;
- btnFile.Enabled := False;
- btnStart.Enabled := False;
- end;
- {-- TMainForm -----------------------------------------------------------------}
- procedure TMainForm.WaveOutStop(Sender: TObject);
- begin
- Timer.Enabled := False;
- btnFile.Enabled := True;
- btnStart.Enabled := True;
- end;
- {-- TMainForm -----------------------------------------------------------------}
- procedure TMainForm.WaveMixerClosePort(Sender: TObject; index: Integer);
- begin
- { the WaveMixer has closed a port, the files was done... }
- { other files to play ??? }
- if PlayIndex < PlayList.Count then
- begin
- if index = 0 then
- begin
- { set the next file and Position }
- AudioFile1.FileName := PListItem(PlayList[PlayIndex]).FileName;
- WaveMixer.StartPos1 := PListItem(PlayList[PlayIndex]).Position;
- { remember the total endposition for this file }
- LastEndTime := WaveMixer.StartPos1 + AudioFile1.FileLength;
- end
- else if index = 1 then
- begin
- { set the next file and Position }
- AudioFile2.FileName := PListItem(PlayList[PlayIndex]).FileName;
- WaveMixer.StartPos2 := PListItem(PlayList[PlayIndex]).Position;
- { remember the total endposition for this file }
- LastEndTime := WaveMixer.StartPos2 + AudioFile2.FileLength;
- end;
- { Notify the WaveMixer that the Input has changed }
- WaveMixer.InputDone[index] := False;
- inc(PlayIndex);
- end
- else
- { no other file to play, set MaxPlayTime }
- { so WaveOut stops if the last file is done }
- WaveMixer.MaxPlayTime := LastEndTime;
- CurrentFile := CurrentFile+1;
- end;
- {-- TMainForm -----------------------------------------------------------------}
- procedure TMainForm.btnFileClick(Sender: TObject);
- const
- CrossFadeTime = 2500; {ms}
- var
- NewItem: PListItem;
- Pos,Len: Longint;
- i: integer;
- begin
- { setup a simple playlist so we can demonstrate how to handle it }
- if OpenDialog.Execute then
- begin
- for i := 0 to OpenDialog.Files.Count-1 do
- begin
- TempFile.FileName := OpenDialog.Files[i];
- Len := TempFile.FileLength;
- if (PlayList.Count > 0) then
- with PListItem(PlayList[PlayList.Count-1])^ do
- Pos := Max(Position+Length-CrossFadeTime,0)
- else
- Pos := 0;
- New(NewItem);
- with NewItem^ do
- begin
- FileName := TempFile.FileName;
- Length := Len;
- Position := Pos;
- end;
- PlayList.Add(NewItem);
- PlayListBox.Items.Add(NewItem.FileName+'|'+TimeToString(Pos)+'|'+TimeToString(Len));
- end;
- end;
- end;
- {-- TMainForm -----------------------------------------------------------------}
- procedure TMainForm.PlayListBoxDrawItem(Control: TWinControl;
- Index: Integer; Rect: TRect;
- State: TOwnerDrawState);
- var
- P: Integer;
- R: TRect;
- C: array[0..255] of Char;
- S,S2: string;
- begin
- R := Rect;
- { find the separator in the string }
- P := Pos('|', PlayListBox.Items[Index]);
- { draw the name }
- S := Copy(PlayListBox.Items[Index], 1, P - 1);
- R.Right := R.Left + (Header.SectionWidth[0]);
- ExtTextOut(PlayListBox.Canvas.Handle, R.Left, R.Top, ETO_CLIPPED or
- ETO_OPAQUE, @R, StrPCopy(C, S), Length(S), nil);
- S2 := Copy(PlayListBox.Items[Index], P+1, Length(PlayListBox.Items[Index])-P);
- P := Pos('|', S2);
- S := Copy(S2, 1, P - 1);
- { move the rectangle to the next column }
- R.Left := R.Left + (Header.SectionWidth[0]);
- R.Right:= R.Left + Header.SectionWidth[1];
- ExtTextOut(PlayListBox.Canvas.Handle, R.Left, R.Top, ETO_CLIPPED or
- ETO_OPAQUE, @R, StrPCopy(C, S), Length(S), nil);
- S := Copy(S2, P+1, Length(S2)-P);
- { move the rectangle to the next column }
- R.Left := R.Left + Header.SectionWidth[1];
- R.Right:= R.Left + Header.SectionWidth[2];
- ExtTextOut(PlayListBox.Canvas.Handle, R.Left, R.Top, ETO_CLIPPED or
- ETO_OPAQUE, @R, StrPCopy(C, S), Length(S), nil);
- end;
- {-- TMainForm -----------------------------------------------------------------}
- procedure TMainForm.HeaderSized(Sender: TObject; ASection, AWidth: Integer);
- begin
- PlayListBox.Invalidate;
- end;
- end.
|