source: trunk/Music.pas

Last change on this file was 669, checked in by chronos, 6 days ago
  • Modified: Made loading music libraries optional.
File size: 6.6 KB
Line 
1unit Music;
2
3interface
4
5uses
6 Classes, SysUtils, Dialogs, uos_flat, ctypes;
7
8type
9
10 { TMusicPlayer }
11
12 TMusicPlayer = class
13 private
14 FVolume: Single;
15 PlayerIndex1: Integer;
16 InputIndex1: Integer;
17 Initialized: Boolean;
18 PlayListItemIndex: Integer;
19 InputLength: Integer;
20 AutoPlayNext: Boolean;
21 LibrariesLoaded: Boolean;
22 function GetPlaying: Boolean;
23 procedure Initialize;
24 procedure EndPlay(PlayerIndex: cint32);
25 function GetNextPlaylistItem: string;
26 procedure PlayNext(Data: PtrInt);
27 procedure SetVolume(AValue: Single);
28 public
29 Playlist: TStringList;
30 constructor Create;
31 destructor Destroy; override;
32 procedure RandomizePlaylist;
33 procedure LoadPlaylistFromDir(Directory: string);
34 procedure Play;
35 procedure Stop;
36 property Playing: Boolean read GetPlaying;
37 property Volume: Single read FVolume write SetVolume;
38 end;
39
40var
41 MusicPlayer: TMusicPlayer;
42
43
44implementation
45
46uses
47 Directories, Forms;
48
49{ TMusicPlayer }
50
51procedure TMusicPlayer.Initialize;
52var
53 SndFileFileName: string;
54 PortAudioFileName: string;
55 XmpFileName: string;
56begin
57 if Initialized then Exit;
58
59 {$IFDEF UNIX}
60 SndFileFileName := 'libsndfile.so';
61 PortAudioFileName := 'libportaudio.so';
62 XmpFileName := 'libxmp.so.4';
63 {$ELSE}
64 {$if defined(cpu64)}
65 SndFileFileName := 'LibSndFile-64.dll';
66 PortAudioFileName := 'LibPortaudio-64.dll';
67 XmpFileName := 'libxmp-64.dll';
68 {$ELSE}
69 SndFileFileName := 'LibSndFile-32.dll';
70 PortAudioFileName := 'LibPortaudio-32.dll';
71 XmpFileName := 'libxmp-32.dll';
72 {$ENDIF}
73 {$ENDIF}
74
75 if (PortAudioFileName <> 'system') and (PortAudioFileName <> '') then
76 if not uos_TestLoadLibrary(PChar(PortAudioFileName)) then begin
77 if uos_TestLoadLibrary(PChar(PortAudioFileName + '.1')) then
78 PortAudioFileName := PortAudioFileName + '.1'
79 else
80 if uos_TestLoadLibrary(PChar(PortAudioFileName + '.2')) then
81 PortAudioFileName := PortAudioFileName + '.2';
82 end;
83
84 // Optionally load SndFile
85 if (SndFileFileName <> 'system') and (SndFileFileName <> '') then
86 if not uos_TestLoadLibrary(PChar(SndFileFileName)) then begin
87 if uos_TestLoadLibrary(PChar(SndFileFileName + '.1')) then
88 SndFileFileName := SndFileFileName + '.1'
89 else
90 if uos_TestLoadLibrary(PChar(SndFileFileName + '.2')) then
91 SndFileFileName := SndFileFileName + '.2'
92 else SndFileFileName := '';
93 end;
94
95 if uos_LoadLib(PChar(PortAudioFileName), PChar(SndFileFileName), nil, nil,
96 nil, nil, PChar(XmpFileName)) = 0 then begin
97 LibrariesLoaded := True;
98 end else begin
99 LibrariesLoaded := False;
100 if uosLoadResult.PAloaderror = 1 then
101 WriteLn(StdErr, 'Error: ' + PortAudioFileName + ' not found.');
102 if uosLoadResult.PAloaderror = 2 then
103 WriteLn(StdErr, 'Error: ' + PortAudioFileName + ' can''t be loaded.');
104 if uosLoadResult.SFloaderror = 1 then
105 WriteLn(StdErr, 'Error: ' + SndFileFileName + ' not found.');
106 if uosLoadResult.SFloaderror = 2 then
107 WriteLn(StdErr, 'Error: ' + SndFileFileName + ' can''t be loaded.');
108 if uosLoadResult.XMloadError = 1 then
109 WriteLn(StdErr, 'Error: ' + XmpFileName + ' not found.');
110 if uosLoadResult.XMloadError = 2 then
111 WriteLn(StdErr, 'Error: ' + XmpFileName + ' can''t be loaded.');
112 end;
113
114 Initialized := True;
115end;
116
117function TMusicPlayer.GetPlaying: Boolean;
118begin
119 Result := PlayerIndex1 >= 0;
120end;
121
122procedure TMusicPlayer.EndPlay(PlayerIndex: cint32);
123begin
124 if AutoPlayNext then begin
125 if PlayerIndex = PlayerIndex1 then Application.QueueAsyncCall(PlayNext, 0);
126 end else PlayerIndex1 := -1;
127end;
128
129function TMusicPlayer.GetNextPlaylistItem: string;
130begin
131 Inc(PlayListItemIndex);
132 if PlayListItemIndex >= Playlist.Count then PlayListItemIndex := 0;
133 Result := Playlist[PlayListItemIndex];
134end;
135
136procedure TMusicPlayer.PlayNext(Data: PtrInt);
137begin
138 Play;
139end;
140
141procedure TMusicPlayer.SetVolume(AValue: Single);
142begin
143 if FVolume = AValue then Exit;
144 FVolume := AValue;
145 if FVolume > 1 then FVolume := 1;
146 if FVolume < 0 then FVolume := 0;
147 if Playing then
148 uos_InputSetDSPVolume(PlayerIndex1, InputIndex1, Volume, Volume, True);
149end;
150
151constructor TMusicPlayer.Create;
152begin
153 Playlist := TStringList.Create;
154 PlayerIndex1 := -1;
155 FVolume := 1;
156end;
157
158destructor TMusicPlayer.Destroy;
159begin
160 uos_free();
161 FreeAndNil(Playlist);
162 inherited;
163end;
164
165procedure TMusicPlayer.RandomizePlaylist;
166var
167 I: Integer;
168 Index: Integer;
169 TempPlaylist: TStringList;
170begin
171 if Playlist.Count < 2 then Exit;
172
173 TempPlaylist := TStringList.Create;
174 try
175 TempPlaylist.Assign(Playlist);
176 PlayList.Clear;
177 for I := 0 to TempPlaylist.Count - 1 do begin
178 Index := Random(TempPlaylist.Count);
179 PlayList.Add(TempPlaylist[Index]);
180 TempPlaylist.Delete(Index);
181 end;
182 finally
183 TempPlaylist.Free;
184 end;
185end;
186
187procedure TMusicPlayer.LoadPlaylistFromDir(Directory: string);
188var
189 SearchRec: TSearchRec;
190begin
191 Playlist.Clear;
192 Directory := IncludeTrailingPathDelimiter(Directory);
193 if FindFirst(Directory + '*', faAnyFile, SearchRec) = 0 then
194 try
195 repeat
196 if (SearchRec.Name = '.') or (SearchRec.Name = '..') or ((SearchRec.Attr and faDirectory) > 0) then Continue;
197 Playlist.Add(Directory + SearchRec.Name);
198 until FindNext(SearchRec) <> 0;
199 finally
200 FindClose(SearchRec);
201 end;
202end;
203
204procedure TMusicPlayer.Play;
205var
206 OutputIndex1: Integer;
207 FileName: string;
208begin
209 Initialize;
210 if not LibrariesLoaded then Exit;
211
212 AutoPlayNext := False;
213 if PlayerIndex1 >= 0 then uos_Stop(PlayerIndex1);
214
215 Inc(PlayerIndex1);
216
217 uos_CreatePlayer(PlayerIndex1);
218 uos_EndProc(PlayerIndex1, EndPlay);
219 //uos_LoopEndProc(PlayerIndex1, LoopEndProc);
220
221 FileName := GetNextPlaylistItem;
222 InputIndex1 := uos_AddFromFile(PlayerIndex1, PChar(FileName));
223 if InputIndex1 < 0 then begin
224 MessageDlg('Music file ' + FileName + ' doesn''t exist.', mtError, [mbYes], 0);
225 Exit;
226 end;
227
228 uos_InputSetPositionEnable(PlayerIndex1, InputIndex1, 1);
229 InputLength := uos_InputLength(PlayerIndex1, InputIndex1);
230 uos_InputAddDSPVolume(PlayerIndex1, InputIndex1, Volume, Volume);
231
232 OutputIndex1 := uos_AddIntoDevOut(PlayerIndex1, -1, -1, -1, -1, -1, -1, -1);
233 if OutputIndex1 < 0 then begin
234 MessageDlg('Music output doesn''t work.', mtError, [mbYes], 0);
235 Exit;
236 end;
237
238 uos_Play(PlayerIndex1);
239 AutoPlayNext := True;
240end;
241
242procedure TMusicPlayer.Stop;
243begin
244 Initialize;
245 if not LibrariesLoaded then Exit;
246
247 AutoPlayNext := False;
248 if PlayerIndex1 >= 0 then begin
249 Initialize;
250 uos_Stop(PlayerIndex1);
251 end;
252 PlayerIndex1 := -1;
253end;
254
255initialization
256
257MusicPlayer := TMusicPlayer.Create;
258
259finalization
260
261FreeAndNil(MusicPlayer);
262
263end.
264
Note: See TracBrowser for help on using the repository browser.