Einzelnen Beitrag anzeigen

taaktaak

Registriert seit: 25. Okt 2007
Ort: Radbruch
1.990 Beiträge
 
Delphi 7 Professional
 
#2

Re: master balance verändern!

  Alt 31. Okt 2007, 22:01
Hallo crayzo!
Hier eine sehr alte Unit aus meinem Bestand. Trotz (meiner) einschränkenden Hinweise ist das Ding seit einigen Jahren bei mir im Einsatz. Schau mal rein...
Gruß Ralph

Delphi-Quellcode:
unit Mixer;

interface { ----------------------------------------------------------------- }

uses Windows,Classes,SysUtils,MPlayer,MMSystem,Math;

// BasicFunctions found at [url]http://delphi.about.com[/url]
//
// MixerParameters
//
// VolumePos = Range from 100 to 65535
// --------------------------------------------------------------------
// set TrackBar : Min=100, Max=65535, LineSize=655, PageSize=6553, Frequency=6553
// SelStart=0, SelEnd=0, Height=20, ThumbLength=10,
// TickStyle=tsAuto
//
//
// FadePos = Range from -12 to +12
// --------------------------------------------------------------------
// set TrackBar : Min=-12, Max=12, LineSize=2, PageSize=4, Frequency=4
// SelStart=0, SelEnd=-1, Height=20, ThumbLength=10,
// TickStyle=tsAuto
//
// MediaPlayerParameters
// VolumePos = Range from 0 to 1000

type tMixerCtrl = (MasterOut,WaveOut,CDOut,LineOut);

var AvailMixer : TStringList;

procedure GetAvailMixer;

procedure GetMixerIDs;
procedure SetActiveMixer(NewMixerID:Integer);

function GetVolume(Ctrl:TMixerCtrl):Integer;
procedure SetVolume(Ctrl:tMixerCtrl;Volume:Integer);

function GetBalance(Ctrl:TMixerCtrl):Integer;
procedure SetBalance(Ctrl:tMixerCtrl;Balance:Integer);

function MuteActive(Ctrl:TMixerCtrl):Boolean;
procedure SetMute(Ctrl:tMixerCtrl;State:Boolean);

function GetMediaPlayerVolume(MP:TMediaPlayer):Integer;
procedure SetMediaPlayerVolume(MP:TMediaPlayer;Volume:Integer);

implementation { ----------------------------------------------------------- }
{
  Achtung : Die Balance ist offenbar nicht direkt zu lesen/setzen.
            Daher erfolgt die Berechnung über Differenz VolumenLinks und
            VolumenRechts. Das funktioniert nur, wenn minVolumen=257(?).
            Außerdem führt die VolumenÄnderung im Mixer auf Null zum Zurück-
            setzen der Balance auf Null?!

            >> Lösung trotz intensivem Basteln nicht gefunden!
            >> Vermutlich ist hier noch ein Logikfehler!!                     }


// ------------------------------------------------------- MixerDevicesControls

var MixerID : Integer;

     OutVolID,
     OutMuteID : Array[MasterOut..LineOut] of DWord;

procedure GetMixerIDs;
var CtrlType : DWord;

 function GetID(CompType:DWORD;ControlType:DWord):DWORD;
 var mxl : MIXERLINE;
     mxc : MIXERCONTROL;
     mxlc : MIXERLINECONTROLS;
 begin
  Result :=0;
  mxl.cbStruct :=SizeOf(mxl);
  mxl.dwComponentType:=CompType;
  if (mixerGetLineInfo(MixerID,@mxl,MIXER_GETLINEINFOF_COMPONENTTYPE)=MMSYSERR_NOERROR) then begin
   mxlc.cbStruct :=SizeOf(mxlc);
   mxlc.dwLineID :=mxl.dwLineID;
   mxlc.dwControlType:=ControlType;
   mxlc.cControls :=mxl.cControls;
   mxlc.cbmxctrl :=sizeof(mxc);
   mxlc.pamxctrl :=@mxc;
   if (mixerGetLineControls(MixerID,@mxlc,MIXER_GETLINECONTROLSF_ONEBYTYPE)=MMSYSERR_NOERROR) then
    Result:=mxc.dwControlID;
   end;
 end;

begin
 CtrlType:=MixerControl_ControlType_Volume;
 OutVolID[MasterOut] :=GetID(MixerLine_ComponentType_DST_Speakers, CtrlType);
 OutVolID[WaveOut] :=GetID(MixerLine_ComponentType_SRC_WaveOut, CtrlType);
 OutVolID[CDOut] :=GetID(MixerLine_ComponentType_SRC_CompactDisc,CtrlType);
 OutVolID[LineOut] :=GetID(MixerLine_ComponentType_SRC_Line, CtrlType);

 CtrlType:=MixerControl_ControlType_Mute;
 OutMuteID[MasterOut]:=GetID(MixerLine_ComponentType_DST_Speakers, CtrlType);
 OutMuteID[WaveOut] :=GetID(MixerLine_ComponentType_SRC_WaveOut, CtrlType);
 OutMuteID[CDOut] :=GetID(MixerLine_ComponentType_SRC_CompactDisc,CtrlType);
 OutMuteID[LineOut] :=GetID(MixerLine_ComponentType_SRC_Line, CtrlType);
end;

function pGetVolumeLR(ID:DWord;var VolumeLeft,VolumeRight:DWord):Boolean;
var Volume : Array[0..1] Of TMixerControlDetails_Unsigned;
    mxcd : TMixerControlDetails;
begin
 with mxcd do begin
  cbStruct :=SizeOf(mxcd);
  dwControlID :=ID;
  cChannels :=2;
  cMultipleItems:=0;
  cbDetails :=SizeOf(TMixerControlDetails_Unsigned)*2;
  paDetails :=@Volume;
  Result:=(mixerGetControlDetails(MixerID,@mxcd,MIXER_GETCONTROLDETAILSF_VALUE)=MMSYSERR_NOERROR);
  end;
 VolumeLeft :=Volume[0].dwValue; // reversal to SetVolume
 VolumeRight:=Volume[1].dwValue; // why ??
end;

function pSetVolumeLR(ID,VolumeLeft,VolumeRight:DWord):Boolean;
var Volume : Array[0..1] Of TMixerControlDetails_Unsigned;
    mxcd : TMixerControlDetails;
begin
 if (VolumeLeft <257) and (VolumeRight=0) then VolumeLeft :=257;
 if (VolumeRight<257) and (VolumeLeft =0) then VolumeRight:=257;

 Volume[0].dwValue:=VolumeRight;
 Volume[1].dwValue:=VolumeLeft;
 with mxcd do begin
  cbStruct :=SizeOf(mxcd);
  dwControlID :=ID;
  cChannels :=2;
  cMultipleItems:=0;
  cbDetails :=SizeOf(TMixerControlDetails_Unsigned)*2;
  paDetails :=@Volume;
  Result:=(mixerSetControlDetails(MixerID,@mxcd,MIXER_SETCONTROLDETAILSF_VALUE)=MMSYSERR_NOERROR);
  end;
end;

function pGetMute(ID:DWord;var EnableMute:Boolean):Boolean;
var mxcd : TMixerControlDetails;
    mxcdb : TMixerControlDetailsBoolean;
begin
 with mxcd do begin
  cbStruct :=SizeOf(mxcd);
  dwControlID :=ID;
  cChannels :=1;
  cMultipleItems:=0;
  cbDetails :=SizeOf(TMixerControlDetailsBoolean);
  paDetails :=@mxcdb;
  Result:=(mixerGetControlDetails(MixerID,@mxcd,MIXER_GETCONTROLDETAILSF_VALUE)=MMSYSERR_NOERROR);
  end;
 EnableMute:=LongBool(mxcdb.fValue);
end;

function pSetMute(ID:DWord;EnableMute:Boolean):Boolean;
var mxcd : TMixerControlDetails;
    mxcdb : TMixerControlDetailsBoolean;
begin
 with mxcd do begin
  cbStruct :=SizeOf(mxcd);
  dwControlID :=ID;
  cChannels :=1;
  cMultipleItems:=0;
  cbDetails :=SizeOf(TMixerControlDetailsBoolean);
  paDetails :=@mxcdb;
  LongBool(mxcdb.fValue):=EnableMute;
  Result:=(mixerSetControlDetails(MixerID,@mxcd,MIXER_SETCONTROLDETAILSF_VALUE)=MMSYSERR_NOERROR);
  end;
end;

// --------------------------------------------------------- user interface NEW

procedure GetAvailMixer;
var DNum,i : Integer;
    Caps : TWaveOutCapsA;
begin
 AvailMixer.Clear;
 DNum:=waveOutGetNumDevs; // number of devices
 for i:=0 to DNum-1 do begin // query devicenames
  waveOutGetDevCaps(i,@Caps,SizeOf(TWaveOutCapsA));
  AvailMixer.Add(String(Caps.szPname));
  end;
end;

procedure SetActiveMixer(NewMixerID:Integer);
begin
 if MixerID<AvailMixer.Count then begin
  MixerID:=NewMixerID;
  GetMixerIDs;
  end;
end;

function GetVolume(Ctrl:TMixerCtrl):Integer;
var volL,volR : DWord;
begin
 pGetVolumeLR(OutVolID[Ctrl],volL,volR);
 Result:=Max(volL,volR);
 if Result<257 then Result:=257;
end;

procedure SetVolume(Ctrl:tMixerCtrl;Volume:Integer);
var F,volL,volR : Integer;
    vL,vR : DWord;
begin
 if Volume<257 then Volume:=257;

 pGetVolumeLR(OutVolID[Ctrl],vL,vR);

 volL:=vL;
 volR:=vR;

 if volL=volR then F:=0
              else if volL<volR then F:= 12-((volL*12) div volR)
                                else F:=-(12-((volR*12) div volL));
 volL:=Volume;
 if F<0 then dec(volL,(volL div 12)*abs(F));
 volR:=Volume;
 if F>0 then dec(volR,(volR div 12)*F);

 pSetVolumeLR(OutVolID[Ctrl],volL,volR);
end;

function GetBalance(Ctrl:TMixerCtrl):Integer;
var volL,volR : DWord;
    F : Integer;
begin
 pGetVolumeLR(OutVolID[Ctrl],volL,volR);

 if volL=volR then F:=0
              else if volL<volR then F:= 12-((volL*12) div volR)
                                else F:=-(12-((volR*12) div volL));
 Result:=F;
end;

procedure SetBalance(Ctrl:tMixerCtrl;Balance:Integer);
var F,volL,volR : Integer;
    vL,vR : DWord;
begin
 pGetVolumeLR(OutVolID[Ctrl],vL,vR);

 volL:=Max(vL,vR);
 volR:=volL;
 F :=abs(Balance);
 if Balance<0 then dec(volL,(volL div 12)*F);
 if Balance>0 then dec(volR,(volR div 12)*F);

 pSetVolumeLR(OutVolID[Ctrl],volL,volR);
end;

function MuteActive(Ctrl:TMixerCtrl):Boolean;
begin
 pGetMute(OutMuteID[Ctrl],Result);
end;

procedure SetMute(Ctrl:tMixerCtrl;State:Boolean);
begin
 pSetMute(OutMuteID[Ctrl],State);
end;

// ------------------------------------------ user interface MediaPlayer volume

const MCI_SETAUDIO = $0873;
      MCI_DGV_SETAUDIO_VOLUME = $4002;
      MCI_DGV_SETAUDIO_ITEM = $00800000;
      MCI_DGV_SETAUDIO_VALUE = $01000000;
      MCI_DGV_STATUS_VOLUME = $4019;

type MCI_DGV_SETAUDIO_PARMS = record
                                 dwCallback : DWORD;
                                 dwItem : DWORD;
                                 dwValue : DWORD;
                                 dwOver : DWORD;
                                 lpstrAlgorithm : PChar;
                                 lpstrQuality : PChar;
                                 end;

      MCI_STATUS_PARMS = record
                                 dwCallback : DWORD;
                                 dwReturn : DWORD;
                                 dwItem : DWORD;
                                 dwTrack : DWORD;
                                 end;

procedure SetMediaPlayerVolume(MP:TMediaPlayer;Volume:Integer);
var p : MCI_DGV_SETAUDIO_PARMS;
begin
 p.dwCallback :=0;
 p.dwItem :=MCI_DGV_SETAUDIO_VOLUME;
 p.dwValue :=Volume;
 p.dwOver :=0;
 p.lpstrAlgorithm:=nil;
 p.lpstrQuality :=nil;
 mciSendCommand(MP.DeviceID,MCI_SETAUDIO,
 MCI_DGV_SETAUDIO_VALUE or MCI_DGV_SETAUDIO_ITEM, Cardinal(@p));
end;

function GetMediaPlayerVolume(MP:TMediaPlayer):Integer;
var p : MCI_STATUS_PARMS;
begin
 p.dwCallback:=0;
 p.dwItem :=MCI_DGV_STATUS_VOLUME;
 mciSendCommand(MP.DeviceID,MCI_STATUS,MCI_STATUS_ITEM,Cardinal(@p));
 Result:=p.dwReturn;
end;

initialization { ------------------------------------------------------------ }

 AvailMixer :=TStringList.Create; // init list of mixer names
 AvailMixer.Sorted:=false; // don't sort mixer list
 GetAvailMixer; // get available mixer and save to list


 MixerID :=0; // use current mixer at start
 GetMixerIDs;

finalization { -------------------------------------------------------------- }

 AvailMixer.Free;

end.
Ralph
  Mit Zitat antworten Zitat