unit main_sd; {$mode objfpc}{$H+} interface uses SysUtils, Forms, Classes, StdCtrls, ExtCtrls, uos_flat; type { TForm1 } TForm1 = class(TForm) Button1: TButton; Button2: TButton; Edit1: TEdit; Label1: TLabel; Timer1: TTimer; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure FormActivate(Sender: TObject); procedure FormClose(Sender: TObject; var CloseAction: TCloseAction); procedure Timer1Timer(Sender: TObject); private { private declarations } sound: array[0..2] of string; ms: array[0..2] of Tmemorystream; posi: integer; drum_beats: array[0..2] of string; public { public declarations } end; var Form1: TForm1; stopit: Boolean = False; allok: Boolean = False; x: integer = 0; channels: cardinal = 2; // stereo output implementation {$R *.lfm} { TForm1 } procedure TForm1.Timer1Timer(Sender: TObject); var i: integer; ge: Boolean = False; begin Timer1.Enabled := False; if stopit = False then begin for i := 0 to 2 do if (Copy(drum_beats[i], posi, 1) = 'x') then uos_PlaynofreePaused(i)// uos_InputSetDSPVolume(i,0,0.5,0.5,true); ; application.ProcessMessages; // yes or no ? // if uos_SetGlobalEvent(true) was executed --> This set events (like pause/replay threads) to global. // One event (for example uos_replay) will have impact on all players. for i := 0 to 2 do if (ge = False) and (Copy(drum_beats[i], posi, 1) = 'x') then begin uos_RePlay(i); ge := True; // A uos_replay() of each player will have impact on all players. end; Inc(posi); if (posi > 16) then posi := 1; Timer1.Enabled := True; end; end; procedure TForm1.Button1Click(Sender: TObject); begin Timer1.interval := StrToInt(edit1.Text); stopit := False; posi := 1; Timer1.Enabled := True; edit1.Enabled:=false; end; procedure TForm1.Button2Click(Sender: TObject); begin stopit := True; edit1.Enabled:=true; end; procedure TForm1.FormActivate(Sender: TObject); var ordir: string; lib1, lib2: string; i: integer; begin ordir := Application.Location; {$IFDEF Windows} {$if defined(cpu64)} lib1 := ordir + 'lib\Windows\64bit\LibPortaudio-64.dll'; lib2 := ordir + 'lib\Windows\64bit\LibSndFile-64.dll'; {$else} lib1 := ordir + 'lib\Windows\32bit\LibPortaudio-32.dll'; lib2 := ordir + 'lib\Windows\32bit\LibSndFile-32.dll'; {$endif} {$ENDIF} {$if defined(CPUAMD64) and defined(linux) } lib1 := ordir + 'lib/Linux/64bit/LibPortaudio-64.so'; lib2 := ordir + 'lib/Linux/64bit/LibSndFile-64.so'; {$ENDIF} {$if defined(cpu86) and defined(linux)} lib1 := ordir + 'lib/Linux/32bit/LibPortaudio-32.so'; lib2 := ordir + 'lib/Linux/32bit/LibSndFile-32.so'; {$ENDIF} {$if defined(linux) and defined(cpuarm)} lib1 := ordir + 'lib/Linux/arm_raspberrypi/libportaudio-arm.so'; lib2 := ordir + 'lib/Linux/arm_raspberrypi/libsndfile-arm.so'; {$ENDIF} {$if defined(linux) and defined(cpuaarch64)} lib1 := ordir + 'lib/Linux/aarch64_raspberrypi/libportaudio_aarch64.so'; lib2 := ordir + 'lib/Linux/aarch64_raspberrypi/libsndfile_aarch64.so'; {$ENDIF} {$if defined(CPUAMD64) and defined(openbsd) } lib1 := ordir + 'lib/OpenBSD/64bit/LibPortaudio-64.so'; lib2 := ordir + 'lib/OpenBSD/64bit/LibSndFile-64.so'; {$ENDIF} {$IFDEF freebsd} {$if defined(cpu64)} lib1 := ordir + 'lib/FreeBSD/64bit/libportaudio-64.so' ; lib2 := ordir + 'lib/FreeBSD/64bit/libportaudio-64.so' ; {$else} lib1 := ordir + 'lib/FreeBSD/32bit/libportaudio-32.so'; lib2 := ordir + 'lib/FreeBSD/32bit/libportaudio-32.so' ; {$endif} {$ENDIF} {$IFDEF Darwin} {$IFDEF CPU32} ordir := copy(ordir, 1, Pos('/UOS', ordir) - 1); lib1 := ordir + '/lib/Mac/32bit/LibPortaudio-32.dylib'; lib2 := ordir + '/lib/Mac/32bit/LibSndFile-32.dylib'; {$ENDIF} {$IFDEF CPU64} ordir := copy(ordir, 1, Pos('/UOS', ordir) - 1); lib1 := opath + '/lib/Mac/64bit/LibPortaudio-64.dylib'; lib2 := opath + '/lib/Mac/64bit/LibSndFile-64.dylib'; {$ENDIF} {$ENDIF} {$if defined(CPUAMD64) and defined(linux) } // For Linux amd64, check libsndfile.so if lib2 <> 'system' then if uos_TestLoadLibrary(PChar(lib2)) = false then lib2 := lib2 + '.2'; {$endif} uos_LoadLib(PChar(lib1), PChar(lib2), nil, nil, nil, nil, nil); sound[0] := Application.Location + 'sound' + directoryseparator + 'drums' + directoryseparator + 'HH.wav'; sound[1] := Application.Location + 'sound' + directoryseparator + 'drums' + directoryseparator + 'SD.wav'; sound[2] := Application.Location + 'sound' + directoryseparator + 'drums' + directoryseparator + 'BD.wav'; // { // using memorystream ms[0] := TMemoryStream.Create; ms[0].LoadFromFile(PChar(sound[0])); ms[0].Position := 0; ms[1] := TMemoryStream.Create; ms[1].LoadFromFile(PChar(sound[1])); ms[1].Position := 0; ms[2] := TMemoryStream.Create; ms[2].LoadFromFile(PChar(sound[2])); ms[2].Position := 0; // } drum_beats[0] := 'x0x0x0x0x0x0x0x0'; // hat drum_beats[1] := '0000x0000000x000'; // snare drum_beats[2] := 'x0000000x0x00000'; // kick posi := 1; for i := 0 to 2 do if uos_CreatePlayer(i) then if uos_SetGlobalEvent(i, True) then // This set events (like pause/replay thread) to global. //One event (for example replay) will have impact on all players. // using memorystream if uos_AddFromMemoryStream(i, ms[i], 0, -1, 0, 256) > -1 then // using file // if uos_AddFromfile(i,pchar(sound[i]),-1,0,256) > -1 then // if uos_InputAddDSPVolume(i,0,1,1) > -1 then if uos_AddFromEndlessMuted(i, channels, 256) > -1 then // this for a dummy endless input, must be last input {$if defined(cpuarm) or defined(cpuaarch64)} // need a lower latency if uos_AddIntoDevOut(i, -1, 0.08, -1, -1, 0, 256, -1) > -1 then // stereo output {$else} if uos_AddIntoDevOut(i, -1, 0.03, -1, -1, 0, 256, -1) > -1 then // stereo output {$endif} begin uos_PlayNoFree(i); sleep(250); allok := True; end else allok := False; // if allok = false then application.terminate; end; procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction); begin uos_free(); end; end.