Plot the amplitude in an audio file as a grayscale image
#!/usr/bin/perl | |
use strict; | |
use warnings; | |
# Perl script to plot the amplitude in an audio file as a grayscale image. | |
# Uses SoX and ImageMagick via shell. | |
# | |
# Note that the height of the image is only limited by the length of the | |
# audio file. | |
### Settings are here ### | |
######################### | |
# Width of the output image in pixels | |
my $width = 1024; | |
# Lines per minute | |
my $lpm = 33 + 1/3; | |
# Use anti-aliasing lowpass (faster sampling)? (1=yes, 0=no) | |
my $antialias = 1; | |
# Signed amplitude? (1=yes, 0=no) | |
my $signed = 1; | |
# Brightness multiplier | |
my $brightness = 1.0; | |
# Source audio | |
my $src_file = 'source.flac'; | |
# Image to be written | |
my $dst_file = 'out.png'; | |
### Cursed magic here ### | |
######################### | |
my $lopass = $width / (60 / $lpm) / 2; | |
my $samplerate = ($antialias ? $lopass * 2.2 : 44100); | |
my @img; | |
my $time = 0; | |
my $height = 0; | |
$src_file =~ s/"/\\"/g; | |
open my $sox, '-|', 'sox "' . $src_file . '" -t .s16 -c 1 -r ' . $samplerate . ' - ' . | |
'vol 0.9 '.($antialias ? 'sinc -' . $lopass : '') or die $!; | |
while (not eof $sox) { | |
read $sox, my $sample, 2; | |
$sample = (unpack 's', $sample) / 32767 * $brightness; | |
my $x = int($time / (60 / $lpm) * $width); | |
my $y = int($x / $width); | |
$x = $x % $width; | |
$height = $y + 1; | |
$img[$x][$y] = $signed ? ($sample + 1) / 2 : abs($sample); | |
$time += 1 / $samplerate; | |
} | |
close $sox; | |
$dst_file =~ s/"/\\"/g; | |
open my $magick, '|-', 'magick -size ' . $width . 'x' . $height . | |
' -depth 8 gray:- "' . $dst_file . '"' or die $!; | |
for my $y (0..$height-1) { | |
for my $x (0..$width-1) { | |
my $grayvalue = ($img[$x][$y] // 0) * 255; | |
$grayvalue = 255 if ($grayvalue > 255); | |
$grayvalue = 0 if ($grayvalue < 0); | |
print {$magick} pack 'C', $grayvalue; | |
} | |
} | |
close $magick; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment