2010-06-11 13 views
7

Öncelikle, daha önce gönderildiği gibi birkaç soru olduğunu biliyorum; Ancak, , sorunu yeterince ele almıyorlar. Ben waveXXX API ile konuşmak için tüm pInvoke kancaları ile bir C# uygulaması var ve bu ile ses yakalamak ve oynamak mümkün. Ayrıca, bu API ile hoparlör (WaveOut) ses düzeyini ayarlayabiliyorum.
Sorun, nedeni ne olursa olsun, bu API'nin mikrofon (WaveIn) birimini ayarlamasına izin vermez. Bu yüzden çektiğim mikser kodunu ve pInvoke üzerinden erişimini bulmayı başardım ve bu da mikrofonun ses seviyesini ayarlamamı sağladı, ancak sadece W7 PC'mde. Başladığım mikser kodu buradan gelir: http://social.msdn.microsoft.com/Forums/en-US/isvvba/thread/05dc2d35-1d45-4837-8e16-562ee919da85 ve çalışır, ancak hoparlör sesini ayarlamak için yazılmıştır. Ben SetMicVolume yöntemi Burada gösterilen ...C# 'dan mikrofon kazanımı nasıl ayarlanır (XP ve W7 üzerinde çalışılması gerekir)

public static void SetMicVolume(int mxid, int percentage) 
    { 
     bool rc; 
     int mixer, vVolume; 
     MIXERCONTROL volCtrl = new MIXERCONTROL(); 
     int currentVol; 
     mixerOpen(out mixer, mxid, 0, 0, MIXER_OBJECTF_WAVEIN); 
     int type = MIXERCONTROL_CONTROLTYPE_VOLUME; 
     rc = GetVolumeControl(mixer, MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE, type, out volCtrl, out currentVol); 
     if (rc == false) 
     { 
      mixerClose(mixer); 
      mixerOpen(out mixer, 0, 0, 0, 0); 
      rc = GetVolumeControl(mixer, MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE, type, out volCtrl, out currentVol); 
      if (rc == false)  
       throw new Exception("SetMicVolume/GetVolumeControl() failed"); 
     } 
     vVolume = ((int)((float)(volCtrl.lMaximum - volCtrl.lMinimum)/100.0F) * percentage); 
     rc = SetVolumeControl(mixer, volCtrl, vVolume); 
     if (rc == false) 
      throw new Exception("SetMicVolume/SetVolumeControl() failed"); 
     mixerClose(mixer); 
    } 

Not() GetVolumeControl çağırmak için "ikinci girişim" ekledi. Bu, XP'de, GetVolumeControl'ün ilk çağrısında (bu kod için yukarıdaki siteye bakın) yapıldığı için yapılır, mixerGetLineControlsA() çağrısı MIXERR_INVALCONTROL döndüren XP sistemleriyle başarısız olur. Daha sonra, mixerOpen (out mikser, 0, 0, 0, 0) kullanarak bu ikinci denemede, kod bir hata döndürmez ancak mikrofon kazancı etkilenmez. Not, yukarıda söylediğim gibi, bu W7 üzerinde çalışır (ikinci girişim hiçbir zaman çalıştırılmaz çünkü mixerOpen kullanarak (mikser, mxid, 0, 0, MIXER_OBJECTF_WAVEIN) başarısız olur.

Mikser API'sı üzerinde iyi bir kavrayış olmadığını kabul ediyorum; Ancak, bunun neden W7 üzerinde çalışacağına dair bir ipucu varsa, ama XP değil, bunu duymak isterim. Bu arada, ben bir yanıt almak önce ben anlamaya varsa, ben kendi cevap yazacağım ben ...

cevap

1

Aşağıdaki kodu (6/29/2010 güncellenir) Artık benim için Tamam çalışmak gibi ile sona erdi budur

. Test durumlarımın iki PC'mden biri, diğeri XP, diğeri ise XP olduğunu unutmayın, bu yüzden kesin değil. Bunun tüm makineler için işe yaramadığını doğruladım, ancak yaptıkları için iyi görünüyor. Temel fark yerine 'MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE' arasında 'MIXERLINE_COMPONENTTYPE_DST_WAVEIN' bir bileşeni türünü kullanıyorum o olduğunu

public static bool setMicVolume(int mxid, int percentage) 
    { 
     if (mixerdisabled) 
      return(false); 

     bool rc; 
     int mixer, vVolume, ctrltype, comptype; 
     MIXERCONTROL volCtrl = new MIXERCONTROL(); 
     int currentVol; 
     int mr = mixerOpen(out mixer, mxid, 0, 0, MIXER_OBJECTF_WAVEIN); 
     if (mr != MMSYSERR_NOERROR) 
     { 
      Warning("mixerOpen() failed: " + mr.ToString()); 
      mixerdisabled = true; 
      return(false); 
     } 
     ctrltype = MIXERCONTROL_CONTROLTYPE_VOLUME; 
     comptype = MIXERLINE_COMPONENTTYPE_DST_WAVEIN; 
     rc = GetVolumeControl(mixer, comptype, ctrltype, out volCtrl, out currentVol); 
     if (rc == false) 
     { 
      Warning("SetMicVolume/GetVolumeControl() failed"); 
      mixerdisabled = true; 
      mixerClose(mixer); 
      return(false); 
     } 
     vVolume = ((int)((float)(volCtrl.lMaximum - volCtrl.lMinimum)/100.0F) * percentage); 
     rc = SetVolumeControl(mixer, volCtrl, vVolume); 
     if (rc == false) 
     { 
      Warning("SetMicVolume/SetVolumeControl() failed"); 
      mixerdisabled = true; 
      mixerClose(mixer); 
      return (false); 
     } 
     mixerClose(mixer); 
     return (true); 
    } 

dikkat edin. Bunu gerçekten anlamayın, bu yüzden eğer birisi bir açıklama yapmak isterse (ya da bunun genel olarak işe yaramayacağını söylerse), cevapları karşılıyorum!

+0

Bu işlemin başarısız olduğu bir XP makinesine sahip olduğumu unutmayın, bu yüzden hala mükemmel değil ... –

+0

Kodunuzda int mxid nedir? Nasıl alınır? –

1

Tam olarak bunu bir süre önce NAudio kullanarak .NET Voice Recorder yazarken denedim ve son derece zor buldum. Muhtemelen iki çok kod yazmanız gerekiyor, bir tane XP ve bir tanesi Vista/Win 7 için. Mikser interop için NAudio kullanıyorum. Bu benim (hala her yerde çalışmıyor)

private void TryGetVolumeControl() 
    { 
     int waveInDeviceNumber = waveIn.DeviceNumber; 
     if (Environment.OSVersion.Version.Major >= 6) // Vista and over 
     { 
      var mixerLine = new MixerLine((IntPtr)waveInDeviceNumber, 0, MixerFlags.WaveIn); 
      foreach (var control in mixerLine.Controls) 
      { 
       if (control.ControlType == MixerControlType.Volume) 
       { 
        volumeControl = control as UnsignedMixerControl; 
        MicrophoneLevel = desiredVolume; 
        break; 
       } 
      } 
     } 
     else 
     { 
      var mixer = new Mixer(waveInDeviceNumber); 
      foreach (var destination in mixer.Destinations) 
      { 
       if (destination.ComponentType == MixerLineComponentType.DestinationWaveIn) 
       { 
        foreach (var source in destination.Sources) 
        { 
         if (source.ComponentType == MixerLineComponentType.SourceMicrophone) 
         { 
          foreach (var control in source.Controls) 
          { 
           if (control.ControlType == MixerControlType.Volume) 
           { 
            volumeControl = control as UnsignedMixerControl; 
            MicrophoneLevel = desiredVolume; 
            break; 
           } 
          } 
         } 
        } 
       } 
      } 
     } 

    } 
+0

Mark, hızlı yanıt için teşekkürler. Bundan önce NAudio'yu duymamıştım (ki bu son birkaç aydır beni şaşırtıyor çünkü bilgisayardaki çeşitli ses sorunları için çok fazla "googling" yapıyorum). Oldukça olgun görünüyor. Buna bir bakacağım; Ancak, sadece temel mikser API'sini kullanarak bir çözüm bulmayı çok isterim, böylece sadece mikrofon-ses kontrolünü yapmak için büyük bir pakette çekmekten kaçınırım. –

+0

Mark, NAudio paketini geziyorum (gerçekten temiz görünüyor); ama ben mixerOpen() için herhangi bir çağrı göremiyorum. Bu gözlem doğruysa, mikser mikseri nasıl kullanır? –

+0

, üzerindeki denetimleri değiştirmek için mikseri açmanıza gerek yoktur. –