作者 主题: Processing声音可视化相关讨论  (阅读 6919 次)

jlmgalahad

  • Newbie
  • *
  • 帖子: 30
Processing声音可视化相关讨论
« 于: 十月 10, 2011, 08:15:19 下午 »
最近一直在做这方面的探索,进度缓慢,因此干脆在论坛发帖向大家请教啦!

目前情况是这样,我正在使用forward FFT做音色识别,但是似乎只能进行振幅的控制(get.band()),而关于频率似乎没有值可以记录。

我的设想是如果能测出频率,就能区分不同乐器的声响了。 求指教!谢谢啦!  :)

vinjn

  • SuperManager
  • Hero Member
  • *****
  • 帖子: 586
Re: Processing声音可视化相关讨论
« 回复 #1 于: 十月 10, 2011, 08:54:33 下午 »
声音并不是单个频率的,它在不同频率上都有幅度
fft.getBand(i)返回的是第i个频率段的幅度值
这里的宾语是band,因为通常都是几个频率组成在一起成为一个频率段

下面的代码来自forward FFT的例子
程序代码
  fft.forward(jingle.mix);
  for(int i = 0; i < fft.specSize(); i++)
  {
    // draw the line for frequency band i, scaling it by 4 so we can see it a bit better
    line(i, height, i, height - fft.getBand(i)*4);
  }

fft.specSize()决定了有多少个频率段


关于minim中的FFT
这里还有个文档
http://code.compartmental.net/minim/javadoc/ddf/minim/analysis/FourierTransform.html

你要做的是将当前的声音的所有频率段的幅度值 与 你要检测的音色的 所有频率段的幅度值 进行比较。
找到其中差值最小的,如果把声音看做是一个点,那么就是找距离最接近的点。

如果你要检测的音色比较标准,只在某一个频率上有幅度值,那么可以做些简化。
只要当前声音的最大幅度频率段中包含这个频率,就认为匹配了。

« 最后编辑时间: 十月 10, 2011, 08:56:17 下午 作者 vinjn »

jlmgalahad

  • Newbie
  • *
  • 帖子: 30
Re: Processing声音可视化相关讨论
« 回复 #2 于: 十月 11, 2011, 05:17:24 下午 »
声音并不是单个频率的,它在不同频率上都有幅度
fft.getBand(i)返回的是第i个频率段的幅度值
这里的宾语是band,因为通常都是几个频率组成在一起成为一个频率段

下面的代码来自forward FFT的例子
程序代码
  fft.forward(jingle.mix);
  for(int i = 0; i < fft.specSize(); i++)
  {
    // draw the line for frequency band i, scaling it by 4 so we can see it a bit better
    line(i, height, i, height - fft.getBand(i)*4);
  }

fft.specSize()决定了有多少个频率段


关于minim中的FFT
这里还有个文档
http://code.compartmental.net/minim/javadoc/ddf/minim/analysis/FourierTransform.html

你要做的是将当前的声音的所有频率段的幅度值 与 你要检测的音色的 所有频率段的幅度值 进行比较。
找到其中差值最小的,如果把声音看做是一个点,那么就是找距离最接近的点。

如果你要检测的音色比较标准,只在某一个频率上有幅度值,那么可以做些简化。
只要当前声音的最大幅度频率段中包含这个频率,就认为匹配了。



哈哈!太感谢vinjn啦!明确了这个代码之后,正在调试!  但是目前在选择控制上尚有不清楚,所以我只是在specSize上做选区

比如
 fft.forward(jingle.mix);
      for(int i = 0; i < fft.specSize()/2; i++)
  {
    stroke(25,220,10);
     line(i, height-300, i, height - fft.getBand(i)*4-300);
 if (i < fft.specSize()/10000 || i > fft.specSize()/3.3){
  line(i, height-450, i, height - fft.getBand(i)*4-450);
    }
不知道是否正确?
因为感觉 fft.getBand(i)只是修改的振幅


vinjn

  • SuperManager
  • Hero Member
  • *****
  • 帖子: 586
Re: Processing声音可视化相关讨论
« 回复 #3 于: 十月 11, 2011, 10:42:42 下午 »
没看明白你要的效果,不妨先解释下你的代码
可以先println(fft.specSize()); 看看大小是多少

这个官方的例子你可以多跑跑,对不同声音下显示的不同线段找点感觉


jlmgalahad

  • Newbie
  • *
  • 帖子: 30
Re: Processing声音可视化相关讨论
« 回复 #4 于: 十月 12, 2011, 12:31:21 上午 »
没看明白你要的效果,不妨先解释下你的代码
可以先println(fft.specSize()); 看看大小是多少

这个官方的例子你可以多跑跑,对不同声音下显示的不同线段找点感觉

我换了几首歌~ print一直显示1025,可是我选的采样缓冲确实是2048 
我试了女声和男声以及其它乐器,能明显在波形上看见不同频率(x轴方向)各自的活跃部分,似乎是能够按照我的设想去选择的

我的设想是:分割官方代码中波形上x轴方向的一段频率(截取x值0~100,&100~200...来划分选区), 分割后这段频率的振幅也就是我需要指定的音色的振幅变量了

可是我能截取从0开始任意值的长度,却不能灵活的从x = 10或者x = 100开始截取


vinjn

  • SuperManager
  • Hero Member
  • *****
  • 帖子: 586
Re: Processing声音可视化相关讨论
« 回复 #5 于: 十月 20, 2011, 10:52:05 上午 »
不要想太复杂,其实只是对数组中元素的操作。

程序代码
ArrayList new_range = new ArrayList();//放置你想截取的区域
int start = 100;//从100开始
int end = 200;//到200截止
  for(int i = start ; i < end ; i++)
  {
    new_range.add(fft.getBand(i));//依次添加
  }

jlmgalahad

  • Newbie
  • *
  • 帖子: 30
Re: Processing声音可视化相关讨论
« 回复 #6 于: 二月 11, 2012, 11:14:11 上午 »
非常感谢vinji的指点!在以上的代码中可以做到部分的音色辨识了,但是仍然不准确,播放音乐时不同的配器出现仍有干扰,不太到位,而且似乎只限于现成的音频文件输入,想了解下在即时录入的DDF中能插入fft的分析么?

Tags: