求调教:FFT与扒谱
来源:百度文库 编辑:超级军网 时间:2024/04/29 19:21:14
扒谱扒到纠结了……
应当有一种辅助工具,能人工选定曲子里的一段,算FFT,然后看频率峰图,就知道有哪几个音和声了。
谁知道怎么获得音频数据流?现在有哪些FFT的API?扒谱扒到纠结了……
应当有一种辅助工具,能人工选定曲子里的一段,算FFT,然后看频率峰图,就知道有哪几个音和声了。
谁知道怎么获得音频数据流?现在有哪些FFT的API?
应当有一种辅助工具,能人工选定曲子里的一段,算FFT,然后看频率峰图,就知道有哪几个音和声了。
谁知道怎么获得音频数据流?现在有哪些FFT的API?扒谱扒到纠结了……
应当有一种辅助工具,能人工选定曲子里的一段,算FFT,然后看频率峰图,就知道有哪几个音和声了。
谁知道怎么获得音频数据流?现在有哪些FFT的API?
完全不懂的说{:wu:}
路过 同围观··
完全不知道格林达姆娘说的是什么,只有友情围观了
欢迎天顶星人来地球参观访问。
一牧月 发表于 2010-10-18 10:43
发现我不用自己干了,这个软件已经存在了
Audacity,还是开源免费的,功能巨强大
发现我不用自己干了,这个软件已经存在了
Audacity,还是开源免费的,功能巨强大
jiandingzhe 发表于 2010-10-18 15:41
这不,求人不如求己嘛{:wu:}
这不,求人不如求己嘛{:wu:}
LPC2103 发表于 2010-10-18 17:38
但是那个软件没有时间-频谱分布图,光看强度图看不出在哪段。杯具了。
难道要老子自己开发扩展么……[:a11:]
但是那个软件没有时间-频谱分布图,光看强度图看不出在哪段。杯具了。
难道要老子自己开发扩展么……[:a11:]
jiandingzhe 发表于 2010-10-18 17:42
这个对你来说木有压力啦@
这个对你来说木有压力啦@
博丽灵梦 发表于 2010-10-18 18:05
咱几乎没有用过C和C++,完全没有接触过媒体流……
咱几乎没有用过C和C++,完全没有接触过媒体流……
炼成了,咩哈哈哈哈!!
依然有一个会导致segmentation fault的地方,非常诡异,只能人工限制循环数。
修改完成!
- #!/usr/bin/perl
- use strict;
- use feature qw/say/;
- use Cairo;
- use Getopt::Long;
- use Math::Trig qw/pip2/;
- use PDL;
- use PDL::Audio;
- use POSIX();
- use constant PITCH_STEP => 2**( 1 / 12 );
- my $file_in;
- my $file_out;
- my $time_grid_interval = 1;
- my $window_sz = 16384;
- my $window_step = 512;
- my $page_width = 2000;
- my $freq_from = 50;
- my $freq_to = 7040;
- GetOptions(
- 'in=s' => \$file_in,
- 'out=s' => \$file_out,
- 'size=i' => \$window_sz,
- 'step=i' => \$window_step
- );
- my $pdl = raudio $file_in;
- my $sz = $pdl->getdim(0);
- my $audio_rate = $pdl->rate;
- say "length: $sz";
- say "audio sampling rate: $audio_rate";
- my $window = gen_fft_window $window_sz, 'hamming';
- my $data;
- my $use_spec_from = POSIX::floor( $freq_from * $window_sz / $audio_rate );
- my $use_spec_to = calc_use_spectrum_sz();
- my $scale_rate = log( $use_spec_to / $use_spec_from ) / $page_width - 0.00001;
- my $page_deviate = log($use_spec_from) / $scale_rate;
- my $stride = Cairo::Format::stride_for_width( 'argb32', $page_width );
- my $spec_count = 0;
- say "fft result used: $use_spec_from - $use_spec_to";
- for ( my $i = 0 ; $i < $sz ; $i += $window_step ) {
- $spec_count++;
- my $end = $i + $window_sz - 1;
- say "$spec_count: $i - $end of $sz";
- my $sliced = $pdl->slice("$i:$end");
- my $spec = spectrum $sliced, 1, $window;
- # for ( my $j = 0 ; $j < $spec_sz ; $j++ ) {
- # my $value = POSIX::floor( 255 * abs( $spec->at($j) ) );
- # $data .= pack 'CCCC', $value, $value, $value, 255;
- # }
- for ( my $j = 0 ; $j < $page_width ; $j++ ) {
- my $index = POSIX::floor( exp( ( $j + $page_deviate ) * $scale_rate ) );
- my $index2 =
- POSIX::floor( exp( ( $j + $page_deviate + 1 ) * $scale_rate ) );
- my $value;
- if ( $index = $index2 ) {
- $value = POSIX::floor( 255 * abs( $spec->at($index) ) );
- }
- else {
- my $sum;
- for ( $index .. $index2 ) {
- $sum += POSIX::floor( 255 * abs( $spec->at($_) ) );
- }
- $value = $sum / ( $index2 - $index + 1 );
- }
- $data .= pack 'CCCC', $value, $value, $value, 255;
- }
- if ( $end >= $sz - $window_step ) {
- last;
- }
- }
- say "picture size: w $page_width, h $spec_count";
- say "stride size : $stride";
- say "graphic data size : ", length($data);
- say "height from stride: ", length($data) / $stride;
- my $surface =
- Cairo::ImageSurface->create_for_data( $data, 'argb32', $page_width,
- $spec_count, $stride );
- draw_grid($surface);
- $surface->write_to_png($file_out);
- sub calc_use_spectrum_sz {
- my $bottom = 20 * $window_sz / $audio_rate;
- my $half = POSIX::floor( $window_sz / 2 - $bottom );
- my $freq_limit =
- POSIX::floor( $freq_to * $window_sz / $audio_rate - $bottom );
- return $freq_limit < $half ? $freq_limit : $half;
- }
- sub draw_grid {
- my $face = shift;
- my $cr = Cairo::Context->create($face);
- $cr->set_source_rgb( 0, 1, 1 );
- $cr->set_line_width(0.5);
- my $time_grid_sz = $time_grid_interval * $audio_rate / $window_step;
- my @pitch_cycle = qw/C C# D D# E F F# G G# A A# B/;
- my $freq_C = 440 * ( PITCH_STEP**3 ) / 2;
- for (
- my $y = 0, my $y_step = 0 ;
- $y < $spec_count ;
- $y += $time_grid_sz, $y_step++
- )
- {
- $cr->move_to( 0, $y );
- $cr->line_to( $page_width, $y );
- $cr->stroke;
- $cr->move_to( 0, $y );
- $cr->show_text( $y_step * $time_grid_interval );
- # draw frequency
- my $upper_i = 0;
- my $upper_cycle = 4;
- for ( my $f = $freq_C ; $f < $freq_to ; $f *= PITCH_STEP ) {
- my $x =
- log( $f * $window_sz / $audio_rate ) / $scale_rate -
- $page_deviate;
- $cr->save;
- $cr->translate( $x, $y );
- $cr->rotate( -pip2 );
- $cr->move_to( 0, 0 );
- $cr->show_text( $pitch_cycle[$upper_i] . $upper_cycle );
- $cr->restore;
-
- $cr->move_to($x,$y);
- $cr->line_to($x,$y+5);
- $cr->stroke;
- $upper_i++;
- if ( $upper_i == 12 ) {
- $upper_i -= 12;
- $upper_cycle++;
- }
- }
- my $lower_i = 11;
- my $lower_cycle = 3;
- for ( my $f = $freq_C / PITCH_STEP ;
- $f > $freq_from ; $f /= PITCH_STEP )
- {
- my $x =
- log( $f * $window_sz / $audio_rate ) / $scale_rate -
- $page_deviate;
-
- $cr->save;
- $cr->translate( $x, $y );
- $cr->rotate( -pip2 );
- $cr->move_to( 0, 0 );
- $cr->show_text( $pitch_cycle[$lower_i] . $lower_cycle );
- $cr->restore;
-
- $cr->move_to($x,$y);
- $cr->line_to($x,$y+5);
- $cr->stroke;
- $lower_i--;
- if ( $lower_i == -1 ) {
- $lower_i += 12;
- $lower_cycle--;
- }
- }
- }
- }
炼成了,咩哈哈哈哈!!
依然有一个会导致segmentation fault的地方,非常诡异,只能人工限制循环数。
修改完成!
- #!/usr/bin/perl
- use strict;
- use feature qw/say/;
- use Cairo;
- use Getopt::Long;
- use Math::Trig qw/pip2/;
- use PDL;
- use PDL::Audio;
- use POSIX();
- use constant PITCH_STEP => 2**( 1 / 12 );
- my $file_in;
- my $file_out;
- my $time_grid_interval = 1;
- my $window_sz = 16384;
- my $window_step = 512;
- my $page_width = 2000;
- my $freq_from = 50;
- my $freq_to = 7040;
- GetOptions(
- 'in=s' => \$file_in,
- 'out=s' => \$file_out,
- 'size=i' => \$window_sz,
- 'step=i' => \$window_step
- );
- my $pdl = raudio $file_in;
- my $sz = $pdl->getdim(0);
- my $audio_rate = $pdl->rate;
- say "length: $sz";
- say "audio sampling rate: $audio_rate";
- my $window = gen_fft_window $window_sz, 'hamming';
- my $data;
- my $use_spec_from = POSIX::floor( $freq_from * $window_sz / $audio_rate );
- my $use_spec_to = calc_use_spectrum_sz();
- my $scale_rate = log( $use_spec_to / $use_spec_from ) / $page_width - 0.00001;
- my $page_deviate = log($use_spec_from) / $scale_rate;
- my $stride = Cairo::Format::stride_for_width( 'argb32', $page_width );
- my $spec_count = 0;
- say "fft result used: $use_spec_from - $use_spec_to";
- for ( my $i = 0 ; $i < $sz ; $i += $window_step ) {
- $spec_count++;
- my $end = $i + $window_sz - 1;
- say "$spec_count: $i - $end of $sz";
- my $sliced = $pdl->slice("$i:$end");
- my $spec = spectrum $sliced, 1, $window;
- # for ( my $j = 0 ; $j < $spec_sz ; $j++ ) {
- # my $value = POSIX::floor( 255 * abs( $spec->at($j) ) );
- # $data .= pack 'CCCC', $value, $value, $value, 255;
- # }
- for ( my $j = 0 ; $j < $page_width ; $j++ ) {
- my $index = POSIX::floor( exp( ( $j + $page_deviate ) * $scale_rate ) );
- my $index2 =
- POSIX::floor( exp( ( $j + $page_deviate + 1 ) * $scale_rate ) );
- my $value;
- if ( $index = $index2 ) {
- $value = POSIX::floor( 255 * abs( $spec->at($index) ) );
- }
- else {
- my $sum;
- for ( $index .. $index2 ) {
- $sum += POSIX::floor( 255 * abs( $spec->at($_) ) );
- }
- $value = $sum / ( $index2 - $index + 1 );
- }
- $data .= pack 'CCCC', $value, $value, $value, 255;
- }
- if ( $end >= $sz - $window_step ) {
- last;
- }
- }
- say "picture size: w $page_width, h $spec_count";
- say "stride size : $stride";
- say "graphic data size : ", length($data);
- say "height from stride: ", length($data) / $stride;
- my $surface =
- Cairo::ImageSurface->create_for_data( $data, 'argb32', $page_width,
- $spec_count, $stride );
- draw_grid($surface);
- $surface->write_to_png($file_out);
- sub calc_use_spectrum_sz {
- my $bottom = 20 * $window_sz / $audio_rate;
- my $half = POSIX::floor( $window_sz / 2 - $bottom );
- my $freq_limit =
- POSIX::floor( $freq_to * $window_sz / $audio_rate - $bottom );
- return $freq_limit < $half ? $freq_limit : $half;
- }
- sub draw_grid {
- my $face = shift;
- my $cr = Cairo::Context->create($face);
- $cr->set_source_rgb( 0, 1, 1 );
- $cr->set_line_width(0.5);
- my $time_grid_sz = $time_grid_interval * $audio_rate / $window_step;
- my @pitch_cycle = qw/C C# D D# E F F# G G# A A# B/;
- my $freq_C = 440 * ( PITCH_STEP**3 ) / 2;
- for (
- my $y = 0, my $y_step = 0 ;
- $y < $spec_count ;
- $y += $time_grid_sz, $y_step++
- )
- {
- $cr->move_to( 0, $y );
- $cr->line_to( $page_width, $y );
- $cr->stroke;
- $cr->move_to( 0, $y );
- $cr->show_text( $y_step * $time_grid_interval );
- # draw frequency
- my $upper_i = 0;
- my $upper_cycle = 4;
- for ( my $f = $freq_C ; $f < $freq_to ; $f *= PITCH_STEP ) {
- my $x =
- log( $f * $window_sz / $audio_rate ) / $scale_rate -
- $page_deviate;
- $cr->save;
- $cr->translate( $x, $y );
- $cr->rotate( -pip2 );
- $cr->move_to( 0, 0 );
- $cr->show_text( $pitch_cycle[$upper_i] . $upper_cycle );
- $cr->restore;
-
- $cr->move_to($x,$y);
- $cr->line_to($x,$y+5);
- $cr->stroke;
- $upper_i++;
- if ( $upper_i == 12 ) {
- $upper_i -= 12;
- $upper_cycle++;
- }
- }
- my $lower_i = 11;
- my $lower_cycle = 3;
- for ( my $f = $freq_C / PITCH_STEP ;
- $f > $freq_from ; $f /= PITCH_STEP )
- {
- my $x =
- log( $f * $window_sz / $audio_rate ) / $scale_rate -
- $page_deviate;
-
- $cr->save;
- $cr->translate( $x, $y );
- $cr->rotate( -pip2 );
- $cr->move_to( 0, 0 );
- $cr->show_text( $pitch_cycle[$lower_i] . $lower_cycle );
- $cr->restore;
-
- $cr->move_to($x,$y);
- $cr->line_to($x,$y+5);
- $cr->stroke;
- $lower_i--;
- if ( $lower_i == -1 ) {
- $lower_i += 12;
- $lower_cycle--;
- }
- }
- }
- }
GOOD JOB!
LPC2103 发表于 2010-10-28 10:32
简单的FFT已经不能填满我的欲望了!!我要神经网络!!
简单的FFT已经不能填满我的欲望了!!我要神经网络!!