Permalink
Browse files

spectrogram!

  • Loading branch information...
1 parent 751cd06 commit acfaa444ef3db7dee803dd39bdf10755dba62033 @zpmorgan committed Jan 27, 2012
Showing with 58 additions and 8 deletions.
  1. +56 −6 examples/spectrogram.pl
  2. +2 −2 lib/PDL/GStreamer.pm
View
@@ -3,7 +3,12 @@
use lib 'lib';
use PDL;
use PDL::Graphics2D 'imag2d';
+use PDL::Constants qw'PI I';
use PDL::GStreamer;
+use PDL::FFTW;
+use PDL::Complex;
+
+my $do_play = 0;
use File::Spec;
my $filename = shift @ARGV;
@@ -17,12 +22,57 @@
);
#$tune->seek(10);
-my ($audio,$format) = $tune->capture_audio(5);
+my $seconds = 28;
+my ($audio,$format) = $tune->capture_audio($seconds);
+unless(!$do_play or fork()){
#die $audio->dims;
-my $rawsound = pack ($format->{packtemplate} .'*' , $audio->slice('0')->list);
-my $pa;
-open ($pa,'|pacat --format=s16le --channels=1');
-print $pa $rawsound;
-close($pa);
+ my $rawsound = pack ($format->{packtemplate} .'*' , $audio->slice('0')->list);
+ my $pa;
+ open ($pa,'|pacat --format=s16le --channels=1');
+ print $pa $rawsound unless fork();
+ close($pa);
+ exit;
+}
+
+my $ncols = 1000;
+
+$audio = $audio->slice(0)->copy->squeeze;;
+my $window_time = .04;
+my $window_size = $window_time * $format->{rate};
+my $sample_step = 2;
+
+my $hann_window;
+sub mk_hann_window{
+ my $N = shift;
+ $hann_window = sequence($N);
+ $hann_window = .5 * (1 - cos(2 * PI * $hann_window / ($N-1)));
+}
+
+sub stfft{
+ my $time = shift;
+ $time *= $format->{rate};
+ $time = int $time;
+ my $window = $audio->slice($time.':'.($time+$window_size-1).':'.$sample_step)->sever;
+ mk_hann_window($window->dim(0)) unless defined $hann_window;
+ $window *= $hann_window;
+ #make samples between -1 and 1.
+ $window /= 1<<($format->{width}-1);
+ $window -= 1;
+
+ #fft & convert to polar.
+ $window = cplx rfftw $window;
+ return $window->Cr2p->real;
+}
+my $spectrogram;
+for(0..$ncols-4){
+ my $t = $_ * $seconds / $ncols;
+ my $col = stfft($t)->dummy(1);
+ unless(defined $spectrogram){
+ $spectrogram = zeros(3,$ncols,$col->dim(2));
+ }
+ $spectrogram->slice("0:1,".$_) .= $col;
+}
+$spectrogram /= $spectrogram->slice(":,:,9:-1")->max;
+imag2d($spectrogram);
View
@@ -222,8 +222,8 @@ sub _read_audio_caps{
my ($channels) = $caps =~ /channels=\(int\)(\d)/;
my $ptemplate; #TEMPLATE for unpack. bleh.
- $ptemplate = 'n' if (($width==16) and !$littleendian);
- $ptemplate = 's' if (($width==16) and $littleendian);
+ $ptemplate = 's' if (($width==16) and !$littleendian);
+ $ptemplate = 'n' if (($width==16) and $littleendian);
die "$caps unpackable?" unless $ptemplate;
my $format = {

0 comments on commit acfaa44

Please sign in to comment.