Delphi Fmx Samples -
To create apps that feel native and modern, study these specific areas:
unit AudioSpectrumAnalyzer;interface
uses System.Classes, System.SysUtils, System.Threading, FMX.Forms, FMX.Types, FMX.Controls, FMX.Layouts, FMX.Memo, FMX.Objects, FMX.Media, FMX.Types3D, FMX.Controls3D, FMX.Viewport3D, FMX.Objects3D, System.Math, System.Generics.Collections;
type TAudioSpectrumAnalyzer = class(TForm) Viewport3D: TViewport3D; Camera: TCamera; Light: TLight; TimerUpdate: TTimer; MediaPlayer: TMediaPlayer; ButtonPlay: TButton; ButtonPause: TButton; ButtonOpen: TButton; OpenDialog: TOpenDialog;
procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure TimerUpdateTimer(Sender: TObject); procedure ButtonPlayClick(Sender: TObject); procedure ButtonPauseClick(Sender: TObject); procedure ButtonOpenClick(Sender: TObject);private FBars: TObjectList<TCube>; FFFTBuffer: TArray<Double>; FCanvasBuffer: TArray<Double>; FThread: TTask; FIsAnalyzing: Boolean;
procedure CreateSpectrumBars; procedure UpdateSpectrumBars; procedure AnalyzeAudioBuffer; procedure PerformFFT(const Buffer: TArray<Double>); function ApplyWindowFunction(const Buffer: TArray<Double>; WindowType: Integer): TArray<Double>;public property IsAnalyzing: Boolean read FIsAnalyzing write FIsAnalyzing; end;
var AudioSpectrumAnalyzer: TAudioSpectrumAnalyzer;
implementation
$R *.fmx
procedure TAudioSpectrumAnalyzer.FormCreate(Sender: TObject); begin Caption := '3D Audio Spectrum Analyzer - Delphi FMX Demo'; Width := 1024; Height := 768; delphi fmx samples
// Initialize 3D viewport Viewport3D.Align := TAlignLayout.Client; Viewport3D.Color := TAlphaColors.Black;
// Setup camera position for better view Camera.Position.Point := TPoint3D.Create(0, 5, 20); Camera.Target := TPoint3D.Create(0, 0, 0);
// Create spectrum visualization bars CreateSpectrumBars;
// Initialize FFT buffer SetLength(FFFTBuffer, 2048); SetLength(FCanvasBuffer, 1024);
FIsAnalyzing := False;
// Timer for smooth 60 FPS updates TimerUpdate.Interval := 16; // ~60 FPS TimerUpdate.Enabled := True; end;
procedure TAudioSpectrumAnalyzer.CreateSpectrumBars; var i: Integer; Bar: TCube; XPos: Single; begin FBars := TObjectList<TCube>.Create(True);
for i := 0 to 63 do // 64 bars for spectrum visualization begin Bar := TCube.Create(Viewport3D); Bar.Parent := Viewport3D;
// Create a gradient material for each bar Bar.MaterialSource := TMaterialSource.Create(Bar); // Position bars in a semi-circle XPos := (i - 32) * 0.15; Bar.Position.Point := TPoint3D.Create(XPos, -2, 0); Bar.Width := 0.12; Bar.Height := 0.1; Bar.Depth := 0.1; // Initial scale (height will be animated) Bar.Scale.Point := TPoint3D.Create(1, 0.1, 1); FBars.Add(Bar);end; end;
procedure TAudioSpectrumAnalyzer.ButtonOpenClick(Sender: TObject); begin if OpenDialog.Execute then begin MediaPlayer.FileName := OpenDialog.FileName; ButtonPlay.Enabled := True; end; end;
procedure TAudioSpectrumAnalyzer.ButtonPlayClick(Sender: TObject); begin MediaPlayer.Play; FIsAnalyzing := True;
// Start audio analysis in background thread FThread := TTask.Run(procedure begin while FIsAnalyzing do begin AnalyzeAudioBuffer; TThread.Queue(nil, UpdateSpectrumBars); TThread.Sleep(30); // Update every 30ms end; end); end;
procedure TAudioSpectrumAnalyzer.ButtonPauseClick(Sender: TObject); begin FIsAnalyzing := False; if Assigned(FThread) then FThread.Wait; MediaPlayer.Stop; end;
procedure TAudioSpectrumAnalyzer.AnalyzeAudioBuffer; // This simulates audio capture - in real implementation, you'd capture from MediaPlayer var i: Integer; begin // Simulate audio data with sine waves at different frequencies for i := 0 to Length(FFFTBuffer) - 1 do begin // Generate test signals (replace with actual audio capture) FFFTBuffer[i] := Sin(2 * Pi * 100 * i / 44100) * 0.5 + // 100 Hz bass Sin(2 * Pi * 440 * i / 44100) * 0.3 + // 440 Hz mid Sin(2 * Pi * 2000 * i / 44100) * 0.2; // 2 kHz treble end;
PerformFFT(FFFTBuffer); end;
procedure TAudioSpectrumAnalyzer.PerformFFT(const Buffer: TArray<Double>); // Simplified FFT for demonstration - in real app use a proper FFT library var i: Integer; begin // This is a simplified magnitude calculation // In production, use FFTPACK or similar library
// Calculate magnitudes for each frequency band for i := 0 to 63 do begin // Map to frequency bands (20Hz to 20kHz) var Magnitude := 0.0; for var j := 0 to 31 do begin var Index := i * 32 + j; if Index < Length(Buffer) then Magnitude := Magnitude + Abs(Buffer[Index]); end;
// Normalize and apply logarithmic scaling Magnitude := Magnitude / 32; Magnitude := 20 * Log10(1 + Magnitude * 100); // Store in canvas buffer with smoothing if FCanvasBuffer[i] = 0 then FCanvasBuffer[i] := Magnitude else FCanvasBuffer[i] := FCanvasBuffer[i] * 0.7 + Magnitude * 0.3; // Clamp to reasonable range if FCanvasBuffer[i] > 1 then FCanvasBuffer[i] := 1;end; end;
procedure TAudioSpectrumAnalyzer.UpdateSpectrumBars; var i: Integer; HeightScale: Single; Bar: TCube; Color: TAlphaColor; begin for i := 0 to FBars.Count - 1 do begin Bar := FBars[i];
// Map magnitude to bar height (0.1 to 3.0) HeightScale := 0.1 + FCanvasBuffer[i] * 3.0; Bar.Scale.Point := TPoint3D.Create(1, HeightScale, 1); // Color based on frequency and intensity // Low frequencies (bass) = Red, Mid = Green, High = Blue if i < 20 then // Bass Color := TAlphaColorF.Create(FCanvasBuffer[i], 0.2, 0.2, 1).ToAlphaColor else if i < 45 then // Mid Color := TAlphaColorF.Create(0.2, FCanvasBuffer[i], 0.3, 1).ToAlphaColor else // Treble Color := TAlphaColorF.Create(0.3, 0.2, FCanvasBuffer[i], 1).ToAlphaColor; // Add pulse effect on peaks if FCanvasBuffer[i] > 0.8 then Color := TAlphaColorF.Create(1, 1, 1, 1).ToAlphaColor; Bar.Material := TColorMaterial.Create(Color); // Add rotation effect for extreme frequencies if FCanvasBuffer[i] > 0.9 then Bar.RotateAngle.Point := TPoint3D.Create(0, FCanvasBuffer[i] * 360, 0);end; end;
procedure TAudioSpectrumAnalyzer.FormDestroy(Sender: TObject); begin FIsAnalyzing := False; if Assigned(FThread) then FThread.Wait; FBars.Free; end;
procedure TAudioSpectrumAnalyzer.TimerUpdateTimer(Sender: TObject); begin // Add subtle camera movement for dynamic effect Camera.RotateAngle.Point := TPoint3D.Create( Sin(Now * 2) * 5, // Gentle pan Cos(Now) * 3, // Gentle tilt 0 );
Viewport3D.Render; end;
end.
Never use absolute paths like C:\data.json in cross-platform samples. Replace with TPath.Combine(TPath.GetDocumentsPath, 'data.json') (requires System.IOUtils).
Embarcadero (the company behind Delphi) provides an extensive collection of samples directly within the IDE and on their public repositories. To create apps that feel native and modern,
Delphi FMX is a set of libraries and tools for building cross-platform applications using the Delphi programming language. It provides a unified way to create GUI applications, leveraging the power of the Delphi language and the FireMonkey framework.
A simple "Hello World" application demonstrating the basic structure of a Delphi FMX app.
program HelloWorld;
uses
System.StartUpCopy,
FMX.Forms,
FMX.Controls,
FMX.Types;
begin
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Form1.Label1.Text := 'Hello World!';
Application.Run;
end.