unit Volumes;
interfaceuses
Windows, Messages, Classes, ExtCtrls, ComCtrls, MMSystem;
const
CDVolume = 0;
WaveVolume = 1;
MidiVolume = 2;
type
TVolumeControl = class(TComponent)
private
FDevices : array[0..2] of Integer;
FTrackBars : array[0..2] of TTrackBar;
FTimer : TTimer;
function GetInterval: Integer;
procedure SetInterval(AInterval: Integer);
function GetVolume(AIndex: Integer): Byte;
procedure SetVolume(AIndex: Integer; aVolume: Byte);
procedure InitVolume;
procedure SetTrackBar(AIndex: Integer; ATrackBar: TTrackBar);
{ Private declarations }procedure Update(Sender: TObject);
procedure Changed(Sender: TObject);
protected{ Protected declarations }procedure Notification(AComponent: TComponent; AOperation:
TOperation); override;
public{ Public declarations }constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
published{ Published declarations }property Interval: Integer read GetInterval write SetInterval default
500;
property CDVolume: Byte index 0 read GetVolume write SetVolume stored
False;
property CDTrackBar: TTrackBar index 0 read FTrackBars[0] write
SetTrackBar;
property WaveVolume: Byte index 1 read GetVolume write SetVolume
stored False;
property WaveTrackBar: TTrackBar index 1 read FTrackBars[1] write
SetTrackBar;
property MidiVolume: Byte index 2 read GetVolume write SetVolume
stored False;
property MidiTrackBar: TTrackBar index 2 read FTrackBars[2] write
SetTrackBar;
end;
procedureRegister;
implementationprocedureRegister;
begin
RegisterComponents('Any', [TVolumeControl]);
end;
type
TVolumeRec = recordcase Integer of
0: (LongVolume: Longint);
1: (LeftVolume,
RightVolume : Word);
end;
function TVolumeControl.GetInterval: Integer;
begin
Result := FTimer.Interval;
end;
procedure TVolumeControl.SetInterval(AInterval: Integer);
begin
FTimer.Interval := AInterval;
end;
function TVolumeControl.GetVolume(AIndex: Integer): Byte;
var Vol: TVolumeRec;
begin
Vol.LongVolume := 0;
if FDevices[AIndex] < > -1 thencase AIndex of
0: auxGetVolume(FDevices[AIndex], @Vol.LongVolume);
1: waveOutGetVolume(FDevices[AIndex], @Vol.LongVolume);
2: midiOutGetVolume(FDevices[AIndex], @Vol.LongVolume);
end;
Result := (Vol.LeftVolume + Vol.RightVolume) shr 9;
end;
procedure TVolumeControl.SetVolume(aIndex: Integer; aVolume: Byte);
var Vol: TVolumeRec;
beginif FDevices[AIndex] < > -1 thenbegin
Vol.LeftVolume := aVolume shl 8;
Vol.RightVolume := Vol.LeftVolume;
case AIndex of
0: auxSetVolume(FDevices[AIndex], Vol.LongVolume);
1: waveOutSetVolume(FDevices[AIndex], Vol.LongVolume);
2: midiOutSetVolume(FDevices[AIndex], Vol.LongVolume);
end;
end;
end;
procedure TVolumeControl.SetTrackBar(AIndex: Integer; ATrackBar:
TTrackBar);
beginif ATrackBar < > FTrackBars[AIndex] thenbegin
FTrackBars[AIndex] := ATrackBar;
Update(Self);
end;
end;
AOperation: TOperation);
var I: Integer;
begininherited Notification(AComponent, AOperation);
if (AOperation = opRemove) thenfor I := 0 to 2 doif (AComponent = FTrackBars[I])
then FTrackBars[I] := Nil;
end;
procedure TVolumeControl.Update(Sender: TObject);
var I: Integer;
beginfor I := 0 to 2 doif Assigned(FTrackBars[I]) thenwith FTrackBars[I] dobegin
Min := 0;
Max := 255;
if Orientation = trVertical
then Position := 255 - GetVolume(I)
else Position := GetVolume(I);
OnChange := Self.Changed;
end;
end;
constructor TVolumeControl.Create(AOwner: TComponent);
begininherited Create(AOwner);
FTimer := TTimer.Create(Self);
FTimer.OnTimer := Update;
FTimer.Interval := 500;
InitVolume;
end;
destructor TVolumeControl.Destroy;
var I: Integer;
begin
FTimer.Free;
for I := 0 to 2 doif Assigned(FTrackBars[I]) then
FTrackBars[I].OnChange := Nil;
inherited Destroy;
end;
procedure TVolumeControl.Changed(Sender: TObject);
var I: Integer;
beginfor I := 0 to 2 doif Sender = FTrackBars[I] thenwith FTrackBars[I] dobeginif Orientation = trVertical
then SetVolume(I, 255 - Position)
else SetVolume(I, Position);
end;
end;
procedure TVolumeControl.InitVolume;
var AuxCaps : TAuxCaps;
WaveOutCaps : TWaveOutCaps;
MidiOutCaps : TMidiOutCaps;
I,J : Integer;
begin
FDevices[0] := -1;
for I := 0 to auxGetNumDevs - 1 dobegin
auxGetDevCaps(I, @AuxCaps, SizeOf(AuxCaps));
if (AuxCaps.dwSupport and AUXCAPS_VOLUME) < > 0 thenbegin
FTimer.Enabled := True;
FDevices[0] := I;
break;
end;
end;
FDevices[1] := -1;
for I := 0 to waveOutGetNumDevs - 1 dobegin
waveOutGetDevCaps(I, @WaveOutCaps, SizeOf(WaveOutCaps));
if (WaveOutCaps.dwSupport and WAVECAPS_VOLUME) < > 0 thenbegin
FTimer.Enabled := True;
FDevices[1] := I;
break;
end;
end;
FDevices[2] := -1;
for I := 0 to midiOutGetNumDevs - 1 dobegin
MidiOutGetDevCaps(I, @MidiOutCaps, SizeOf(MidiOutCaps));
if (MidiOutCaps.dwSupport and MIDICAPS_VOLUME) < > 0 thenbegin
FTimer.Enabled := True;
FDevices[2] := I;
break;
end;
end;
end;
end.
Приведенный код - это компонент Delphi, который контролирует объем аудио устройств, в частности CD-плееров, устройства вывода волнового сигнала и MIDI-устройства. Он использует Windows API для взаимодействия с этими устройствами.
Для программного изменения объема можно использовать метод SetVolume класса TVolumeControl. Этот метод принимает два параметра: индекс устройства (0 для CD, 1 для волнового сигнала или 2 для MIDI) и новый объем как байт (диапазон от 0 до 255).
Вот пример:
withtvolumecontroldobeginSetVolume(0,128);// установка объема CD на 50% (128)SetVolume(1,192);// установка объема волнового сигнала на 75% (192)SetVolume(2,255);// установка объема MIDI на максимальный (255)end;
Обратите внимание, что метод SetVolume не изменяет объем немедленно. Вместо этого он обновляет внутреннее состояние компонента и планирует событие таймера для обновления объема устройства.
Также помните, что этот код является специфичным для Delphi и может требовать модификаций для работы с другими средами разработки или платформами.
Альтернативное решение - использовать более высокоуровневую библиотеку или фреймворк для управления аудио устройствами. Это может сделать код более абстрактным и проще в написании, а также упростить интеграцию с другими компонентами. Некоторые примеры таких библиотек включают:
OpenAL (Open Audio Library)
FMOD (Fast Multimedia Output and Delivery)
PortAudio
SoundTouch
Эти библиотеки предоставляют более стандартизированный способ взаимодействия с аудио устройствами, что упрощает написание портативного кода, работающего на различных платформах.
Программно изменять громкость звука с помощью компонента Volumes в Delphi.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.