By george i think that's the answer. Sound generated with your fix is the exact same tone as the 8bit one!!! Thanks so much for your help BrowserUK! I tried to do this over a year ago and was stuck then too. I have read the pack docs so many times its crazy but their brevity times my ignorance about value types still confuses me. Here is a working example with your fix for a 16bit mono sound wave...
use Win32::Sound;
# Create the object
$WAV = new Win32::Sound::WaveOut(44100, 16, 1);
$data = "";
$counter = 0;
$increment = 440/44100;
# Generate 44100 samples ( = 1 second)
for $i (1..44100) {
# Calculate the pitch
# (range 0..65335 for 16 bits)
$v = int(sin($counter/2*3.14) * (65335/2));
#signed integer (v) range -32768 <-> 32767
$data .= pack("v", $v);
$counter += $increment;
}
$WAV->Load($data); # get it
$WAV->Write(); # hear it
1 until $WAV->Status(); # wait for completion
$WAV->Save("sinus.wav"); # write to disk
$WAV->Unload(); # drop it
thanks again, hopefully someone else can use this too.
BTW if anyone wants to do this in stereo here's the code for 16bit stereo sound too. Just as above, this generates a 1 second sinusoidal wave at 440Hz but in both channels.
use Win32::Sound;
# Create the object
$WAV = new Win32::Sound::WaveOut(44100, 16, 2);
$data = "";
$counter = 0;
$increment = 440/44100;
# Generate 44100 samples ( = 1 second)
for $i (1..44100) {
# Calculate the pitch
# (range 0..65335 for 16 bits)
$v = int(sin($counter/2*3.14) * (65335/2));
#signed integer (v) range -32768 <-> 32767
$data .= pack("v", $v);
$data .= pack("v", $v);
$counter += $increment;
}
$WAV->Load($data); # get it
$WAV->Write(); # hear it
1 until $WAV->Status(); # wait for completion
$WAV->Save("sinus.wav"); # write to disk
$WAV->Unload(); # drop it
exit;
Thanks again all!