WAV 音频文件解读以及可视化

回复
头像
523066680
Administrator
Administrator
帖子: 573
注册时间: 2016年07月19日 12:14
联系:

WAV 音频文件解读以及可视化

帖子 523066680 »

模块
package LoadPCM;
use Fcntl qw/:seek/;

our $file = "chord.wav"; #default
our $fh;
our %fmt;
our %data;

sub init
{
$file = shift if ( @_ > 0 );
open our $fh, "<:raw", $file;
seek($fh, 12, SEEK_SET); # 略过文件头
load_fmt_chunk();
}

sub load_fmt_chunk
{
our %fmt;
my $buff;
my @item = qw/ ID
ChunkSize
FormatTag
Channels
SamplesPerSec
AvgBytesPerSec
BlockAlign
BitsPerSample /;
read($fh, $buff, 24);
@fmt{ @item } = unpack("LLssLLsss", $buff);

for my $k ( @item )
{
printf "%-15s: %d\n", $k, $fmt{$k};
}
}

sub load_data_chunk
{
my ($rframe, $rlength) = @_;
our $fh;
our %data;
my $buff;
read($fh, $buff, 8);
@data{"ID", "ChunkSize"} = unpack("LL", $buff);
$data{"length"} = $data{ChunkSize} / $fmt{"BlockAlign"};

my @frame;
my $frame_bytes = $fmt{"BlockAlign"};

for my $it ( 1 .. $data{"length"} )
{
read($fh, $buff, $frame_bytes);
if ( $fmt{"BitsPerSample"} == 8 ) {
push @frame, [ unpack( "C"x $fmt{"Channels"} , $buff) ];
} else {
push @frame, [ unpack( "s"x $fmt{"Channels"} , $buff) ];
}
}

$data{"frame"} = \@frame;
@$rframe = @frame;
$$rlength = $data{"length"};
}

1;
显示波形图
use Modern::Perl;
use OpenGL qw/ :all /;
use OpenGL::Config;
use Time::HiRes 'sleep';
use LoadPCM;

STDOUT->autoflush(1);

our $SIZE_X = 800;
our $SIZE_Y = 600;

our $WinID;
our $PI = 3.1415926536;
our $PI2 = $PI * 2;
our $MAX_LEVEL = 10;

our @frame;
our $flen;
#LoadPCM::init( "RELOADED - Dead Island installer.wav" );
#LoadPCM::init("linkmicinvitePCM.wav");
#LoadPCM::init("cute.wav");
LoadPCM::init("CHIMES.wav");
LoadPCM::load_data_chunk( \@frame, \$flen );
our $bits = $LoadPCM::fmt{"BitsPerSample"};
our $channels = $LoadPCM::fmt{"Channels"};

die "frame data error" if not defined $frame[0]->[0];

&Main();

sub printstr
{
for my $i ( split("", $_[0]) )
{
#glutBitmapCharacter(GLUT_BITMAP_9_BY_15, ord($i));
glutBitmapCharacter(GLUT_BITMAP_HELVETICA_12, ord($i));
}
}

sub display
{
state $offset = 0;
state $repeat = 0;

glClear(GL_COLOR_BUFFER_BIT);

glPushMatrix();
glTranslatef(-1.0, -1.0, 0.0);
glScalef(3.0, 3.0, 3.0);

glColor3f(1.0, 1.0, 1.0);
glBegin(GL_LINES);
glVertex3f(-200.0, 0.0, 0.0);
glVertex3f(200.0, 0.0, 0.0);
glVertex3f(0.0, -200.0, 0.0);
glVertex3f(0.0, 200.0, 0.0);
glEnd();

#if ($bits == 8 ) { glTranslatef(0.0, 50.0, 0.0); }
glColor3f(1.0, 0.0, 0.0);

my $yscale = 0.1;
my $xscale = 0.05;
my $ch = 0;
glBegin(GL_LINE_STRIP);
#glBegin(GL_POINTS);
for my $id ( $offset .. $offset+(100/$xscale) )
{
glVertex3f( ($id-$offset)*$xscale, $frame[$id]->[$ch]*$yscale, 0.0 );
}
glEnd();
$offset += 1;
$repeat = 1;

glPopMatrix();
glutSwapBuffers();
}

sub init
{
glClearColor(0.0, 0.0, 0.0, 1.0);
glLineWidth(1.0);
glPointSize(1.0);
#glDisable(GL_LINE_SMOOTH);
}

sub idle
{
sleep 0.05;
glutPostRedisplay();
}

sub Reshape
{
my $half = 100.0;
glViewport(0.0,0.0, $SIZE_X, $SIZE_Y);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, $half, -$half, $half,-20.0,200.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.0,0.0,100.0,0.0,0.0,0.0, 0.0,1.0,100.0);
}

sub hitkey
{
my $key = shift;
if (lc(chr($key)) eq 'q')
{
glutDestroyWindow($WinID);
}
elsif ($key == 27)
{
glutDestroyWindow($WinID);
}
}

sub Main
{
glutInit();
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE |GLUT_MULTISAMPLE );
glutInitWindowSize($SIZE_X, $SIZE_Y);
glutInitWindowPosition(1,1);
our $WinID = glutCreateWindow("PCM");
&init();
glutDisplayFunc(\&display);
glutReshapeFunc(\&Reshape);
glutKeyboardFunc(\&hitkey);
glutIdleFunc(\&idle);
glutMainLoop();
}
wave.png
(22.81 KiB) 已下载 28 次
cute.wav.7z
(45.16 KiB) 已下载 91 次
头像
523066680
Administrator
Administrator
帖子: 573
注册时间: 2016年07月19日 12:14
联系:

Re: WAV 音频文件解读以及可视化

帖子 523066680 »

2019-04-06
已经做成柱状频谱图(spectrum)
spectrum1.png
(61.78 KiB) 已下载 16 次
回复

在线用户

正浏览此版面之用户: 没有注册用户 和 1 访客