簡體   English   中英

如何使用minim庫為左右聲道制作兩個FFT對象進行處理

[英]how to make two FFT objects for the left and right channel with the minim library for processing

我有以下代碼從音頻文件創建一個 FFT 對象,請參閱下面的代碼:

import ddf.minim.*;
import ddf.minim.analysis.*;

Minim       minim;
AudioPlayer player;
FFT         fft;


void setup(){
  minim = new Minim(this);
  player = minim.loadFile("audio.mp3");
  fft = new FFT( player.bufferSize(), player.sampleRate() ); 
  fft.logAverages(86, 1); 
  fft.window(FFT.HAMMING);
  numZones = fft.avgSize();
}

但是現在我想為左右聲道創建兩個 FFT 對象。 所以最后我想要一個 fftLeft = new FFT(audio.left) 和一個 fftRight = new FFT(audio.right)

我已經嘗試過.getChannel(player.LEFT)方法,但這沒有用。 有沒有人有關於如何做到這一點的提示或建議?

當您運行 FFT 的forward()方法時,您可以傳遞所需的通道。

像這樣的東西:

//in setup()
fftLeft  = new FFT( player.bufferSize(), player.sampleRate() );
fftRight = new FFT( player.bufferSize(), player.sampleRate() );
//in draw()
fftLeft.forward(player.left);
fftRight.forward(player.right);

這是帶有 minim 的 SoundSpectrum 示例的調整版本:

/**
  * An FFT object is used to convert an audio signal into its frequency domain representation. This representation
  * lets you see how much of each frequency is contained in an audio signal. Sometimes you might not want to 
  * work with the entire spectrum, so it's possible to have the FFT object calculate average frequency bands by 
  * simply averaging the values of adjacent frequency bands in the full spectrum. There are two different ways 
  * these can be calculated: <b>Linearly</b>, by grouping equal numbers of adjacent frequency bands, or 
  * <b>Logarithmically</b>, by grouping frequency bands by <i>octave</i>, which is more akin to how humans hear sound.
  * <br/>
  * This sketch illustrates the difference between viewing the full spectrum, 
  * linearly spaced averaged bands, and logarithmically spaced averaged bands.
  * <p>
  * From top to bottom:
  * <ul>
  *  <li>The full spectrum.</li>
  *  <li>The spectrum grouped into 30 linearly spaced averages.</li>
  *  <li>The spectrum grouped logarithmically into 10 octaves, each split into 3 bands.</li>
  * </ul>
  *
  * Moving the mouse across the sketch will highlight a band in each spectrum and display what the center 
  * frequency of that band is. The averaged bands are drawn so that they line up with full spectrum bands they 
  * are averages of. In this way, you can clearly see how logarithmic averages differ from linear averages.
  * <p>
  * For more information about Minim and additional features, visit http://code.compartmental.net/minim/
  */

import ddf.minim.analysis.*;
import ddf.minim.*;

Minim minim;  
AudioPlayer jingle;

FFT fftLogLeft,fftLogRight;

float height3;
float height23;
float spectrumScale = 4;

float centerFrequency;

PFont font;

void setup()
{
  size(512, 480);
  height3 = height/3;
  height23 = 2*height/3;

  minim = new Minim(this);
  jingle = minim.loadFile("jingle.mp3", 1024);

  // loop the file
  jingle.loop();

  // create an FFT object for calculating logarithmically spaced averages
  // left channel
  fftLogLeft = new FFT( jingle.bufferSize(), jingle.sampleRate() );
  fftLogLeft.logAverages( 22, 3 );

  fftLogRight = new FFT( jingle.bufferSize(), jingle.sampleRate() );
  fftLogRight.logAverages( 22, 3 );

  rectMode(CORNERS);
}

void draw()
{
  background(0);
  //run FFT on left channel
  fftLogLeft.forward( jingle.left );
  //run FFT on left channel
  fftLogRight.forward( jingle.right );

  plotFFT(fftLogLeft,height-50,"Left Channel");
  plotFFT(fftLogRight,height,"Right Channel");
}

void plotFFT(FFT fft,float y,String prefix){
  // draw the logarithmic averages
  {
    // since logarithmically spaced averages are not equally spaced
    // we can't precompute the width for all averages
    for(int i = 0; i < fft.avgSize(); i++)
    {
      centerFrequency    = fft.getAverageCenterFrequency(i);
      // how wide is this average in Hz?
      float averageWidth = fft.getAverageBandWidth(i);   

      // we calculate the lowest and highest frequencies
      // contained in this average using the center frequency
      // and bandwidth of this average.
      float lowFreq  = centerFrequency - averageWidth/2;
      float highFreq = centerFrequency + averageWidth/2;

      // freqToIndex converts a frequency in Hz to a spectrum band index
      // that can be passed to getBand. in this case, we simply use the 
      // index as coordinates for the rectangle we draw to represent
      // the average.
      int xl = (int)fft.freqToIndex(lowFreq);
      int xr = (int)fft.freqToIndex(highFreq);

      // if the mouse is inside of this average's rectangle
      // print the center frequency and set the fill color to red
      if ( mouseX >= xl && mouseX < xr )
      {
        fill(255, 128);
        text(prefix + "Logarithmic Average Center Frequency: " + centerFrequency, 5, y - 25);
        fill(255, 0, 0);
      }
      else
      {
          fill(255);
      }
      // draw a rectangle for each average, multiply the value by spectrumScale so we can see it better
      rect( xl, y, xr, y - fft.getAvg(i)*spectrumScale );
    }
  }
}

筆記:

  • 在運行之前,您需要將 .mp3 文件拖放到草圖上。 將其命名為“jingle.mp3”或更改對loadFile()的調用以使用正確的文件名
  • 我以對數平均值為例。 與線性或根本沒有平均值相比,它們對於可視化更有用。 有關處理中聲音可視化的 FFT 的更多有用提示,請參閱此答案和哥倫比亞大學教授的Dan Ellis 音樂信號處理課程(因為一些實踐是使用 Processing 的 minim 庫)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM