首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >处理Minim中的逆FFT

处理Minim中的逆FFT
EN

Stack Overflow用户
提问于 2021-12-17 18:21:27
回答 1查看 105关注 0票数 0

我试图输出我的电脑麦克风输入到扬声器输出在处理过程中使用Minim。该项目的目的是分析输入(麦克风、声音文件等),对其频谱进行一些修改,最后将其输出到扬声器或保存在文件中(我仍然不知道如何实现最后一个功能)。

我在这个帖子https://forum.processing.org/beta/num_1256413038.html中提到了mots的答案,但我不能让它发挥作用:没有任何东西是通过扬声器播放的。

这是我使用的代码:

代码语言:javascript
复制
import ddf.minim.*;
import ddf.minim.analysis.*;


private FFT fftIn, fftOut;
private AudioInput input;
private AudioOutput output;
private Minim minim;

void setup() {
  size(300, 200);

  minim = new Minim(this);

  input = minim.getLineIn();
  input.addListener(new Listener());

  output = minim.getLineOut();
  output.addSignal(new Signal());
  
  fftOut = fftIn = new FFT(input.bufferSize(), input.sampleRate());
}

class Listener implements AudioListener {
  public void  samples(float[] sample) {
    fftIn.forward(sample);
  }
  public void samples(float[] left, float[] right) {
    samples(left);
  }
}


private class Signal implements AudioSignal {
  public void generate(float[] sample) {
    boolean mode = false;
    
    if (mode) {
      fftIn.inverse(sample);
    } else {
      for (int i = 0; i < input.bufferSize() / 2; i++) {
        fftOut.setBand(i, fftIn.getBand(i));
      }                
      fftOut.inverse(sample);
    }
  }

  public void generate(float[] left, float[] right) {
    generate(right);
  }
}

编辑2021年12月31日

这是我写下的代码:它运行时没有任何错误,但正如你在OUT部分看到的,沿着整个频谱的许多频率都会产生噪声,并对输出产生噪声。我认为这是由样品之间的不连续引起的。

守则:

代码语言:javascript
复制
import ddf.minim.*;
import ddf.minim.analysis.*;


Minim minim;
AudioInput mic;
AudioOutput out;
FFT drawfft, testfft;

PGraphics IN, OUT;

float scale = 8, barWidth;


public void settings() {
  size(1200, 960);
}

void setup() {
  surface.setResizable(false);

  init();
  
  IN = createGraphics(1200, 480);
  OUT = createGraphics(1200, 480);
}

void draw() {
  drawSpectrum(IN, -1);
  image(IN, 0, 0);
  drawSpectrum(OUT, 1);
  image(OUT, 0, height - OUT.height);
}

void drawSpectrum(PGraphics pg, int channel) {
  if(channel == -1) drawfft.forward(mic.mix);
  else if(channel == 1) drawfft.forward(out.mix);
  
  int W = width;
  int H = (height - 5) / 2;
  
  pg.beginDraw();

  pg.background(0);

  barWidth = W / float(drawfft.specSize());
  
  pg.fill(255);
  pg.textAlign(RIGHT, TOP);
  pg.textSize(13);
  if(channel == -1) pg.text("IN", pg.width - 8, 8);
  else if(channel == 1) pg.text("OUT", pg.width - 8, 8);

  
  for(int i = 0; i < drawfft.specSize(); i++) {
    pg.strokeWeight(1);
    pg.fill(255, 0, 0);
    pg.stroke(255, 0, 0);
    pg.rect(i * barWidth, H, barWidth, -constrain(dB(drawfft.getBand(i)) * scale, 0, H));
  }
  
  pg.endDraw();
}

void init() {
  minim = new Minim(this);
  minim.debugOn();
  
  mic = minim.getLineIn(Minim.MONO);
  out = minim.getLineOut(Minim.MONO);
  
  testfft = new FFT(mic.bufferSize(), mic.sampleRate());

  mic.addListener(new InEvent());
  out.addSignal(new OutEvent());

  drawfft = new FFT(mic.bufferSize(), mic.sampleRate());
}

float dB(float amp) { return 20 * (log(amp) / log(10)); }


class InEvent implements AudioListener {
  synchronized void samples(float[] samp) {
    testfft.forward(samp);
  }
  
  synchronized void samples(float[] sampL, float[] sampR) {
    samples(sampL);
  }
}

class OutEvent implements AudioSignal {
  synchronized void generate(float[] samp) {
    testfft.inverse(samp);
  }
 
  synchronized void generate(float[] left, float[] right) {
    generate(left);
  }
}

接受任何答复,

西蒙尼

EN

回答 1

Stack Overflow用户

发布于 2021-12-31 02:28:58

我调试了您发布的代码,它现在应该没有错误地运行。我不知道演示是如何工作的,但是它确实产生了来自我的macOS扬声器的一个粗糙的输出,这与原始作者的评论是一致的。请注意,'println‘调用表示'fftIn’实际上等于'fftOut‘。output.AddSignal()必须向下移动几行,因为它依赖于fftIn和fftOut的值。还有必要将“fftIn”和“fftOut”区分开来,尽管两者是平等的。在源代码中没有修改。为了让它运行(没有它就不能运行),添加了一个空的抽签()。

代码语言:javascript
复制
import ddf.minim.*;
import ddf.minim.analysis.*;

private FFT fftIn, fftOut;
private AudioInput input;
private AudioOutput output;
private Minim minim;

void setup() {
  size(300, 200);
  minim = new Minim(this);
  // Added Minim.MONO
  input = minim.getLineIn(Minim.MONO);
  input.addListener(new Listener());
  output = minim.getLineOut();
  // Separated fftIn from fftOut
  fftIn = new FFT(input.bufferSize(), input.sampleRate());
  println("fftIn =",fftIn);
  fftOut = fftIn;
  // moved this down here because it needs fftIn, fftOut
  output.addSignal(new Signal());
}

class Listener implements AudioListener {
  public void  samples(float[] sample) {
    fftIn.forward(sample);
  }
  public void samples(float[] left, float[] right) {
    samples(left);
  }
}

private class Signal implements AudioSignal {
  public void generate(float[] sample) {
    boolean mode = false;
    println("fftOut =",fftOut);
    if (mode) {
      fftIn.inverse(sample);
    } else {
      for (int i = 0; i < input.bufferSize() / 2; i++) {
        fftOut.setBand(i, fftIn.getBand(i));
      }                
      fftOut.inverse(sample);
    }
  }

  public void generate(float[] left, float[] right) {
    generate(right);
  }
}

// Won't run without adding this
void draw() {  
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70397348

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档