I wrote following code to fade out the Video Playback volume as descending gradually when the installer finishes installing my program.
procedure CurPageChanged(CurPageID: Integer);
var
X: Integer;
begin
...
if CurPageID = wpFinished then
begin
VideoHandler.Release;
VideoHandler.Close;
DSSetVolume(-0);
X := 0;
repeat
DSSetVolume(X);
Log(IntToStr(X));
X = X - 1;
until X = -10000;
DSStopMediaPlay;
...
end;
...
end;
Above code outputs the X value as I expecting to reduce volume gradually and I can see it like -1 , -2 ... -10000
in the log well. But when this repeat process starts,
WizardForm
appears normally, but nothing is displaying in its wpFinished
Page. Only an empty form is displaying. There is nothing is drawn in the form except WizardForm.Caption
. It behaves like freezing until the repeat process (loop) finishes.
Volume never reduces normally or to a gradual descending order.
After the loop finishes and Log outputs -10000
, WizardForm
displays normally and page also showing normally. Volume stops suddenly because I set to DSStopMediaPlay
.
How can I do the above process (gradual reduction of video playback sound) correctly without any freezing or exception?
UPDATE
Following Code can give best results when the User's System Sound has been set to 20%
in Sound Control Panel in Windows.
procedure VolumeFadeTimerProc(HandleW, msg, idEvent, TimeSys: LongWord);
begin
MPEGVideoVolume := MPEGVideoVolume - 15;
if MPEGVideoVolume < -4000 then
begin
DSStopMediaPlay;
KillTimer( 0, TimerID);
KillTimer( 0, VolumeFadeTimer);
Log('Volume Fade Timer has been reset.');
end
else
begin
Log('MPEG Video Volume has been set to: ' + IntToStr(MPEGVideoVolume));
DSSetVolume(MPEGVideoVolume);
end;
end;
Volume Reducing Amount is 15
Maximum Reducing Volume Amount is -4000
Following Code can give best results when the User's System Sound has been set to 100%
in Sound Control Panel in Windows.
procedure VolumeFadeTimerProc(HandleW, msg, idEvent, TimeSys: LongWord);
begin
MPEGVideoVolume := MPEGVideoVolume - 35;
if MPEGVideoVolume < -10000 then
begin
DSStopMediaPlay;
KillTimer( 0, TimerID);
KillTimer( 0, VolumeFadeTimer);
Log('Volume Fade Timer has been reset.');
end
else
begin
Log('MPEG Video Volume has been set to: ' + IntToStr(MPEGVideoVolume));
DSSetVolume(MPEGVideoVolume);
end;
end;
Volume Reducing Amount is 35
Maximum Reducing Volume Amount is -10000
Do I need to automatically change Volume Reducing Amount and Maximum Reducing Volume according to the Amount of user's System Sound set to?
Thanks in advance.
Because you stop the window message pump in your loop. What freezes the window and probably also prevents the volume fade out.
You have to use a timer to fade out the volume without freezing the message pump.
[Code]
function SetTimer(
hWnd: longword; nIDEvent, uElapse: LongWord; lpTimerFunc: LongWord): LongWord;
external 'SetTimer@user32.dll stdcall';
var
Volume: Integer;
VolumeFadeTimer: LongWord;
procedure VolumeFadeTimerProc(
H: LongWord; Msg: LongWord; IdEvent: LongWord; Time: LongWord);
begin
{ Fade by -1000 every 100 ms }
Volume := Volume - 1000;
if Volume <= -10000 then
begin
DSStopMediaPlay;
KillTimer(0, VolumeFadeTimer);
end
else
begin
DSSetVolume(Volume);
end;
end;
procedure CurPageChanged(CurPageID: Integer);
begin
if CurPageID = wpFinished then
begin
VideoHandler.Release;
VideoHandler.Close;
Volume := 0;
{ call VolumeFadeCallback every 100 ms }
VolumeFadeTimer := SetTimer(0, 0, 100, CreateCallback(@VolumeFadeTimerProc));
DSSetVolume(Volume);
end;
end;
For CreateCallback
function, you need Inno Setup 6. If you are stuck with Inno Setup 5, you can use WrapCallback
function from InnoTools InnoCallback library.