⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mmmixer.pas

📁 一套及时通讯的原码
💻 PAS
📖 第 1 页 / 共 5 页
字号:

    TMMItemInfo         = record
        Val1, Val2: TMMItemParam;
        Name      : string;
    end;

    {-- TMMCustomMixerControl -------------------------------------------}
    TMMCustomMixerControl = class(TMMNonVisualComponent)
    private
       FAudioLine    : TMMAudioLine;
       FControlId    : TMMControlId;
       FControlType  : TMMControlType;
       FControlClass : TMMControlClass;
       FControlSetup : TMMControlSetup;
       FObserver     : TMMObserver;
       FObservable   : TMMObservable;
       FControlInfo  : TMMControlInfo;
       FOnChange     : TNotifyEvent;
       FCDummy       : TMMControlClass;

       procedure SetAudioLine(Value: TMMAudioLine);
       procedure SetControlId(Value: TMMControlId);
       procedure SetControlType(Value: TMMControlType);
       procedure LineNotify(Sender, Data: TObject);
       function  GetMixer: TMMMixerDevice;
       function  GetLineId: TMMLineId;
       function  StoreControlId: Boolean;
       procedure SetControlInfo(const Value: TMMControlInfo);
       function  ValueIndex(C: TMMChannel; Item: TMMItemIndex): Integer;
       function  GetItemInfo(Index: TMMItemIndex): TMMItemInfo;
       function  StoreControlType: Boolean;
    protected
       procedure UpdateControl; virtual;
       procedure Loaded; override;
       procedure Notification(AComponent: TComponent; Operation: TOperation); override;
       procedure NeedMixer;
       procedure NeedId;
       procedure Changed; virtual;
       procedure DoChange; dynamic;
       procedure ControlIdChanged; virtual;
       function  GetBoolean: Boolean; virtual;
       procedure SetBoolean(Value: Boolean); virtual;
       function  GetUnsigned: Cardinal; virtual;
       procedure SetUnsigned(Value: Cardinal); virtual;
       function  GetSigned: Integer; virtual;
       procedure SetSigned(Value: Integer); virtual;
       function  GetAvailable: Boolean; virtual;
       procedure CalcParams(C: TMMChannel; Item: TMMItemIndex; var Ch: TMMChannelIndex; var It: TMMItemIndex);
       function  ValidControl(const Info: TMixerControl): Boolean; virtual;
       function  GetControlSetup: TMMControlSetup;
       function  GetChannels: TMMChannelIndex; virtual;
       function  GetItems: TMMItemIndex; virtual;
    public
       constructor Create(AOwner: TComponent); override;
       destructor  Destroy; override;

       procedure AddObserver(O: TMMObserver);
       procedure RemoveObserver(O: TMMObserver);

       function  GetChannelSigned(C: TMMChannel; Item: TMMItemIndex): Integer; virtual;
       procedure SetChannelSigned(C: TMMChannel; Item: TMMItemIndex; Value: Integer); virtual;
       function  GetChannelUnsigned(C: TMMChannel; Item: TMMItemIndex): Cardinal; virtual;
       procedure SetChannelUnsigned(C: TMMChannel; Item: TMMItemIndex; Value: Cardinal); virtual;
       function  GetChannelBoolean(C: TMMChannel; Item: TMMItemIndex): Boolean; virtual;
       procedure SetChannelBoolean(C: TMMChannel; Item: TMMItemIndex; Value: Boolean); virtual;

       function ValidMixer: Boolean;
       function CanModify: Boolean;
       function GetItemForLine(Line: TMMAudioLine): TMMItemIndex;

       property Mixer: TMMMixerDevice read GetMixer;
       property LineId: TMMLineId read GetLineId;
       property AsBoolean: Boolean read GetBoolean write SetBoolean;
       property AsUnsigned: Cardinal read GetUnsigned write SetUnsigned;
       property AsSigned: Integer read GetSigned write SetSigned;
       property Available: Boolean read GetAvailable;
       property Channels: TMMChannelIndex read GetChannels;
       property Items: TMMItemIndex read GetItems;
       property ItemInfo[Index:TMMItemIndex]: TMMItemInfo read GetItemInfo;
    published
       property AudioLine: TMMAudioLine read FAudioLine write SetAudioLine;
       property ControlId: TMMControlId read FControlId write SetControlId stored StoreControlId;
       property ControlClass: TMMControlClass read FControlClass write FCDummy stored False;
       property ControlInfo: TMMControlInfo read FControlInfo write SetControlInfo stored False;
       property OnChange: TNotifyEvent read FOnChange write FOnChange;
    protected
       property ControlType: TMMControlType read FControlType write SetControlType stored StoreControlType;
    end;

    TMMControlIdChange = class(TMMMixerChange)
    end;

    EMMMixerControlError = class(Exception)
    end;

    {-- TMMMixerControl -----------------------------------------------------}
    TMMMixerControl = class(TMMCustomMixerControl)
    published
        property    ControlType;
    end;

const
    MaxLeftPan  = -32768;
    MaxRightPan = 32767;

type
    {-- TMMVolumeControl ----------------------------------------------------}
    TMMVolumeControl = class(TMMCustomMixerControl)
    private
        FPanValue: Integer;

        procedure SetPanValue(Value: Integer);
    protected
        function  ValidControl(const Info: TMixerControl): Boolean; override;
        procedure SetUnsigned(Value: Cardinal); override;
        procedure SetSigned(Value: Integer); override;

        function  Pan(C: TMMChannel): Extended;
    public
        constructor Create(AOwner: TComponent); override;

        procedure SetChannelSigned(C: TMMChannel; Item: TMMItemIndex; Value: Integer); override;
        procedure SetChannelUnsigned(C: TMMChannel; Item: TMMItemIndex; Value: Cardinal); override;
    published
        property PanValue: Integer read FPanValue write SetPanValue default 0;
    end;

    {-- TMMPanControl -------------------------------------------------------}
    TMMPanControl = class(TMMCustomMixerControl)
    private
        FVolume    : TMMVolumeControl;
        FObserver  : TMMObserver;
        FSimulate  : Boolean;
        FSimActive : Boolean;
        FValue     : Integer;

        procedure SetControl(Value:TMMVolumeControl);
        procedure SetSimulate(Value:Boolean);
        procedure VolumeNotify(Sender,Data:TObject);
    protected
        function  ValidControl(const Info: TMixerControl): Boolean; override;
        procedure UpdatePan;
        procedure Notification(AComponent: TComponent; Operation: TOperation); override;
        procedure UpdatePanValue;
        procedure UpdateVolumePan;
        procedure SetSigned(Value: Integer); override;
        function  GetSigned: Integer; override;
        function  GetAvailable: Boolean; override;
        procedure UpdateControl; override;
        function  GetChannels: TMMChannelIndex; override;
        function  GetItems: TMMItemIndex; override;
    public
        constructor Create(AOwner: TComponent); override;
        destructor  Destroy; override;

        function  GetChannelSigned(C: TMMChannel; Item: TMMItemIndex): Integer; override;
        procedure SetChannelSigned(C: TMMChannel; Item: TMMItemIndex; Value: Integer); override;
    published
        property  VolumeControl: TMMVolumeControl read FVolume write SetControl;
        property  Simulate: Boolean read FSimulate write SetSimulate default True;
    end;

{-- Mixer service -------------------------------------------------------}
{ D3: This lines rely on current Win32 API}
function APIToCompType(dwType: DWORD): TMMComponentType;
function CompTypeToAPI(CompType: TMMComponentType): DWORD;
function DeviceTypeToTarget(DevType: TMMAudioDeviceType): UINT;
function ControlTypeToAPI(ControlType: TMMControlType): DWORD;
function APIToControlType(ControlType: DWORD): TMMControlType;
function APIToControlFlags(fdwControl: DWORD): TMMControlFlags;
function APIToLineFlags(fdwLine: DWORD): TMMLineFlags;
function ControlClassOfType(CT: DWORD): TMMControlClass;
function IsControlTypeSingleSelect(CT: DWORD): Boolean;
function ControlIdToIdent(Id: LongInt; var S: string): Boolean;
function LineIdToIdent(Id: LongInt; var S: string): Boolean;
function ItemIndexToIdent(Id: LongInt; var S: string): Boolean;
function IdentToControlId(const S: string; var Id: LongInt): Boolean;
function IdentToLineId(const S: string; var Id: LongInt): Boolean;
function IdentToItemIndex(const S: string; var Id: LongInt): Boolean;

type
    EMMMixerServiceError = class(Exception)
    end;

{========================================================================}
implementation
{========================================================================}

uses
    MMDesign;

{== Mixer service =======================================================}
const
    CompTypes: array[TMMComponentType] of DWORD =
           (MIXERLINE_COMPONENTTYPE_DST_DIGITAL,
            MIXERLINE_COMPONENTTYPE_DST_HEADPHONES,
            MIXERLINE_COMPONENTTYPE_DST_LINE,
            MIXERLINE_COMPONENTTYPE_DST_MONITOR,
            MIXERLINE_COMPONENTTYPE_DST_SPEAKERS,
            MIXERLINE_COMPONENTTYPE_DST_TELEPHONE,
            MIXERLINE_COMPONENTTYPE_DST_UNDEFINED,
            MIXERLINE_COMPONENTTYPE_DST_VOICEIN,
            MIXERLINE_COMPONENTTYPE_DST_WAVEIN,
            MIXERLINE_COMPONENTTYPE_SRC_ANALOG,
            MIXERLINE_COMPONENTTYPE_SRC_AUXILIARY,
            MIXERLINE_COMPONENTTYPE_SRC_COMPACTDISC,
            MIXERLINE_COMPONENTTYPE_SRC_DIGITAL,
            MIXERLINE_COMPONENTTYPE_SRC_LINE,
            MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE,
            MIXERLINE_COMPONENTTYPE_SRC_PCSPEAKER,
            MIXERLINE_COMPONENTTYPE_SRC_SYNTHESIZER,
            MIXERLINE_COMPONENTTYPE_SRC_TELEPHONE,
            MIXERLINE_COMPONENTTYPE_SRC_UNDEFINED,
            MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT);

{------------------------------------------------------------------------}
function APIToCompType(dwType: DWORD): TMMComponentType;
var
    i: TMMComponentType;
begin
    for i := Low(TMMComponentType) to High(TMMComponentType) do
    if CompTypes[i] = dwType then
    begin
       Result := i;
       Exit;
    end;
    { TODO: Should be resource id }
    raise EMMMixerServiceError.Create('Undefined API component type');
end;

{------------------------------------------------------------------------}
function CompTypeToAPI(CompType: TMMComponentType): DWORD;
begin
   Result := CompTypes[CompType];
end;

{------------------------------------------------------------------------}
function MakeVersion(Maj, Min: Byte): WORD;
begin
   Result := MakeWord(Min, Maj);
end;

{------------------------------------------------------------------------}
const
    Targets: array[TMMAudioDeviceType] of UINT =
           (MIXERLINE_TARGETTYPE_MIDIIN,
            MIXERLINE_TARGETTYPE_MIDIOUT,
            MIXERLINE_TARGETTYPE_WAVEIN,
            MIXERLINE_TARGETTYPE_WAVEOUT,
            MIXERLINE_TARGETTYPE_AUX,
            MIXERLINE_TARGETTYPE_UNDEFINED);

{------------------------------------------------------------------------}
function DeviceTypeToTarget(DevType: TMMAudioDeviceType): UINT;
begin
   Result := Targets[DevType];
end;

{------------------------------------------------------------------------}
const
    Types: array[TMMControlType] of DWORD =
           (MIXERCONTROL_CONTROLTYPE_CUSTOM,

            MIXERCONTROL_CONTROLTYPE_BASS,
            MIXERCONTROL_CONTROLTYPE_EQUALIZER,
            MIXERCONTROL_CONTROLTYPE_FADER,
            MIXERCONTROL_CONTROLTYPE_TREBLE,
            MIXERCONTROL_CONTROLTYPE_VOLUME,

            MIXERCONTROL_CONTROLTYPE_MIXER,
            MIXERCONTROL_CONTROLTYPE_MULTIPLESELECT,
            MIXERCONTROL_CONTROLTYPE_MUX,
            MIXERCONTROL_CONTROLTYPE_SINGLESELECT,

            MIXERCONTROL_CONTROLTYPE_BOOLEANMETER,
            MIXERCONTROL_CONTROLTYPE_PEAKMETER,
            MIXERCONTROL_CONTROLTYPE_SIGNEDMETER,
            MIXERCONTROL_CONTROLTYPE_UNSIGNEDMETER,

            MIXERCONTROL_CONTROLTYPE_DECIBELS,
            MIXERCONTROL_CONTROLTYPE_PERCENT,
            MIXERCONTROL_CONTROLTYPE_SIGNED,
            MIXERCONTROL_CONTROLTYPE_UNSIGNED,

            MIXERCONTROL_CONTROLTYPE_PAN,
            MIXERCONTROL_CONTROLTYPE_QSOUNDPAN,
            MIXERCONTROL_CONTROLTYPE_SLIDER,

            MIXERCONTROL_CONTROLTYPE_BOOLEAN,
            MIXERCONTROL_CONTROLTYPE_BUTTON,
            MIXERCONTROL_CONTROLTYPE_LOUDNESS,
            MIXERCONTROL_CONTROLTYPE_MONO,
            MIXERCONTROL_CONTROLTYPE_MUTE,
            MIXERCONTROL_CONTROLTYPE_ONOFF,
            MIXERCONTROL_CONTROLTYPE_STEREOENH,

            MIXERCONTROL_CONTROLTYPE_MICROTIME,
            MIXERCONTROL_CONTROLTYPE_MILLITIME);

{------------------------------------------------------------------------}
function ControlTypeToAPI(ControlType: TMMControlType): DWORD;
begin
   Result := Types[ControlType];
end;

{------------------------------------------------------------------------}
function APIToControlType(ControlType: DWORD): TMMControlType;
begin
   for Result := Low(TMMControlType) to High(TMMControlType) do
   if Types[Result] = ControlType then
      Exit;
   Result := ctCustom; { Because on my computer there are some undefined device }
end;

{------------------------------------------------------------------------}
const
    Flags: array[TMMControlFlag] of DWORD =
       (MIXERCONTROL_CONTROLF_DISABLED,
        MIXERCONTROL_CONTROLF_MULTIPLE,
        MIXERCONTROL_CONTROLF_UNIFORM);

{------------------------------------------------------------------------}
function APIToControlFlags(fdwControl: DWORD): TMMControlFlags;
var
   i: TMMControlFlag;
begin
   Result:= [];
   for i:= Low(TMMControlFlag) to High(TMMControlFlag) do
   if (fdwControl and Flags[i]) <> 0 then
       Include(Result,i);
end;

{------------------------------------------------------------------------}
const
    LineFlags: array[TMMLineFlag] of DWORD =
       (MIXERLINE_LINEF_ACTIVE,
        MIXERLINE_LINEF_DISCONNECTED,
        MIXERLINE_LINEF_SOURCE);

{------------------------------------------------------------------------}
function APIToLineFlags(fdwLine: DWORD): TMMLineFlags;
var
   i: TMMLineFlag;
begin
   Result:= [];
   for i:= Low(TMMLineFlag) to High(TMMLineFlag) do
   if (fdwLine and LineFlags[i]) <> 0 then
       Include(Result,i);
end;

{------------------------------------------------------------------------}
const
    CClasses: array[TMMControlClass] of DWORD =
           (MIXERCONTROL_CT_CLASS_CUSTOM,
            MIXERCONTROL_CT_CLASS_FADER,
            MIXERCONTROL_CT_CLASS_LIST,
            MIXERCONTROL_CT_CLASS_METER,
            MIXERCONTROL_CT_CLASS_NUMBER,
            MIXERCONTROL_CT_CLASS_SLIDER,
            MIXERCONTROL_CT_CLASS_SWITCH,
            MIXERCONTROL_CT_CLASS_TIME);

{------------------------------------------------------------------------}
function ControlClassOfType(CT: DWORD): TMMControlClass;
begin

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -