Stránka sa načítava, prosím čakajte…
© 2005 – 2024 Roman Horváth, všetky práva vyhradené. Dnes je 2. 5. 2024.
Dátum: 25. 3. 2020, pred štyrmi rokmi
Rozozvučanie reproduktorov v Lazaruse je prekvapivo netriviálne. Potrebujeme externú zvukovú knižnicu. Stránka, z ktorej som vychádzal (Audio libraries – Free Pascal wiki ) ponúka osem alternatív. Zvolil som si jednoduché filtrovacie kritérium: Ak treba na to, aby sa z reproduktorov skutočne ozval nejaký zvuk príliš veľa krokov, tak alternatívu zavrhujem. Viaceré vyzerali sľubne, ale na prvý raz sa mi podarilo prehrať zvuk len s pomocou príkladov v knižnici UOS (United OpenLib of Sound), ktorej repozitár sa nachádza na tejto adrese: https://github.com/fredvs/uos/ . Tu je obraz repozitára z 19. 3. 2020:
- uos : United OpenLib of Sound 5,26 MB (5,01 MiB), 19. 3. 2020
Niektoré príklady mi nefungovali, viaceré sú zbytočne komplikované. Jedným z najjednoduchších je SimpleDrums. Autor má dosť kostrbatý „rukopis,“ resp. „zdrojovokódopis,“ tak som sa príklad pokúsil prepísať do nového projektu:
- Simple Drums 61,44 kB (60,00 KiB), 27. 3. 2020
Výsledok je principiálne rovnaký, len je to mierne „učesané.“ Celý projekt je priamo závislý od knižnice UOS, preto musia byť obidva priečinky (uos-master
aj SimpleDrums
) rozbalené na rovnakom umiestnení.
Rád by som to zjednodušil, ale vyžadovalo by to ešte „trochu viac“ (skôr viac, než trochu) času. Skúste sa na to pozrieť aj v tomto stave, či to nebude náhodou postačovať. Dajte mi, prosím, vedieť. Ďakujem.
Výpis zdrojového kódu jednotky (na zviditeľnenie jej obsahu):
Poznámka: | Keby ste chceli projekt reprodukovať od začiatku, tak okrem toho, že priečinok uos‑master treba mať uložený tam, kde sa nachádza projekt, treba urobiť v nastaveniach projektu jednu úpravu. Treba pridať medzi cesty ku knižniciam („unitám“) cestu do pod priečinka exaples UOSu: Projekt – Voľby projektu – Cesty – Other units files (‑Fu): ..\uos‑master\examples . Inak by nebola nájdená knižnica uos_flat a všetko, čo s ňou súvisí. (Ostatné záležitosti sa dajú „naklikať“ tak, ako sme postupovali doteraz.) |
---|
simpledrumsunit.pas
unit SimpleDrumsUnit; {$mode objfpc}{$H+} interface uses Classes, SysUtils, Forms, Controls, Graphics, Dialogs, 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 FormClose(Sender: TObject; var CloseAction: TCloseAction); procedure FormCreate(Sender: TObject); procedure Timer1Timer(Sender: TObject); private sound: array[0..2] of String; ms: array[0..2] of Tmemorystream; posi: integer; drum_beats: array[0..2] of String; public end; var Form1: TForm1; stopit: 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 not stopit then begin for i := 0 to 2 do if (Copy(drum_beats[i], posi, 1) = 'x') then begin // uos_InputSetDSPVolume(i, 0, 0.5, 0.5, true); uos_PlaynofreePaused(i) end; 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 (not ge) 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 end; procedure TForm1.Button2Click(Sender: TObject); begin stopit := true end; procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction); begin uos_free() end; procedure TForm1.FormCreate(Sender: TObject); var ordir: String; lib1, lib2: String; i: integer; latency : real = 0.03; begin ordir := Application.Location; {$if defined(cpu32)} {$ifdef Windows} lib1 := ordir + '..\uos-master\examples\lib\Windows\32bit\LibPortaudio-32.dll'; lib2 := ordir + '..\uos-master\examples\lib\Windows\32bit\LibSndFile-32.dll'; {$endif} {$ifdef linux} lib1 := ordir + '../uos-master/examples/lib/Linux/32bit/LibPortaudio-32.so'; lib2 := ordir + '../uos-master/examples/lib/Linux/32bit/LibSndFile-32.so'; {$endif} {$ifdef freebsd} lib1 := ordir + '../uos-master/examples/lib/FreeBSD/32bit/libportaudio-32.so'; lib2 := ordir + '../uos-master/examples/lib/FreeBSD/32bit/libsndfile-32.so'; {$endif} {$ifdef Darwin} lib1 := ordir + '../uos-master/examples/lib/Mac/32bit/LibPortaudio-32.dylib'; lib2 := ordir + '../uos-master/examples/lib/Mac/32bit/LibSndFile-32.dylib'; {$endif} {$endif} {$if defined(cpu64)} {$ifdef Windows} lib1 := ordir + '..\uos-master\examples\lib\Windows\64bit\LibPortaudio-64.dll'; lib2 := ordir + '..\uos-master\examples\lib\Windows\64bit\LibSndFile-64.dll'; {$endif} {$ifdef linux} lib1 := ordir + '../uos-master/examples/lib/Linux/64bit/LibPortaudio-64.so'; lib2 := ordir + '../uos-master/examples/lib/Linux/64bit/LibSndFile-64.so'; {$endif} {$ifdef freebsd} lib1 := ordir + '../uos-master/examples/lib/FreeBSD/64bit/libportaudio-64.so'; lib2 := ordir + '../uos-master/examples/lib/FreeBSD/64bit/libsndfile-64.so'; {$endif} {$ifdef Darwin} lib1 := ordir + '../uos-master/examples/lib/Mac/64bit/LibPortaudio-64.dylib'; lib2 := ordir + '../uos-master/examples/lib/Mac/64bit/LibSndfile-64.dylib'; {$endif} {$endif} {$if defined(linux) and defined(cpuarm)} lib1 := ordir + '../uos-master/examples/lib/Linux/arm_raspberrypi/libportaudio-arm.so'; lib2 := ordir + '../uos-master/examples/lib/Linux/arm_raspberrypi/libsndfile-arm.so'; latency := 0.08; {$endif} uos_LoadLib(Pchar(lib1), Pchar(lib2), nil, nil, nil, nil); sound[0] := Application.Location + '..' + directoryseparator + 'uos-master' + directoryseparator + 'examples' + directoryseparator + 'sound' + directoryseparator + 'drums' + directoryseparator + 'HH.wav'; sound[1] := Application.Location + '..' + directoryseparator + 'uos-master' + directoryseparator + 'examples' + directoryseparator + 'sound' + directoryseparator + 'drums' + directoryseparator + 'SD.wav'; sound[2] := Application.Location + '..' + directoryseparator + 'uos-master' + directoryseparator + 'examples' + directoryseparator + '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 begin if uos_CreatePlayer(i) and uos_SetGlobalEvent(i, true) and // This set events (like pause/replay thread) to global. // One event (for example replay) will have impact on all players. // using memorystream (uos_AddFromMemoryStream(i, ms[i], 0, -1, 0, 256) > -1) and // using file // (uos_AddFromfile(i, pchar(sound[i]), -1, 0, 256) > -1) and // (uos_InputAddDSPVolume(i, 0, 1, 1) > -1) and (uos_AddFromEndlessMuted(i, channels, 256) > -1) then begin // this for a dummy endless input, must be last input if uos_AddIntoDevOut(i, -1, latency, -1, -1, 0, 256, -1) > -1 then // stereo output begin uos_PlayNoFree(i); sleep(250); // allok := true end // else allok := false end end; // if not allok then application.terminate end; end.