TlačiťTlačiť Slovenčina English Hľadať RSS

© 2005 – 2024 Roman Horváth, všetky práva vyhradené. Dnes je 2. 5. 2024.

Stránka sa načítava, prosím čakajte…

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 otvárané v novom okne
(obvykle ide o externý odkaz)) 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/​ otvárané v novom okne
(obvykle ide o externý odkaz). Tu je obraz repozitára z 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:

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.