2016-01-10 4 views
7

Я работаю над проектом IoT winodws, который управляет светодиодной полосой на основе аудиовхода. Теперь у меня есть код, который получает аудио и записывает его в буфер с помощью API AudioGraph, но я не знаю, как я могу обрабатывать аудио для некоторых полезных данных.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; 


     } 
    } 

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

Edit:

Может быть, я должен сделать этот вопрос менее специфичен для аудиографа. Я использую API для ввода своего аудиовхода. Данные, которые я получаю из API, являются байтом *, и я могу использовать его для float * Как я могу изменить его из байта * или float * на некоторые другие данные, которые я могу использовать для создания некоторых цветовых кодов.

Я попытался сделать некоторый анализ БПФ на поплавке *, чтобы получить 164 светодиода * 3 (rgb) = 492 бункера. И обработать эти данные дальше, чтобы получить значения от 0 до 255.

Итак, как я могу обработать этот float * или byte *, чтобы получить эти полезные данные? Или как мне начать?

+0

Вы можете посмотреть на https://github.com/filoe/cscore, есть пример включен (см изображение вниз ниже) –

ответ

10

Эти данные чередуются с поплавком IEEE, поэтому он чередует данные канала при прохождении через массив, а диапазон данных для каждого образца составляет от -1 до 1. Например, монофонический сигнал имеет только один канал, поэтому он не будет чередовать данные вообще; но стереофонический сигнал имеет два канал аудио и так:

dataInFloat[0] 

является первой выборкой данных из левого канала и

dataInFloat[1] 

является первой выборкой данных из правого канала. Затем

dataInFloat[2] 

является образцом данных из левого канала второй. и они просто продолжают идти туда и обратно. Все остальные данные, которые вы в конечном итоге заботитесь, находятся в windows.media.mediaproperties.audioencodingproperties

Итак, вы знаете, что вы (по существу) можете сразу получить общий объем сигнала непосредственно из этих данных, посмотрев на абсолютная величина каждого образца. Вы определенно захотите усреднить его в течение некоторого времени. Вы даже можете просто прикрепить эффекты EQ к различным узлам и сделать отдельные узлы Low, Mids и High Analyzer и даже не попасть в FFT-материал. НО ЧТО ЭТО? (на самом деле все еще весело)

А потом, чтобы получить ваши сложные гармонические данные и сделать по-настоящему сладкий визуализатор, вы хотите сделать БПФ на нем. Людям нравится использовать AForge для изучения сценариев, таких как ваши. См. «Источники/изображения/ComplexImage.cs для использования», «Источники/Математика/FourierTransform.cs» для реализации

Затем вы можете легко получить свои классические данные о бинах и сделать классический материал визуализатора музыки или получить больше creative или что угодно! технология потрясающая!

+0

Спасибо!У меня все еще есть некоторые вопросы. У меня в большинстве случаев длина буфера 3840 во время кадра 0,01 секунды, поэтому это означает (3840/sizeof (float))/2, что мои левая и правая чаны имеют длину 480 поплавков. Это правильно? Кодирование свойств моего графика битрейт 3072000, бит/образец 32, выборка 48000 –

+0

Вы верны! Обратите внимание, что диапазон данных равен [-1, + 1], поэтому, если вы посмотрите на среднее значение ABSOLUTE этих данных, вы получите приблизительную оценку громкости. (Я тоже пересматриваю свой пост выше этой информации) Но на самом деле вы должны передать это FFT для получения истинных значений данных назад, но амплитудный трюк (среднее абсолютное значение поплавка) отлично работает для быстрого n-грязного анализа и значительно меньше интенсивность процессора. Я делаю это все время, если у меня есть только одна внешняя вещь, которую я хочу вызвать из музыки (один свет, один двигатель, вибрация телефона и т. Д.). – andymule

+0

Хорошо, Ницца! Итак, теперь я создаю сложный массив с реальной частью значений левого аудио (например, что-то вроде hammingwindow?), А сложная часть будет равна 0 (всегда 0 для звука справа?). И если этот массив является длиной 2^n, я бросаю его через БПФ и возвращу частоту против времени. И тогда я ожидаю, что вторая половина такая же, как и первая часть. Но это не так :(Итак, правильно ли, что я думаю и делаю? –

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); 
Смежные вопросы