320 lines
8.8 KiB
ObjectPascal
320 lines
8.8 KiB
ObjectPascal
program waveform_fpGUI;
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
uses
|
|
{$IFDEF UNIX}
|
|
cthreads, {$ENDIF}
|
|
SysUtils,
|
|
Classes,
|
|
fpg_base,
|
|
fpg_main,
|
|
fpg_widget,
|
|
uos_flat,
|
|
ctypes,
|
|
fpg_style_chrome_silver_flatmenu,
|
|
fpg_stylemanager,
|
|
{%units 'Auto-generated GUI code'}
|
|
fpg_form,
|
|
fpg_editbtn,
|
|
fpg_label,
|
|
fpg_button {%endunits};
|
|
|
|
type
|
|
|
|
Twaveform = class(TfpgForm)
|
|
private
|
|
{@VFD_HEAD_BEGIN: waveform}
|
|
FilenameEdit1: TfpgFileNameEdit;
|
|
Label1: TfpgLabel;
|
|
Button1: TfpgButton;
|
|
Custom1: TfpgWidget;
|
|
{@VFD_HEAD_END: waveform}
|
|
public
|
|
procedure AfterCreate; override;
|
|
procedure drawwave(Sender: TObject);
|
|
procedure btnDrawClick(Sender: TObject);
|
|
procedure btnCloseClick(Sender: TObject);
|
|
procedure DrawWaveForm;
|
|
end;
|
|
|
|
var
|
|
opath, fnsf, fnmp, ordir: string;
|
|
PlayerIndex1, In1Index, filelength, framewanted: integer;
|
|
poswav, chan: integer;
|
|
waveformdata: array of cfloat;
|
|
|
|
|
|
{@VFD_NEWFORM_DECL}
|
|
|
|
{@VFD_NEWFORM_IMPL}
|
|
|
|
procedure Twaveform.DrawWaveForm;
|
|
begin
|
|
waveformdata := uos_InputGetLevelArray(PlayerIndex1, In1Index);
|
|
fpgapplication.ProcessMessages;
|
|
button1.tag := 1;
|
|
custom1.Visible := True;
|
|
|
|
end;
|
|
|
|
procedure Twaveform.btndrawclick(Sender: TObject);
|
|
begin
|
|
custom1.Visible := False;
|
|
|
|
windowtitle := 'Wave Form. uos version ' + IntToStr(uos_getversion());
|
|
|
|
PlayerIndex1 := 0;
|
|
|
|
//// Create the player.
|
|
uos_CreatePlayer(PlayerIndex1);
|
|
//// PlayerIndex : from 0 to what your computer can do !
|
|
//// If PlayerIndex exists already, it will be overwriten...
|
|
|
|
//// add input from audio file with default parameters
|
|
In1Index := uos_AddFromFile(PlayerIndex1, PChar(FilenameEdit1.filename));
|
|
|
|
//// no output because only decode the steam for wave form
|
|
|
|
/// get the length of the audio file
|
|
filelength := uos_InputLength(PlayerIndex1, In1Index);
|
|
|
|
chan := uos_InputGetChannels(PlayerIndex1, In1Index);
|
|
|
|
// writeln('chan = ' + inttostr(chan));
|
|
// writeln('filelength = ' + inttostr(filelength));
|
|
|
|
///// set calculation of level/volume into array (usefull for wave form procedure)
|
|
uos_InputSetLevelArrayEnable(PlayerIndex1, In1Index, 2);
|
|
///////// set level calculation (default is 0)
|
|
// 0 => no calcul
|
|
// 1 => calcul before all DSP procedures.
|
|
// 2 => calcul after all DSP procedures.
|
|
|
|
//// determine how much frame will be designed
|
|
framewanted := filelength div custom1.Width;
|
|
|
|
uos_InputSetFrameCount(PlayerIndex1, In1Index, framewanted);
|
|
|
|
///// Assign the procedure of object to execute at end of stream
|
|
uos_EndProc(PlayerIndex1, @DrawWaveForm);
|
|
|
|
uos_Play(PlayerIndex1); /////// everything is ready, here we are, lets do it...
|
|
|
|
end;
|
|
|
|
procedure Twaveform.drawwave(Sender: TObject);
|
|
begin
|
|
if button1.tag = 0 then
|
|
with Custom1 do
|
|
begin
|
|
Canvas.GradientFill(GetClientRect, clgreen, clBlack, gdVertical);
|
|
Canvas.TextColor := clWhite;
|
|
Canvas.DrawText(60, 20, 'uos');
|
|
end
|
|
else
|
|
begin
|
|
Custom1.Canvas.GradientFill(GetClientRect, clwhite, clblack, gdVertical);
|
|
|
|
poswav := 0;
|
|
|
|
while poswav < length(waveformdata) div chan do
|
|
begin
|
|
if chan = 2 then
|
|
begin
|
|
Custom1.Canvas.setcolor(cldarkgreen);
|
|
|
|
Custom1.Canvas.drawLine(poswav, Custom1.Height div 2, poswav, ((Custom1.Height div 2) - 1) - round(
|
|
(waveformdata[poswav * 2]) * (Custom1.Height / 2) - 1));
|
|
|
|
Custom1.Canvas.setcolor(clred);
|
|
Custom1.Canvas.drawLine(poswav, (Custom1.Height div 2) + 2, poswav, ((Custom1.Height div 2) + 1) + round(
|
|
(waveformdata[(poswav * 2) + 1]) * (Custom1.Height / 2) + 1));
|
|
end;
|
|
if chan = 1 then
|
|
begin
|
|
Custom1.Canvas.setcolor(cldarkgreen);
|
|
Custom1.Canvas.drawLine(poswav, 0, poswav, ((Custom1.Height) - 1) - round((waveformdata[poswav]) * (Custom1.Height) - 1));
|
|
end;
|
|
Inc(poswav);
|
|
end;
|
|
Custom1.Canvas.TextColor := clBlack;
|
|
Custom1.Canvas.DrawText(60, 20, 'Right Channel');
|
|
|
|
Custom1.Canvas.TextColor := clWhite;
|
|
Custom1.Canvas.DrawText(60, Custom1.Height - 40, 'Left Channel');
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
procedure Twaveform.btnCloseClick(Sender: TObject);
|
|
begin
|
|
uos_UnloadLib();
|
|
end;
|
|
|
|
procedure Twaveform.AfterCreate;
|
|
begin
|
|
{%region 'Auto-generated GUI code' -fold}
|
|
|
|
{@VFD_BODY_BEGIN: waveform}
|
|
Name := 'waveform';
|
|
SetPosition(267, 185, 841, 475);
|
|
WindowTitle := 'Wave Form';
|
|
IconName := '';
|
|
Hint := '';
|
|
WindowPosition := wpScreenCenter;
|
|
BackgroundColor := clmoneygreen;
|
|
Ondestroy := @btnCloseClick;
|
|
|
|
FilenameEdit1 := TfpgFileNameEdit.Create(self);
|
|
with FilenameEdit1 do
|
|
begin
|
|
Name := 'FilenameEdit1';
|
|
SetPosition(28, 28, 360, 24);
|
|
ExtraHint := '';
|
|
FileName := '';
|
|
Filter := '';
|
|
InitialDir := '';
|
|
TabOrder := 1;
|
|
end;
|
|
|
|
Label1 := TfpgLabel.Create(self);
|
|
with Label1 do
|
|
begin
|
|
Name := 'Label1';
|
|
SetPosition(164, 12, 80, 15);
|
|
FontDesc := '#Label1';
|
|
Hint := '';
|
|
Text := 'Audio file';
|
|
end;
|
|
|
|
Button1 := TfpgButton.Create(self);
|
|
with Button1 do
|
|
begin
|
|
Name := 'Button1';
|
|
SetPosition(400, 28, 412, 23);
|
|
FontDesc := '#Label1';
|
|
Hint := '';
|
|
ImageName := '';
|
|
TabOrder := 3;
|
|
Text := 'Draw Wave Form';
|
|
onclick := @btndrawClick;
|
|
end;
|
|
|
|
Custom1 := TfpgWidget.Create(self);
|
|
with Custom1 do
|
|
begin
|
|
Name := 'Custom1';
|
|
SetPosition(2, 68, 836, 404);
|
|
OnPaint := @drawwave;
|
|
end;
|
|
|
|
{@VFD_BODY_END: waveform}
|
|
{%endregion}
|
|
|
|
|
|
ordir := IncludeTrailingBackslash(ExtractFilePath(ParamStr(0)));
|
|
// Height := 197;
|
|
{$IFDEF Windows}
|
|
{$if defined(cpu64)}
|
|
fnsf := ordir + 'lib\Windows\64bit\LibSndFile-64.dll';
|
|
fnmp := ordir + 'lib\Windows\64bit\LibMpg123-64.dll';
|
|
|
|
{$else}
|
|
fnsf := ordir + 'lib\Windows\32bit\LibSndFile-32.dll';
|
|
fnmp := ordir + 'lib\Windows\32bit\LibMpg123-32.dll';
|
|
{$endif}
|
|
FilenameEdit1.FileName := ordir + 'sound\test.mp3';
|
|
{$ENDIF}
|
|
|
|
{$IFDEF Darwin}
|
|
{$IFDEF CPU32}
|
|
opath := ordir;
|
|
opath := copy(opath, 1, Pos('/uos', opath) - 1);
|
|
FilenameEdit1.FileName := ordir + 'sound/test.mp3';
|
|
fnsf := opath + '/lib/Mac/32bit/LibSndFile-32.dylib';
|
|
fnmp := opath + '/lib/Mac/32bit/LibMpg123-32.dylib';
|
|
{$ENDIF}
|
|
{$IFDEF CPU64}
|
|
opath := ordir;
|
|
opath := copy(opath, 1, Pos('/uos', opath) - 1);
|
|
FilenameEdit1.FileName := ordir + 'sound/test.mp3';
|
|
fnsf := opath + '/lib/Mac/64bit/LibSndFile-64.dylib';
|
|
fnmp:= opath + '/lib/Mac/64bit/LibMpg123-64.dylib';
|
|
{$ENDIF}
|
|
{$ENDIF}
|
|
|
|
|
|
{$if defined(CPUAMD64) and defined(linux) }
|
|
fnsf := ordir + 'lib/Linux/64bit/LibSndFile-64.so';
|
|
fnmp := ordir + 'lib/Linux/64bit/LibMpg123-64.so';
|
|
FilenameEdit1.FileName := ordir + 'sound/test.mp3';
|
|
{$ENDIF}
|
|
{$if defined(cpu86) and defined(linux)}
|
|
fnsf := ordir + 'lib/Linux/32bit/LibSndFile-32.so';
|
|
fnmp := ordir + 'lib/Linux/32bit/LibMpg123-32.so';
|
|
FilenameEdit1.FileName := ordir + 'sound/test.mp3';
|
|
{$ENDIF}
|
|
{$if defined(linux) and defined(cpuarm)}
|
|
fnsf := ordir + 'lib/Linux/arm_raspberrypi/libsndfile-arm.so';
|
|
fnmp := ordir + 'lib/Linux//arm_raspberrypi/libmpg123-arm.so';
|
|
FilenameEdit1.FileName := ordir + 'sound/test.mp3';
|
|
{$ENDIF}
|
|
|
|
{$if defined(linux) and defined(cpuaarch64)}
|
|
fnsf := ordir + 'lib/Linux/aarch64_raspberrypi/libportaudio_aarch64.so';
|
|
fnmp := ordir + 'lib/Linux/aarch64_raspberrypi/libmpg123_aarch64.so';
|
|
FilenameEdit1.FileName := ordir + 'sound/test.mp3';
|
|
{$ENDIF}
|
|
|
|
{$IFDEF freebsd}
|
|
{$if defined(cpu64)}
|
|
fnsf := ordir + 'lib/FreeBSD/64bit/libsndfile-64.so';
|
|
fnmp := ordir + 'lib/FreeBSD/64bit/libmpg123-64.so';
|
|
{$else}
|
|
fnsf := ordir + 'lib/FreeBSD/32bit/libsndfile-32.so';
|
|
fnmp := ordir + 'lib/FreeBSD/32bit/libmpg123-32.so';
|
|
{$endif}
|
|
FilenameEdit1.FileName := ordir + 'sound/test.mp3';
|
|
{$ENDIF}
|
|
|
|
{$if defined(CPUAMD64) and defined(linux) }
|
|
// For Linux amd64, check libsndfile.so
|
|
if uos_TestLoadLibrary(PChar(fnsf)) = false then
|
|
fnsf := fnsf + '.2';
|
|
{$endif}
|
|
|
|
if uos_LoadLib(nil, PChar(fnsf), PChar(fnmp), nil, nil, nil, nil) = 0 then
|
|
button1.Enabled := True
|
|
else
|
|
begin
|
|
button1.Enabled := False;
|
|
button1.Text := 'Error while loading libraries :-(';
|
|
end;
|
|
|
|
end;
|
|
|
|
procedure MainProc;
|
|
var
|
|
frm: Twaveform;
|
|
begin
|
|
fpgApplication.Initialize;
|
|
try
|
|
if fpgStyleManager.SetStyle('Chrome silver flat menu') then
|
|
fpgStyle := fpgStyleManager.Style;
|
|
fpgApplication.CreateForm(Twaveform, frm);
|
|
fpgApplication.MainForm := frm;
|
|
frm.Show;
|
|
fpgApplication.Run;
|
|
finally
|
|
uos_free;
|
|
frm.Free;
|
|
end;
|
|
end;
|
|
|
|
begin
|
|
MainProc;
|
|
end.
|
|
|