Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Mixer Control


Автор: php 9.9.2004, 14:24
Каким образом можно подготовить микрофон к записи,
т.е вкл или выкл его в системе..
Знаю что можно исп-ть директиву MixerSetControlDetails,
но как это сделать для записи (Record Control)

Автор: Illusion Dolphin 9.9.2004, 19:49
А если так:
Код

uses
 MMSystem;

// Setzt die Lautstarke fur das Mikrofon
// Set the volume for the microphone

function SetMicrophoneVolume(bValue: Word): Boolean;
var {0..65535}
 hMix: HMIXER;
 mxlc: MIXERLINECONTROLS;
 mxcd: TMIXERCONTROLDETAILS;
 vol: TMIXERCONTROLDETAILS_UNSIGNED;
 mxc: MIXERCONTROL;
 mxl: TMixerLine;
 intRet: Integer;
 nMixerDevs: Integer;
begin
 // Check if Mixer is available
 // Uberprufen, ob ein Mixer vorhanden
 nMixerDevs := mixerGetNumDevs();
 if (nMixerDevs < 1) then
 begin
   Exit;
 end;

 // open the mixer
 intRet := mixerOpen(@hMix, 0, 0, 0, 0);
 if intRet = MMSYSERR_NOERROR then
 begin
   mxl.dwComponentType := MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE;
   mxl.cbStruct := SizeOf(mxl);

   // get line info
   intRet := mixerGetLineInfo(hMix, @mxl, MIXER_GETLINEINFOF_COMPONENTTYPE);

   if intRet = MMSYSERR_NOERROR then
   begin
     ZeroMemory(@mxlc, SizeOf(mxlc));
     mxlc.cbStruct := SizeOf(mxlc);
     mxlc.dwLineID := mxl.dwLineID;
     mxlc.dwControlType := MIXERCONTROL_CONTROLTYPE_VOLUME;
     mxlc.cControls := 1;
     mxlc.cbmxctrl := SizeOf(mxc);

     mxlc.pamxctrl := @mxc;
     intRet := mixerGetLineControls(hMix, @mxlc,
       MIXER_GETLINECONTROLSF_ONEBYTYPE);

     if intRet = MMSYSERR_NOERROR then
     begin
       {
        // Microphone Name
           Label1.Caption := mxlc.pamxctrl.szName;

         // Min/Max Volume
         Label2.Caption := IntToStr(mxc.Bounds.dwMinimum) + '->' + IntToStr(mxc.Bounds.dwMaximum);
       }
       ZeroMemory(@mxcd, SizeOf(mxcd));
       mxcd.dwControlID := mxc.dwControlID;
       mxcd.cbStruct := SizeOf(mxcd);
       mxcd.cMultipleItems := 0;
       mxcd.cbDetails := SizeOf(Vol);
       mxcd.paDetails := @vol;
       mxcd.cChannels := 1;

       // vol.dwValue := mxlc.pamxctrl.Bounds.lMinimum; Set min. Volume / Minimum setzen
       // vol.dwValue := mxlc.pamxctrl.Bounds.lMaximum; Set max. Volume / Maximum setzen
       vol.dwValue := bValue;

       intRet := mixerSetControlDetails(hMix, @mxcd,
         MIXER_SETCONTROLDETAILSF_VALUE);
       if intRet <> MMSYSERR_NOERROR then
         ShowMessage('SetControlDetails Error');
     end
     else
       ShowMessage('GetLineInfo Error');
   end;
   intRet := mixerClose(hMix);
 end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
 SetMicrophoneVolume(30000);
end;

{********************************************************}

// Enable/disable "Mute Microphone Volume"
// Ton fur Mikrofon ein/ausschalten

function SetMicrophoneVolumeMute(bMute: Boolean): Boolean;
var
 hMix: HMIXER;
 mxlc: MIXERLINECONTROLS;
 mxcd: TMIXERCONTROLDETAILS;
 vol: TMIXERCONTROLDETAILS_UNSIGNED;
 mxc: MIXERCONTROL;
 mxl: TMixerLine;
 intRet: Integer;
 nMixerDevs: Integer;
 mcdMute: MIXERCONTROLDETAILS_BOOLEAN;
begin
 // Check if Mixer is available
 // Uberprufen, ob ein Mixer vorhanden ist
 nMixerDevs := mixerGetNumDevs();
 if (nMixerDevs < 1) then
 begin
   Exit;
 end;

 // open the mixer
 // Mixer offnen
 intRet := mixerOpen(@hMix, 0, 0, 0, 0);
 if intRet = MMSYSERR_NOERROR then
 begin
   mxl.dwComponentType := MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE;
   mxl.cbStruct := SizeOf(mxl);

   // mixerline info
   intRet := mixerGetLineInfo(hMix, @mxl, MIXER_GETLINEINFOF_COMPONENTTYPE);

   if intRet = MMSYSERR_NOERROR then
   begin
     ZeroMemory(@mxlc, SizeOf(mxlc));
     mxlc.cbStruct := SizeOf(mxlc);
     mxlc.dwLineID := mxl.dwLineID;
     mxlc.dwControlType := MIXERCONTROL_CONTROLTYPE_MUTE;
     mxlc.cControls := 1;
     mxlc.cbmxctrl := SizeOf(mxc);
     mxlc.pamxctrl := @mxc;

     // Get the mute control
     // Mute control ermitteln
     intRet := mixerGetLineControls(hMix, @mxlc,
       MIXER_GETLINECONTROLSF_ONEBYTYPE);

     if intRet = MMSYSERR_NOERROR then
     begin
       ZeroMemory(@mxcd, SizeOf(mxcd));
       mxcd.cbStruct := SizeOf(TMIXERCONTROLDETAILS);
       mxcd.dwControlID := mxc.dwControlID;
       mxcd.cChannels := 1;
       mxcd.cbDetails := SizeOf(MIXERCONTROLDETAILS_BOOLEAN);
       mxcd.paDetails := @mcdMute;

       mcdMute.fValue := Ord(bMute);

       // set, unset mute
       // Stumsschalten ein/aus
       intRet := mixerSetControlDetails(hMix, @mxcd,
         MIXER_SETCONTROLDETAILSF_VALUE);
       {
       mixerGetControlDetails(hMix, @mxcd,
                              MIXER_GETCONTROLDETAILSF_VALUE);
       Result := Boolean(mcdMute.fValue);
       }
       Result := intRet = MMSYSERR_NOERROR;

       if intRet <> MMSYSERR_NOERROR then
         ShowMessage('SetControlDetails Error');
     end
     else
       ShowMessage('GetLineInfo Error');
   end;

   intRet := mixerClose(hMix);
 end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
 SetMicrophoneVolumeMute(False);
end;

{********************************************************}

// Enable/disable "Mute" for several mixer line sources.

uses
 MMSystem;

type
 TMixerLineSourceType = (lsDigital, lsLine, lsMicrophone, lsCompactDisk,
   lsTelephone,
   lsWaveOut, lsAuxiliary, lsAnalog, lsLast);

function SetMixerLineSourceMute(AMixerLineSourceType: TMixerLineSourceType;
 bMute: Boolean): Boolean;
var
 hMix: HMIXER;
 mxlc: MIXERLINECONTROLS;
 mxcd: TMIXERCONTROLDETAILS;
 vol: TMIXERCONTROLDETAILS_UNSIGNED;
 mxc: MIXERCONTROL;
 mxl: TMixerLine;
 intRet: Integer;
 nMixerDevs: Integer;
 mcdMute: MIXERCONTROLDETAILS_BOOLEAN;
begin
 Result := False;
 // Check if Mixer is available
 // Uberprufen, ob ein Mixer vorhanden ist
 nMixerDevs := mixerGetNumDevs();
 if (nMixerDevs < 1) then
 begin
   Exit;
 end;

 // open the mixer
 // Mixer offnen
 intRet := mixerOpen(@hMix, 0, 0, 0, 0);
 if intRet = MMSYSERR_NOERROR then
 begin
   ZeroMemory(@mxl, SizeOf(mxl));
   case AMixerLineSourceType of
     lsDigital: mxl.dwComponentType := MIXERLINE_COMPONENTTYPE_SRC_DIGITAL;
     lsLine: mxl.dwComponentType := MIXERLINE_COMPONENTTYPE_SRC_LINE;
     lsMicrophone: mxl.dwComponentType :=
       MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE;
     lsCompactDisk: mxl.dwComponentType :=
       MIXERLINE_COMPONENTTYPE_SRC_COMPACTDISC;
     lsTelephone: mxl.dwComponentType := MIXERLINE_COMPONENTTYPE_SRC_TELEPHONE;
     lsWaveOut: mxl.dwComponentType := MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT;
     lsAuxiliary: mxl.dwComponentType := MIXERLINE_COMPONENTTYPE_SRC_AUXILIARY;
     lsAnalog: mxl.dwComponentType := MIXERLINE_COMPONENTTYPE_SRC_ANALOG;
     lsLast: mxl.dwComponentType := MIXERLINE_COMPONENTTYPE_SRC_LAST;
   end;

   // mixerline info
   mxl.cbStruct := SizeOf(mxl);
   intRet := mixerGetLineInfo(hMix, @mxl, MIXER_GETLINEINFOF_COMPONENTTYPE);

   if intRet = MMSYSERR_NOERROR then
   begin
     ZeroMemory(@mxlc, SizeOf(mxlc));
     mxlc.cbStruct := SizeOf(mxlc);
     mxlc.dwLineID := mxl.dwLineID;
     mxlc.dwControlType := MIXERCONTROL_CONTROLTYPE_MUTE;
     mxlc.cControls := 1;
     mxlc.cbmxctrl := SizeOf(mxc);
     mxlc.pamxctrl := @mxc;

     // Get the mute control
     // Mute control ermitteln
     intRet := mixerGetLineControls(hMix, @mxlc,
       MIXER_GETLINECONTROLSF_ONEBYTYPE);

     if intRet = MMSYSERR_NOERROR then
     begin
       ZeroMemory(@mxcd, SizeOf(mxcd));
       mxcd.cbStruct := SizeOf(TMIXERCONTROLDETAILS);
       mxcd.dwControlID := mxc.dwControlID;
       mxcd.cChannels := 1;
       mxcd.cbDetails := SizeOf(MIXERCONTROLDETAILS_BOOLEAN);
       mxcd.paDetails := @mcdMute;

       mcdMute.fValue := Ord(bMute);

       // set, unset mute
       // Stumsschalten ein/aus
       intRet := mixerSetControlDetails(hMix, @mxcd,
         MIXER_SETCONTROLDETAILSF_VALUE);
       {
       mixerGetControlDetails(hMix, @mxcd, IXER_GETCONTROLDETAILSF_VALUE);
       Result := Boolean(mcdMute.fValue);
       }
       Result := intRet = MMSYSERR_NOERROR;

       if intRet <> MMSYSERR_NOERROR then
         ShowMessage('SetControlDetails Error');
     end
     else
       ShowMessage('GetLineInfo Error');
   end;
   intRet := mixerClose(hMix);
 end;
end;

// Example Call; Beispielaufruf:

procedure TForm1.Button1Click(Sender: TObject);
begin
 // Ton ausschalten
 SetMixerLineSourceMute(lsLine, True);
end;


Автор: php 10.9.2004, 08:43
Данный код несомненно хорош, но действет только на устройства для воспроизведения
звука (Play Control).
Вопрос, как переделать (или что-то добавить), чтоб действовало на устройсва записи (Record Control).

Автор: Illusion Dolphin 10.9.2004, 17:39
php: Если он годится для одного, то можно переписать на другое... Код кишит всякими константами вроде
Код

MIXER_GETLINEINFOF_COMPONENTTYPE

Думаю, что стоит просто в делфе при нажатой кнопке ctrl кликнуть по константам и посмотреть, какие ещё константы имеются, тогда, я думаю, там будет просто другая константы для твоего случая (обячно по имени можно уже понять, что подходит).

Автор: p0s0l 10.9.2004, 22:13
php:
Цитата
Данный код несомненно хорош, но действет только на устройства для воспроизведения звука (Play Control).

А разве микрофон - устройство воспроизведения ? (хотя можно и так использовать smile.gif)

У меня всё работает:
SetMicrophoneVolume(0..65535) меняет громкость записи с микрофона.
SetMicrophoneVolumeMute(true/false) - выключает/включает микрофон
SetMixerLineSourceMute(lsMicrophone, true/false) - тоже вк./выкл. микрофон
или что тебе надо ?

Автор: Illusion Dolphin 10.9.2004, 22:37
Цитата
А разве микрофон - устройство воспроизведения ? (хотя можно и так использовать )

Как бы да... Посмотри в свойствах громкости, там есть микрофон и для PlayBack и для Recording... Т.е. там нужно просто константы подменить (надо же хоть что-то человеку сделать самому biggrin.gif )...

Автор: p0s0l 11.9.2004, 01:18
Недоглядел - постучал по микрофону, а проверить запись поленился...
Изменить код, как я понял, надо так:
Цитата
function SetMicrophoneVolume(bValue: Word): Boolean;
var {0..65535}
  hMix: HMIXER;
  mxlc: MIXERLINECONTROLS;
  mxcd: TMIXERCONTROLDETAILS;
  vol: TMIXERCONTROLDETAILS_UNSIGNED;
  mxc: MIXERCONTROL;
  mxl: TMixerLine;
  intRet: Integer;
  nMixerDevs: Integer;
begin
  // Check if Mixer is available
  // Uberprufen, ob ein Mixer vorhanden
  nMixerDevs := mixerGetNumDevs();
  if (nMixerDevs < 1) then
  begin
    Exit;
  end;

  // open the mixer
  intRet := mixerOpen(@hMix, 0, 0, 0, 0);
  if intRet = MMSYSERR_NOERROR then
  begin

    mxl.dwComponentType := MIXERLINE_COMPONENTTYPE_DST_WAVEIN;
    mxl.cbStruct := SizeOf(mxl);

    // get line info
    intRet := mixerGetLineInfo(hMix, @mxl, MIXER_GETLINEINFOF_COMPONENTTYPE);

    if intRet = MMSYSERR_NOERROR then
    begin
      for intRet := 0 to mxl.cConnections-1 do
      begin
        mxl.dwSource := intRet;
        mixerGetLineInfo(hMix, @mxl, MIXER_GETLINEINFOF_SOURCE);
        if mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE then Break;
      end;


      ZeroMemory(@mxlc, SizeOf(mxlc));
      mxlc.cbStruct := SizeOf(mxlc);
      mxlc.dwLineID := mxl.dwLineID;
      mxlc.dwControlType := MIXERCONTROL_CONTROLTYPE_VOLUME;
      mxlc.cControls := 1;
      mxlc.cbmxctrl := SizeOf(mxc);

      mxlc.pamxctrl := @mxc;
      intRet := mixerGetLineControls(hMix, @mxlc,
        MIXER_GETLINECONTROLSF_ONEBYTYPE);

      if intRet = MMSYSERR_NOERROR then
      begin
        {
        // Microphone Name
          Label1.Caption := mxlc.pamxctrl.szName;

        // Min/Max Volume
        Label2.Caption := IntToStr(mxc.Bounds.dwMinimum) + '->' + IntToStr(mxc.Bounds.dwMaximum);
      }
        ZeroMemory(@mxcd, SizeOf(mxcd));
        mxcd.dwControlID := mxc.dwControlID;
        mxcd.cbStruct := SizeOf(mxcd);
        mxcd.cMultipleItems := 0;
        mxcd.cbDetails := SizeOf(Vol);
        mxcd.paDetails := @vol;
        mxcd.cChannels := 1;

        // vol.dwValue := mxlc.pamxctrl.Bounds.lMinimum; Set min. Volume / Minimum setzen
        // vol.dwValue := mxlc.pamxctrl.Bounds.lMaximum; Set max. Volume / Maximum setzen
        vol.dwValue := bValue;

        intRet := mixerSetControlDetails(hMix, @mxcd,
          MIXER_SETCONTROLDETAILSF_VALUE);
        if intRet <> MMSYSERR_NOERROR then
          ShowMessage('SetControlDetails Error');
      end
      else
        ShowMessage('GetLineInfo Error');
    end;
    intRet := mixerClose(hMix);
  end;
end;
(изменения - жирным)... Остальные функции думаю также изменяться...

Автор: php 11.9.2004, 19:36
Пробовал подставить выделенные изменения в приведённую ранее функцию
SetMicrophoneVolumeMute(), пишет GetLineInfo Error.

Функция SetMicrophoneVolume отлично работает, но как его включить то программно,
или я что-то не так делаю ?.. sad.gif

Автор: p0s0l 11.9.2004, 20:17
Хмм... Для записи у микрофона нет такого управления, как Mute...

Надо найти переключатель выбора источника записи... Т.е. это включается не в управлении микрофона, а видимо в управлении Recording...
Надо посмотреть...

Автор: php 12.9.2004, 04:27
Пробовал подставлять:
mxl.dwComponentType := MIXERLINE_COMPONENTTYPE_DST_VOICEIN,
но никакого эффекта не даёт..., может с ним что-либо связано?,

Автор: p0s0l 12.9.2004, 21:57
Функция выбора микрофона в качестве источника записи:
Код
function SelectMicrophone : Boolean;
var
 mxlc: MIXERLINECONTROLS;
 mxcd: TMIXERCONTROLDETAILS;
 mxc: MIXERCONTROL;
 mxl: TMixerLine;
 mcdValue : array [0..255] of integer;
 i, Num : byte;

begin
 Result := False;

 mxl.dwComponentType := MIXERLINE_COMPONENTTYPE_DST_WAVEIN;
 mxl.cbStruct := SizeOf(mxl);
 if mixerGetLineInfo(0, @mxl, MIXER_GETLINEINFOF_COMPONENTTYPE) <> MMSYSERR_NOERROR then
 begin
   ShowMessage('GetLineInfo Error');
   Exit;
 end;

 ZeroMemory(@mxlc, SizeOf(mxlc));
 mxlc.cbStruct := SizeOf(mxlc);
 mxlc.dwLineID := mxl.dwLineID;
 mxlc.dwControlType := MIXERCONTROL_CONTROLTYPE_MUX;
 mxlc.cControls := 1;
 mxlc.cbmxctrl := SizeOf(mxc);
 mxlc.pamxctrl := @mxc;

 if mixerGetLineControls(0, @mxlc, MIXER_GETLINECONTROLSF_ONEBYTYPE) <> MMSYSERR_NOERROR then
 begin
   ShowMessage('GetLineControls Error');
   Exit;
 end;

 ZeroMemory(@mxcd, SizeOf(mxcd));
 mxcd.cbStruct := SizeOf(TMIXERCONTROLDETAILS);
 mxcd.dwControlID := mxc.dwControlID;
 mxcd.cChannels := 1;
 mxcd.cMultipleItems := mxc.cMultipleItems;
 mxcd.cbDetails := SizeOf(MIXERCONTROLDETAILS_UNSIGNED);
 mxcd.paDetails := @mcdValue;
 ZeroMemory (@mcdValue, SizeOf(mcdValue));

// узнаём № микрофона
 Num := mxl.cConnections-1;
 for i := 0 to mxl.cConnections-1 do
 begin
   mxl.dwSource := i;
   mixerGetLineInfo(0, @mxl, MIXER_GETLINEINFOF_SOURCE);
   if mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE then Break;
   Dec (Num);
 end;

 mcdValue[Num] := 1;

 if mixerSetControlDetails(0, @mxcd, MIXER_SETCONTROLDETAILSF_VALUE) <> MMSYSERR_NOERROR then
 begin
   ShowMessage('SetControlDetails Error');
   Exit;
 end;

 Result := True;
end;
Только тут странное дело:
Когда делаем mixerSetControlDetails, нужно в массиве mcdValue указать источник записи - нужный элемент массива д.б.=1, остальные элементы д.б. = 0.
Вся проблема в том, чтобы узнать № элемента. У меня получилось так, что №элемента равен "обратному" №источника записи...
Т.е. если у меня у микрофона dwSource=6, то нужно выставлять mcdValue[1] (7-6=1)... Возможно, это только у меня так, возможно - у всех...
Так что проверь, и если не будет работать - посмотри как у тебя соотносятся №источника и №элемента массива...

Автор: php 13.9.2004, 14:01
Да у меня аналогичная ситуация в случае dwSource=6 активируется микрофон,
а вообще в списке устройств он фигурирует у меня под номером 3, потом проверю у других..

Ну, а так всё работает Grand Thanks..!! smile.gif

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)