Subject: horrid 16bit beep solution.
To: RiscBSD <port-arm32@NetBSD.ORG>
From: Ale Terlevich <A.I.Terlevich@durham.ac.uk>
List: port-arm32
Date: 11/27/1996 14:22:45
  Hi,

  Has anyone else been *really* annoyed by the beep sound when using a 16bit
soundcard/motherboard?

  I certainly have, so I've written a wee perl script to convert 
/sys/arch/arm32/mainbus/waveform.h from VIDC uLaw to 16bit signed linear.

  It doubles the frequency cos it has to throw away half the samples to 
keep it 4k long, but it now sounds correct!

  I'm afraid you can only use it if you compile your own kernels cos it 
replaces the waveform compiled into the kernel.  Maybe if mark released 
the source to mkbeep someone could write a mkbeep16 to create 16 bit 
waveforms on the fly, but I'm afraid I have no idea how to write it from 
scratch.

  To use the script, do something like

cd /sys/arch/arm32/mainbus
perl mk16beep waveform.h > waveform16.h

then either
rm waveform.h
mv waveform16.h waveform.h

or change the #include lines in vidcaudio.c and beep.c to include 
waveform16.h instead of waveform.h

Now just recompile and off you go!

  Obviously you shouldn't use mkbeep or it'll replace your nice new 
waveform with a horrid 8bit one.

 Hope someone else finds this useful!

Ale.

Here's the perl(5) script! Perl's not my strong point, so please
forgive any horrid style mistakes :)

#!perl
# Ale's program to make the beep work.  27-11-96

while ( ( $line = <> )!~ /\{/ ) { print $line; }
print $line;

$i=0;
while ( ($line = <>) !~ /\}/ ) {
    chop $line;
    $line =~ s/^\s+//;
    $line =~ s/,$//;
    @tmp = split /,\s/ , $line;
    for ( $j=0 ; $j < scalar(@tmp) ; $j += 1 ) {
	$wave[$i+$j] = unulaw(oct($tmp[$j]));
    }
    $i+=scalar(@tmp);
}

#Only print out every other value so that the total doesn't go over 4k.
for ( $i = 1 ; $i < scalar(@wave) ; $i += 8 ) {
    for ( $j=0 ; $j < 8 ; $j +=2 ) {
	$tmp1 = $wave[$i+$j] & 255;
	$tmp2 = ($wave[$i+$j] >> 8) & 255;
	printf "0x%X, 0x%X, ",$tmp1,$tmp2;
    }
    print "\n";
}
print $line;
while ( $line = <> ) { print $line; }

sub unulaw {
#convert from VIDC uLaw to signed 32 bit.
    local($bt) = @_;
    local($sign,$chord,$pos,$step,$base);
    
    $sign =-( ($bt & 1)*2-1);
    $pos = ($bt & 30 ) >> 1;
    $chord = ($bt & (7<<5) ) >> 5 ;
    $step = 1 << $chord;
    $base = ($step - 1) * 16;
    $sign*($base+$step*$pos);
}