The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

Win32::Sound - An extension to play with Windows sounds

SYNOPSIS

use Win32::Sound;
Win32::Sound::Volume('100%');
Win32::Sound::Play("file.wav");
Win32::Sound::Stop();

# ...and read on for more fun ;-)

FUNCTIONS

Win32::Sound::Play(SOUND, [FLAGS])

Plays the specified sound: SOUND can the be name of a WAV file or one of the following predefined sound names:

SystemDefault
SystemAsterisk
SystemExclamation
SystemExit
SystemHand
SystemQuestion
SystemStart

Additionally, if the named sound could not be found, the function plays the system default sound (unless you specify the SND_NODEFAULT flag). If no parameters are given, this function stops the sound actually playing (see also Win32::Sound::Stop).

FLAGS can be a combination of the following constants:

SND_ASYNC

The sound is played asynchronously and the function returns immediately after beginning the sound (if this flag is not specified, the sound is played synchronously and the function returns when the sound ends).

SND_LOOP

The sound plays repeatedly until it is stopped. You must also specify SND_ASYNC flag.

SND_NODEFAULT

No default sound is used. If the specified sound cannot be found, the function returns without playing anything.

SND_NOSTOP

If a sound is already playing, the function fails. By default, any new call to the function will stop previously playing sounds.

Win32::Sound::Stop()

Stops the sound currently playing.

Win32::Sound::Volume()

Returns the wave device volume; if called in an array context, returns left and right values. Otherwise, returns a single 32 bit value (left in the low word, right in the high word). In case of error, returns undef and sets $!.

Examples:

($L, $R) = Win32::Sound::Volume();
if( not defined Win32::Sound::Volume() ) {
    die "Can't get volume: $!";
}
Win32::Sound::Volume(LEFT, [RIGHT])

Sets the wave device volume; if two arguments are given, sets left and right channels independently, otherwise sets them both to LEFT (eg. RIGHT=LEFT). Values range from 0 to 65535 (0xFFFF), but they can also be given as percentage (use a string containing a number followed by a percent sign).

Returns undef and sets $! in case of error, a true value if successful.

Examples:

Win32::Sound::Volume('50%');
Win32::Sound::Volume(0xFFFF, 0x7FFF);
Win32::Sound::Volume('100%', '50%');
Win32::Sound::Volume(0);
Win32::Sound::Format(filename)

Returns information about the specified WAV file format; the array contains:

  • sample rate (in Hz)

  • bits per sample (8 or 16)

  • channels (1 for mono, 2 for stereo)

Example:

($hz, $bits, $channels) 
    = Win32::Sound::Format("file.wav");
Win32::Sound::Devices()

Returns all the available sound devices; their names contain the type of the device (WAVEOUT, WAVEIN, MIDIOUT, MIDIIN, AUX or MIXER) and a zero-based ID number: valid devices names are for example:

WAVEOUT0
WAVEOUT1
WAVEIN0
MIDIOUT0
MIDIIN0
AUX0
AUX1
AUX2

There are also two special device names, WAVE_MAPPER and MIDI_MAPPER (the default devices for wave output and midi output).

Example:

@devices = Win32::Sound::Devices();
Win32::Sound::DeviceInfo(DEVICE)

Returns an associative array of information about the sound device named DEVICE (the same format of Win32::Sound::Devices).

The content of the array depends on the device type queried. Each device type returns at least the following information:

manufacturer_id
product_id
name
driver_version

For additional data refer to the following table:

WAVEIN..... formats
            channels

WAVEOUT.... formats
            channels
            support
            
MIDIOUT.... technology
            voices
            notes
            channels
            support
            
AUX........ technology
            support
            
MIXER...... destinations
            support

The meaning of the fields, where not obvious, can be evinced from the Microsoft SDK documentation (too long to report here, maybe one day... :-).

Example:

%info = Win32::Sound::DeviceInfo('WAVE_MAPPER');
print "$info{name} version $info{driver_version}\n";

THE WaveOut PACKAGE

Win32::Sound also provides a different, more powerful approach to wave audio data with its WaveOut package. It has methods to load and then play WAV files, with the additional feature of specifying the start and end range, so you can play only a portion of an audio file.

Furthermore, it is possible to load arbitrary binary data to the soundcard to let it play and save them back into WAV files; in a few words, you can do some sound synthesis work.

FUNCTIONS

new Win32::Sound::WaveOut(FILENAME)
new Win32::Sound::WaveOut(SAMPLERATE, BITS, CHANNELS)
new Win32::Sound::WaveOut()

This function creates a WaveOut object; the first form opens the specified wave file (see also Open() ), so you can directly Play() it.

The second (and third) form opens the wave output device with the format given (or if none given, defaults to 44.1kHz, 16 bits, stereo); to produce something audible you can either Open() a wave file or Load() binary data to the soundcard and then Write() it.

Note that by default Win32::Sound::WaveOut will use the first soundcard (eg. WAVEOUT0). If you want to use a different one, you have to do the following:

my $WAV = Win32::WaveOut->new();
$WAV->CloseDevice();
$WAV->OpenDevice(1); # open WAVEOUT1
Close()

Closes the wave file currently opened.

CloseDevice()

Closes the wave output device; you can change format and reopen it with OpenDevice().

GetErrorText(ERROR)

Returns the error text associated with the specified ERROR number; note it only works for wave-output-specific errors.

Load(DATA)

Loads the DATA buffer in the soundcard. The format of the data buffer depends on the format used; for example, with 8 bit mono each sample is one character, while with 16 bit stereo each sample is four characters long (two 16 bit values for left and right channels). The sample rate defines how much samples are in one second of sound. For example, to fit one second at 44.1kHz 16 bit stereo your buffer must contain 176400 bytes (44100 * 4).

Open(FILE)

Opens the specified wave FILE.

OpenDevice([ID])

Opens the wave output device with the current sound format (not needed unless you used CloseDevice()).

By default it will open the first device (eg. WAVEOUT0). If you have multiple soundcards, you can specify which one to use by adding the numeric ID of the (WAVEOUT) device.

Example:

$WAV->OpenDevice(1); # opens WAVEOUT1

See also Win32::Sound::Devices() to list the currently available soundcards.

Pause()

Pauses the sound currently playing; use Restart() to continue playing.

Play( [FROM, TO] )

Plays the opened wave file. You can optionally specify a FROM - TO range, where FROM and TO are expressed in samples (or use FROM=0 for the first sample and TO=-1 for the last sample). Playback happens always asynchronously, eg. in the background.

Position()

Returns the sample number currently playing; note that the play position is not zeroed when the sound ends, so you have to call a Reset() between plays to receive the correct position in the current sound.

Reset()

Stops playing and resets the play position (see Position()).

Restart()

Continues playing the sound paused by Pause().

Save(FILE, [DATA])

Writes the DATA buffer (if not given, uses the buffer currently loaded in the soundcard) to the specified wave FILE.

Status()

Returns 0 if the soundcard is currently playing, 1 if it's free, or undef on errors.

Unload()

Frees the soundcard from the loaded data.

Volume( [LEFT, RIGHT] )

Gets or sets the volume for the wave output device. It works the same way as Win32::Sound::Volume.

Write()

Plays the data currently loaded in the soundcard; playback happens always asynchronously, eg. in the background.

THE SOUND FORMAT

The sound format is stored in three properties of the WaveOut object: samplerate, bits and channels. If you need to change them without creating a new object, you should close before and reopen afterwards the device.

$WAV->CloseDevice();
$WAV->{samplerate} = 44100; # 44.1kHz
$WAV->{bits}       = 8;     # 8 bit
$WAV->{channels}   = 1;     # mono
$WAV->OpenDevice();

You can also use the properties to query the sound format currently used.

EXAMPLE

This small example produces a 1 second sinusoidal wave at 440Hz and saves it in sinus.wav:

use Win32::Sound;

# Create the object
my $WAV = new Win32::Sound::WaveOut(44100, 8, 2);

my $data = ""; 
my $counter = 0;
my $increment = 440/44100;

# Generate 44100 samples ( = 1 second)
for my $i (1..44100) {

    # Calculate the pitch 
    # (range 0..255 for 8 bits)
    my $v = sin($counter*2*3.14) * 127 + 128;    

    # "pack" it twice for left and right
    $data .= pack("CC", $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

VERSION

Win32::Sound version 0.52, 18 Dec 2013.

AUTHOR

Aldo Calpini, dada@perl.it

Parts of the code provided and/or suggested by Dave Roth.

Additional fixes and module maintenance kindly provided by Jan Dubois, jand@activestate.com.