2016-01-10 27 views
7

Tôi đang làm việc trên một dự án IoT winodws điều khiển dải dẫn dựa trên đầu vào âm thanh. Bây giờ tôi có một số mã được âm thanh trong và viết nó vào một bộ đệm với API AudioGraph, nhưng tôi không biết làm thế nào tôi có thể xử lý âm thanh cho một số dữ liệu hữu ích.xử lý âm thanh uwp âm thanh uwp

mã của tôi cho đến nay:

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; 


     } 
    } 

Vì vậy, tôi kết thúc với đệm của tôi như là một phao. Nhưng làm thế nào tôi có thể thay đổi điều này thành dữ liệu hữu ích mà làm cho nó có thể tạo ra một cái gì đó giống như một máy phân tích phổ?

Edit:

Có lẽ tôi phải đưa ra câu hỏi này ít cụ thể hơn cho các máy không ảnh. Tôi sử dụng một API để có được đầu vào âm thanh của tôi. Dữ liệu tôi nhận được từ API là một byte * và tôi có thể truyền nó thành một float * Làm thế nào tôi có thể thay đổi nó từ byte * hoặc float * sang một số dữ liệu khác mà tôi có thể sử dụng để tạo một số mã màu.

Tôi thaught về làm một số phân tích FFT trên phao * để có được 164 led * 3 (rgb) = 492 thùng. Và xử lý dữ liệu này xa hơn để nhận được một số giá trị từ 0 đến 255.

Vậy làm cách nào để xử lý phao * hoặc byte * này để nhận dữ liệu hữu ích này? Hoặc làm thế nào để tôi bắt đầu?

+0

Bạn có thể xem https://github.com/filoe/cscore, có một mẫu được bao gồm (xem hình bên dưới) –

Trả lời

10

Dữ liệu đó là xen kẽ IEEE float, vì vậy nó thay thế dữ liệu kênh khi bạn duyệt qua mảng và phạm vi dữ liệu cho mỗi mẫu là từ -1 đến 1. Ví dụ: tín hiệu đơn âm chỉ có một kênh nó sẽ không xen kẽ dữ liệu; nhưng một tín hiệu âm thanh stereo có hai kênh âm thanh, và như vậy:

dataInFloat[0] 

là mẫu đầu tiên của dữ liệu từ các kênh trái và

dataInFloat[1] 

là mẫu đầu tiên của dữ liệu từ cầu môn bên mình. Sau đó,

dataInFloat[2] 

là mẫu giây mẫu dữ liệu từ kênh bên trái. và họ cứ tiếp tục đi qua lại. Tất cả dữ liệu khác mà bạn sẽ chỉ quan tâm là trong windows.media.mediaproperties.audioencodingproperties

Vì vậy, chỉ cần biết điều này, bạn (về bản chất) có thể ngay lập tức nhận được khối lượng tổng thể của tín hiệu trực tiếp từ dữ liệu này bằng cách xem giá trị tuyệt đối của mỗi mẫu. Bạn chắc chắn sẽ muốn trung bình nó ra trong một số lượng thời gian. Bạn thậm chí có thể gắn các hiệu ứng EQ vào các nút khác nhau và tạo các nút Low, Mids và High phân tích riêng biệt và thậm chí không bao giờ vào được các công cụ FFT. NHƯNG CAI ĐO CO GI VUI? (nó thực sự vẫn vui)

Và sau đó, vâng, để có được dữ liệu hài hòa phức tạp của bạn và làm cho một visualizer thực sự ngọt ngào, bạn muốn làm một FFT trên đó. Mọi người thích sử dụng AForge để biết các tình huống học tập, như kịch bản của bạn. Xem Nguồn/Imaging/ComplexImage.cs để sử dụng, Nguồn/Math/FourierTransform.cs để thực hiện

Sau đó, bạn có thể dễ dàng lấy dữ liệu thùng cổ điển và thực hiện công cụ visualizer âm nhạc cổ điển hoặc nhận thêm creative hoặc bất kỳ thứ gì! công nghệ tuyệt vời!

+0

Cảm ơn!Tôi vẫn còn một số câu hỏi. Tôi có phần lớn thời gian đệm là 3840 trong khung thời gian là 0,01 giây, do đó, điều này có nghĩa là (3840/sizeof (float))/2 rằng các kênh bên trái và bên phải của tôi có chiều dài 480 phao. Thê nay đung không? Các giá trị mã hóa của biểu đồ của tôi là tốc độ bit là 3072000, bit/mẫu 32, lấy mẫu 48000 –

+0

Bạn chính xác! Lưu ý rằng phạm vi dữ liệu là [-1, + 1], vì vậy nếu bạn xem xét giá trị trung bình của giá trị ABSOLUTE của dữ liệu đó, bạn sẽ nhận được ước tính sơ bộ về khối lượng. Nhưng tôi thực sự bạn nên chuyển nó sang FFT để lấy lại các giá trị dữ liệu thực sự, nhưng thủ thuật biên độ (giá trị float tuyệt đối trung bình) hoạt động tốt cho một cách nhanh chóng-n-dơ bẩn phân tích và ít tốn kém hơn nhiều CPU. Tôi làm tất cả các thời gian nếu tôi chỉ có một điều bên ngoài tôi muốn kích hoạt từ âm nhạc (một ánh sáng, một động cơ, điện thoại rung, vv ...) – andymule

+0

Được rồi, Nice! Vì vậy, bây giờ tôi tạo ra một mảng phức tạp với phần thực sự các giá trị của âm thanh bên trái (Chẳng hạn như một hammingwindow cần thiết?) Và phần phức tạp sẽ là 0 (Luôn luôn 0 cho âm thanh phải không?). Và nếu mảng đó có chiều dài là 2^n thì tôi ném nó qua FFT và sẽ trả về tần số so với thời gian. Và điều tôi mong đợi là nửa thứ hai cũng giống như phần thứ nhất. Nhưng nó không phải là: (Vì vậy, nó là đúng những gì tôi đang suy nghĩ và làm? –

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);