2016-01-10 33 views
7

私はオーディオ入力に基づいてledストリップを制御するwinodws IoTプロジェクトに取り組んでいます。オーディオを取得してAudioGraph APIを使ってバッファに書き込むコードをいくつか用意していますが、オーディオを処理して有用なデータにする方法がわかりません。uwp AudioGraphオーディオ処理

私のコード今のところ:

private async void MainPage_Loaded(object sender, RoutedEventArgs eventArgs) 
{ 
     try 
     { 
      // Initialize the led strip 
      //await this.pixelStrip.Begin(); 

      sampleAggregator.FftCalculated += new EventHandler<FftEventArgs>(FftCalculated); 
      sampleAggregator.PerformFFT = true; 

      // Create graph 
      AudioGraphSettings settings = new AudioGraphSettings(AudioRenderCategory.Media); 
      settings.DesiredSamplesPerQuantum = fftLength; 
      settings.DesiredRenderDeviceAudioProcessing = Windows.Media.AudioProcessing.Default; 
      settings.QuantumSizeSelectionMode = QuantumSizeSelectionMode.ClosestToDesired; 

      CreateAudioGraphResult result = await AudioGraph.CreateAsync(settings); 
      if (result.Status != AudioGraphCreationStatus.Success) 
      { 
       // Cannot create graph 
       return; 
      } 
      graph = result.Graph; 

      // Create a device input node using the default audio input device 
      CreateAudioDeviceInputNodeResult deviceInputNodeResult = await graph.CreateDeviceInputNodeAsync(MediaCategory.Other); 

      if (deviceInputNodeResult.Status != AudioDeviceNodeCreationStatus.Success) 
      { 
       return; 
      } 

      deviceInputNode = deviceInputNodeResult.DeviceInputNode; 

      frameOutputNode = graph.CreateFrameOutputNode(); 
      frameOutputNode.Start(); 
      graph.QuantumProcessed += AudioGraph_QuantumProcessed; 

      // Because we are using lowest latency setting, we need to handle device disconnection errors 
      graph.UnrecoverableErrorOccurred += Graph_UnrecoverableErrorOccurred; 

      graph.Start(); 
     } 
     catch (Exception e) 
     { 
      Debug.WriteLine(e.ToString()); 
     } 
    } 

    private void AudioGraph_QuantumProcessed(AudioGraph sender, object args) 
    { 
     AudioFrame frame = frameOutputNode.GetFrame(); 
     ProcessFrameOutput(frame); 
    } 

    unsafe private void ProcessFrameOutput(AudioFrame frame) 
    { 
     using (AudioBuffer buffer = frame.LockBuffer(AudioBufferAccessMode.Write)) 
     using (IMemoryBufferReference reference = buffer.CreateReference()) 
     { 
      byte* dataInBytes; 
      uint capacityInBytes; 
      float* dataInFloat; 

      // Get the buffer from the AudioFrame 
      ((IMemoryBufferByteAccess)reference).GetBuffer(out dataInBytes, out capacityInBytes); 

      dataInFloat = (float*)dataInBytes; 


     } 
    } 

だから私はfloat型としての私のバッファーで終わります。しかし、これをスペクトルアナライザのようなものを作ることを可能にする有用なデータに変更するにはどうすればよいですか?

編集:

たぶん私はaudiographのため、この質問は、以下の特定のようにする必要があります。私は、私のオーディオ入力を得るためにAPIを使用します。 APIから取得するデータは1バイトで、フロートにキャストすることができます。*バイト*またはフロート*から、いくつかのカラーコードを作成するために使用できる他のデータに変更できますか?

私はフロート*でいくつかのFFT解析を行い、164個のLED * 3(rgb)= 492個のビンを得ることを教えました。このデータをさらに処理して、0から255の間の値を取得します。

このフロート*またはバイト*を処理してこの有用なデータを取得するにはどうすればよいですか?または私はどのように始めますか?

+0

あなたはhttps://github.com/filoe/cscoreを見ても、サンプルがあるが –

答えて

10

このデータはインターリーブされているので、配列をステップ実行するときにチャネルデータが交互になり、各サンプルのデータ範囲は-1〜1です。 たとえば、モノラル信号には1つのチャネルしかないためデータを全くインターリーブしません。しかし、ステレオ信号は、オーディオの2つのチャネルを有し、従って:

dataInFloat[0] 

は左チャンネルからのデータの最初のサンプルであると

dataInFloat[1] 

は右チャンネルからのデータの最初のサンプルです。次いで、

dataInFloat[2] 

は左チャンネルからのデータのサンプルです。彼らはちょうど前後に行っています。あなたが気にすることになる他のすべてのデータは、windows.media.mediaproperties.audioencodingpropertiesにあります。

これを知っているだけで、(本質的に)このデータから、各サンプルの絶対値。あなたは間違いなくそれをある程度の時間にわたって平均化したいと思うでしょう。 EQエフェクトを別のノードに接続して、別々のLow、Mids、Highのアナライザノードを作成し、FFTに入ることもありません。それは何ですか?

そして、ええ、あなたの複雑な調和データを取得し、本当に甘いビジュアライザーを作るには、FFTをしたいと思っています。あなたのような学習シナリオでは、AForgeを楽しんでいます。使用のためにはSources/Imaging/ComplexImage.cs、実装のためにはSources/Math/FourierTransform.csをご覧ください。

あなたは簡単に古典的なビンデータを取得し、古典的な音楽ビジュアライザのものをやることができます。技術は素晴らしいです!

+0

感謝を(ダウン下の画像を参照)含まれて!私はまだいくつかの質問があります。ほとんどの場合、フレーム時間0.01秒で3840のバッファ長さがあるので、これは3840/sizeof(float)/ 2で、左右のシャネルの長さは480フロートであることを意味します。これは正しいですか?私のグラフの符号化プロパティは、ビットレート3072000、ビット/サンプル32、サンプラート48000 –

+0

あなたは正しいです! データの範囲は[-1、+ 1]なので、そのデータのABSOLUTE値の平均値を見ると、おおまかな見積もりが得られます。 (私はこの情報で上記の私のポストを改訂しています) 本当にあなたは真のデータ値を得るためにFFTに渡すべきですが、振幅トリック(平均絶対フロート値)はすばやく汚れていますCPU集約度ははるかに低くなります。私は音楽から鳴らしたい外付けのものが1つだけあればいつでもやります(1つのライト、1つのモーター、電話の振動など...) – andymule

+0

よろしくお願いします。ですから、実際の部分に左のオーディオの値(例えば、ハミングウィンドウが必要なのでしょうか?)の複雑な配列を作成し、複雑な部分は0になります(オーディオの場合は常に0です)。そして、その配列が2^nの長さであれば、それをFFTに渡し、周波数と時間を返します。私が期待するのは、後半は最初の部分と同じです。しかし、そうではありません:(それで、私は思っていて、何をやっているのですか? –

0
dataInFloat = (float*)dataInBytes; 
    float max = 0; 
    for (int i = 0; i < graph.SamplesPerQuantum; i++) 
       { 
        max = Math.Max(Math.Abs(dataInFloat[i]), max); 

       } 

       finalLevel = max; 
       Debug.WriteLine(max); 
関連する問題