Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number
 
PerlMonks  

Win32::Sound buffer problems

by Dr. Mu (Hermit)
on Feb 23, 2005 at 06:07 UTC ( [id://433591]=perlquestion: print w/replies, xml ) Need Help??

Dr. Mu has asked for the wisdom of the Perl Monks concerning the following question:

I'm using Win32::Sound::WaveOut to create some simple sound sequences. I've written the following module to smooth the interface with my application:
package SoundPlayer; use strict; use Win32::Sound; my $Rate = 8000; sub new { my $invocant = shift; my $class = ref($invocant) || $invocant; my $self = {player => Win32::Sound::WaveOut->new($Rate, 8, 1)}; bless $self, $class; return $self } sub play { my $self = shift; my $player = $self->{player}; $self->stop; my $silence = pack('C', 128); my $data = ''; foreach (@_) { my ($freq, $dur) = @$_; $dur *= $Rate; if ($freq == 0) { $data .= $silence x ($dur) } else { foreach (0 .. $dur - 1) { my $v = 128 + 127 * triangle($_ * $freq / $Rate * 256) +; $data .= pack('C', $v) } } } $player->Unload; $player->Load($data); $player->Write; } sub playBites { my $self = shift; my $tempo = shift; my @sequence; while (@_) { my $bite = shift; foreach my $note ($bite->sequence) { my ($freq, $dur) = @$note; $dur /= $tempo; push @sequence, [int($freq), int($dur) / 1000] } } $self->play(@sequence) } sub done { my $self = shift; return $self->{player}->Status } sub stop { my $self = shift; my $player = $self->{player}; $player->Reset; $player->Unload } #---[Functions for different waveforms]------------------------------ sub _duo { my $x = shift; return (sin($x) + 0.5 * sin(3 * $x) + 0.25 * sin(5 * $x)) / 1.75 } sub _square { my $x = (int(shift) % 256); return $x < 128 ? -1 : 1 } sub _triangle { my $x = (int(shift) % 256); return $x < 128 ? $x / 128 - 0.5 : (256 - $x) / 128 - 0.5 } sub _cliptriangle { my $x = shift; my $y = _triangle($x) * 1.25; return $y > 1 ? 1 : $y < -1 ? -1 : $y } 1;
It works fine, and I get the sounds I want. But I'm having a problem when long-duration sequences are followed those of shorter durations. Once the shorter sequence has finished, the remainder of the longer sequence continues playing until it has finished. Apparently the buffer is not getting cleared properly between sequences. But I'm at a loss how to remedy the situation (short of filling the ends of short sequences with silence -- a bad option). Any ideas?

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://433591]
Approved by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others romping around the Monastery: (2)
As of 2024-04-24 22:52 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found