2017-08-07 4 views
1

私は4チャンネルシステムの特定のスピーカーに特定のオーディオ信号を送る必要があるNAudioのC#プロジェクトに取り組んでいます。基本的には、フロント左のスピーカーには「環境音」、フロント右のスピーカーには「フロントパネルの表示音」、フロントの左スピーカーには「事前に録音された指示」を送る必要があります。 私のデスクトップコンピュータがサポートしている2チャンネルセットアップでは私の現在のデザインが動作しますが、テストハードウェア上で4チャンネルに拡張しようとすると、「値が期待値の範囲内に収まらない」というエラーが発生します。 WasapiOut.init()を呼び出すと私は問題がMultiplexingSampleProviderによって何らかの形で引き起こされたと思いますが、問題を解決する理由/方法を理解することはできません。私はそれをロードしようとする前に私が使用しているAudioDeviceが十分なチャンネルをサポートしていることを確認します。したがって、問題の原因となるチャンネルの不足ではありません。ここでMultiplexingSampleProviderとWasapiOutを持つNAudio

は、問題の原因となるコードです:

// Create mixer provider for each channel. 
for(int Count = 0; Count < Channels; Count++) 
{ 
    _Mixers.Add(new MixingSampleProvider(_Format.AsStandardWaveFormat())); 
    _Mixers[Count].MixerInputEnded += SoundEndedEvent; 
} 

// Create and configure multiplexer provider. 
_Multi = new MultiplexingSampleProvider(_Mixers, Channels); 
for(int count = 0; count < Channels; count++) 
{ 
    _Multi.ConnectInputToOutput(count, 0); 
} 

// Add master volume control provider. 
_Volume = new VolumeSampleProvider(_Multi); 
_Volume.Volume = 1.0f; 

// Initialize output device. 
_OutputDev.Init(p_Volume); 

_formatは設定44.1kHzで、32ビット、1つのチャネルとWAVEFORMATEXTENSIBLEクラスです。

私は_OutputDev.Init(p_Volume)を呼び出すまで動作しますが、これは '値が期待値の範囲内に収まらない'ということです。例外。

この例外が発生する理由とその解決方法を教えてください。

ありがとうございます。

編集

これは私が取得していますスタックトレースです。

System.ArgumentException: Value does not fall within the expected range. at System.Runtime.InteropServices.Marshal.ThrowExceptionForHRInternal(Int32 errorCode, IntPtr errorInfo) at NAudio.Wave.WasapiOut.Init(IWaveProvider waveProvider) at NAudio.Wave.WaveExtensionMethods.Init(IWavePlayer wavePlayer, ISampleProvider sampleProvider, Boolean convertTo16Bit) at GSound.Audio.Player..ctor(Int32 Channels, Int32 Device) in E:\Dev\GSound_Wasapi\Projects\GSound\Audio\Player.cs:line 220 at GSound.Audio.Handler..ctor(Config TheConfig) in E:\Dev\GSound_Wasapi\Projects\GSound\Audio\Handler.cs:line 78 at GSound.UIData..ctor() in E:\Dev\GSound_Wasapi\Projects\GSound\UIData.cs:line 63

私は問題がE_INVALIDARGエラーを生成しているAudioClient.Initializeコール、で起こっていると思います。これは、WasapiOutで生成されたフォーマット値の問題か、クライアントのプロパティに関する問題のいずれかを示します。私は両方の問題を調べるつもりですが、どんな指針が役に立つでしょう。

もう一度ありがとうございます。

私は1つのシステム上で動作する4チャンネルオーディオを得ている
+0

WASAPIデバイスでは、必ずしもマルチチャンネル音声(2チャンネル以上)で開くことができません。私は確かに自分自身を達成するために管理していない。 ASIO –

+0

興味深いので、選択したデバイスがMMDevice.Propertiesを介して示しても、PKEY_AudioEndPoint_PhysicalSpeakersは4つのスピーカーをマスクしており、実際にはアクセスできません.ASIOドライバを取得できるかどうかを確認する必要があります私たちが使用しているサウンドカード用です。 Wasapiに関してもっと知ろうとするだけでなく、それがちょっと変わったように思えます。 – JonDemers

答えて

0

は(さらに別のシステム上でテストする必要がありますが、なぜそれはしません表示されません。)以下の調整が行われた

MultiplexingSampleProviderを削除し、独自のSampleProviderを変更して、希望のチャンネルに信号データをコピーし、他のチャンネルに0データをコピーするだけで、複数のチャンネル出力を処理しました。問題の1つは、MultiplexingSampleProviderが、入力サンプルプロバイダのチャネル数を含むその出力用の入力サンプルプロバイダ波形を使用することです。元のカスタムサンプルプロバイダはモノラルチャンネルだったので、マルチプレクサは4チャンネルで使用しようとするとエラーになります。私はマルチプレクサを、入力フォーマットと同じで、コンストラクタを介して設定されたチャンネル番号を使用して、代わりに独自の波形を使用するように書き換えることがどれほど難しいのだろうかと思います。

MultiplexingSampleProviderなどWasapiOutクラスの別の問題は、彼らはWAVEFORMATEXTENSIBLEクラスを処理していないということですが、私はWaveFormat.Encodingはタイプ拡張(サブフォーマットMEDIASUBTYPE_IEEE_FLOAT)であることを可能にするためにMixingSampleProviderとSampleToWaveProviderクラスを修正することになりましたIeeeFloatなどがあります。

/// <summary> 
/// Creates a new MixingSampleProvider, with no inputs, but a specified WaveFormat 
/// </summary> 
/// <param name="waveFormat">The WaveFormat of this mixer. All inputs must be in this format</param> 
public MixingSampleProvider(WaveFormat waveFormat) 
{ 
    if(waveFormat.Encoding == WaveFormatEncoding.Extensible) 
    { 
     if(((WaveFormatExtensible)waveFormat).SubFormat != NAudio.Dmo.AudioMediaSubtypes.MEDIASUBTYPE_IEEE_FLOAT) 
     { 
      throw new ArgumentException("Must be already floating point"); 
     } 
    } 
    else if(waveFormat.Encoding != WaveFormatEncoding.IeeeFloat) 
    { 
     throw new ArgumentException("Mixer wave format must be IEEE float"); 
    } 
    sources = new List<ISampleProvider>(); 
    WaveFormat = waveFormat; 
} 

最後に、WaveFormatExtensibleにプロパティを追加して、dwChannelMask設定を設定できるようにしました。この設定はシステムに実際に出力に使用するスピーカーを示します。私の場合は0x33(FL、FR、RL、RRスピーカー)です。通常のWaveFormatExtensibleコンストラクタでは、dwChannelMaskは0x7(FL、FR、FC、LowFreqスピーカー)に設定されると想定しています。これは最初の4つのスピーカー値です。 dwChannelMaskを設定することで、使用するスピーカーを指定することができます。

/// <summary>Gets or sets the channel mask.</summary> 
/// <value>The channel mask.</value> 
public int ChannelMask 
{ 
    get 
    { 
     return dwChannelMask; 
    } 
    set 
    { 
     dwChannelMask = value; 
    } 
} 

これは、オーディオとオーディオのコーデックを扱う際の非常に興味深い教訓です。

他人に役立つことを願っています。

もう一度ありがとうございます。