#!/usr/bin/perl # # Wireless Signal Tone Generator # Copyright (C) 2008 Timm Murray # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # use strict; use warnings; use Audio::Data; use Audio::Play; use Time::HiRes 'usleep'; my $DEBUG = 0; $ENV{PATH} = '/bin:/usr/bin'; # Highest and lowest frequencies played my $LOW_FREQ = 400; my $HIGH_FREQ = 2600; # Highest and lowest signal power (usually expressed in negative dB) my $LOW_SIGNAL = -100; my $HIGH_SIGNAL = 0; # Amplitude of the sine wave generated my $AMP = 0.1; # Timing factors for the program sleeping and the sine wave length, respectively my $SLEEP_DELAY = 500_000; # microseconds my $AUDIO_DELAY = 0.5; # seconds (can be decimal number) # The granularity of the scale my $SCALE = 100; # Interface name to check my $INTERFACE = 'wlan0'; # Path to iwconfig program my $IWCONFIG = '/sbin/iwconfig'; my $audio_play = Audio::Play->new; $SIG{INT} = sub { $audio_play->flush; exit 0; }; my @freq_scale = scale( $HIGH_FREQ, $LOW_FREQ, $SCALE ); my @signal_scale = scale( $HIGH_SIGNAL, $LOW_SIGNAL, $SCALE ); my %scale = map { $signal_scale[$_] => $freq_scale[$_] } 0 .. $#signal_scale; sub set_rate { my ($audio_data, $audio_play) = @_; $audio_data->rate( 8000 ); if( $audio_data->rate != $audio_play->rate ) { $audio_play->rate( $audio_data->rate ); if( $audio_data->rate != $audio_play->rate ) { warn "Converting to " . $audio_play->rate . " Hz\n"; $audio_data->rate( $audio_play->rate ); } } return 1; } sub scale { my ($high, $low, $scale) = @_; my $range = $high - $low; my $percent = $range / $scale; my @scale = map $low + $percent * $_, 0 .. $scale; return @scale; } sub get_signal { my $got = `$IWCONFIG $INTERFACE`; my ($signal) = $got =~ / Signal \s+ level [:=] \s* ([\d\-]+) /x; $signal = $HIGH_SIGNAL if $signal > $HIGH_SIGNAL; $signal = $LOW_SIGNAL if $signal < $LOW_SIGNAL; return $signal; } sub debug { my ($in) = @_; print $in . "\n" if $DEBUG; return 1; } { my @signal = map -1 * $_, 0 .. 100; my $i = 0; sub get_test_signal { $i = 0 if $i > $#signal; return $signal[$i++]; } } { while( 1 ) { #my $signal = get_test_signal; my $signal = get_signal; my $freq = $scale{$signal}; debug( "Signal ${signal}dB, freq ${freq}" ); my $audio_data = Audio::Data->new; set_rate( $audio_data, $audio_play ); $audio_data->tone( $freq, $AUDIO_DELAY, $AMP ); $audio_play->play( $audio_data ); usleep $SLEEP_DELAY; } }