📄 unit1.pas
字号:
{: 3D Sound sample (FMOD and BASS managers are used in this sample).<p>
This sample has a moving red sound source with a looping sound, and a "mickey"
listener that you can move around using the trackbars.<p>
You already know the TGLScene, TGLSceneViewer, the TTimer is just used for
regularly updating the Form's caption with FPS and CPU usage stats. You also
know the TGLCadencer, but here, it not only cadenced the scene, but is also
referred and used by the sound managers TGLSMFMOD and TGLSMBASS.<p>
A TGLSoundLibrary is used to load and store the sample, a 44kHz WAV file. The
sound library can be used to embed sound files in the application, you just
have to add a sample at design-time and this removes the need for an external
file, but for our samples, we share a single wav files among all demos.
Sound libraries are used to store sound samples, you may only play a sample
that is available in library (you can add/remove samples dynamically).<p>
We also have sound manager. There can only be one *active* sound manager in
any app at any time, it serves as an interface to a low-level sound API.
3D sounds are dynamic things, the easiest way to achieve this is to connect
the manager to the cadencer by setting its "Cadencer" property, this way,
it will get updated regularly.<p>
And now, the last part : a sound emitter behaviour has been attached to the
red sphere, in this behaviour we specify a sample (by selecting a sound
library, and a sample in the sound library). The "NbLoops" property was also
adjusted, to keep our sound looping (playing again and again).<p>
That's basicly all you need to use GLScene Sound System. Note however, that
depending on the low-level API you chose (ie. sound manager), some features
amy or may not be available, but you don't need to worry about that, if
a feature is unavailable on a particular driver, it will just be ignored.<p>
For the sake of the demo, all three samples are using different formats,
the APIs take care of the conversions: "drumloop.wav" is a 44kHz ADPCM,
"howl.mp3" a 16kHz MP3, and "chimes.wav" a 22kHz ADPCM... All three files
however are mono, because stereo sounds cannot go 3D... Remember that only
3D sounds are required to be mono, if you have some background music or ambient
soundtrack, it can be stereo (use the BASS or FMOD API directly to play it).
}
unit Unit1;
interface
uses
Classes, Forms, ExtCtrls, GLCadencer, GLScene, GLObjects, GLMisc,
GLSound, GLSMFMOD, ComCtrls, Controls, GLSMBASS, StdCtrls, GLWin32Viewer,
GLGeomObjects;
type
TForm1 = class(TForm)
GLScene: TGLScene;
GLSceneViewer: TGLSceneViewer;
GLCamera1: TGLCamera;
DummyCube: TGLDummyCube;
Sphere: TGLSphere;
GLLightSource: TGLLightSource;
GLSMFMOD: TGLSMFMOD;
GLSoundLibrary: TGLSoundLibrary;
GLCadencer1: TGLCadencer;
Timer: TTimer;
Mickey: TGLSphere;
Sphere2: TGLSphere;
Sphere3: TGLSphere;
Cone1: TGLCone;
TrackBar: TTrackBar;
Plane1: TGLPlane;
Disk1: TGLDisk;
Torus1: TGLTorus;
TrackBar1: TTrackBar;
GLSMBASS: TGLSMBASS;
Panel1: TPanel;
Label1: TLabel;
RBBass: TRadioButton;
RBFMOD: TRadioButton;
Button1: TButton;
Button2: TButton;
procedure SphereProgress(Sender: TObject; const deltaTime,
newTime: Double);
procedure TimerTimer(Sender: TObject);
procedure TrackBarChange(Sender: TObject);
procedure TrackBar1Change(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure RBFMODClick(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ D閏larations priv閑s }
public
{ D閏larations publiques }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
uses VectorGeometry, SysUtils;
procedure TForm1.FormCreate(Sender: TObject);
begin
// Load our sound sample
GLSoundLibrary.Samples.AddFile('..\..\media\drumloop.wav');
GLSoundLibrary.Samples.AddFile('..\..\media\chimes.wav');
GLSoundLibrary.Samples.AddFile('..\..\media\howl.mp3');
end;
procedure TForm1.SphereProgress(Sender: TObject; const deltaTime,
newTime: Double);
var
alpha : Single;
begin
// Move the red sphere (sound source) along an elliptic path
alpha:=60*DegToRad(newTime);
TGLSphere(Sender).Position.SetPoint(sin(alpha)*2, 0.5, cos(alpha)*5);
end;
procedure TForm1.TrackBarChange(Sender: TObject);
begin
// Rotate the listener around the vertical axis
DummyCube.TurnAngle:=TrackBar.Position;
Application.ProcessMessages;
end;
procedure TForm1.TrackBar1Change(Sender: TObject);
begin
// Move the listener forward/back
Mickey.Position.Z:=TrackBar1.Position/10;
Application.ProcessMessages;
end;
procedure TForm1.TimerTimer(Sender: TObject);
var
mngName : String;
begin
// some stats
if ActiveSoundManager is TGLSMBASS then
mngName:='BASS'
else if ActiveSoundManager is TGLSMFMOD then
mngName:='FMOD'
else mngName:='';
if ActiveSoundManager<>nil then
Caption:=Format('%.2f FPS, %s CPU use : %.2f%%',
[GLSceneViewer.FramesPerSecond, mngName,
ActiveSoundManager.CPUUsagePercent])
else Caption:='No active sound manager.';
GLSceneViewer.ResetPerformanceMonitor;
end;
procedure TForm1.RBFMODClick(Sender: TObject);
var
newManager : TGLSoundManager;
begin
// This method switches managers. On a real world project, this would never
// happen: you would choose and API and then cling to it, but the GLSS
// completely wraps the underlying complexity and makes it a snap
if RBFMOD.Checked then
newManager:=GLSMFMOD
else newManager:=GLSMBASS;
if newManager<>ActiveSoundManager then begin
// shut down current one, and activate the new one
if ActiveSoundManager<>nil then begin
ActiveSoundManager.Active:=False;
newManager.Active:=True;
// restart sound
GetOrCreateSoundEmitter(Sphere).Playing:=True;
end;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
with TGLBSoundEmitter.Create(Mickey.Behaviours) do begin
Source.SoundLibrary:=GLSoundLibrary;
Source.SoundName:='chimes.wav';
Playing:=True;
end;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
with TGLBSoundEmitter.Create(Mickey.Behaviours) do begin
Source.SoundLibrary:=GLSoundLibrary;
Source.SoundName:='howl.mp3';
Playing:=True;
end;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -