According to the Audio::Data docs, + is overloaded for additive mixing of two Data objects. So just create a second Data object for your second tone, add them, and save it back to the original object. Make sure when you call silence() that you are not overwriting the original data. You may have to use ->append($data_object->silence(...)) instead of calling silence() directly.
If, instead, you are trying to concatenate sounds (one sound plays after the other... for instance, a monotonic telephone dialing sequence), then you will have to use appends. Regardless, right now you are just overwriting your previous data with the last tone (or possibly the silence()).
Check the CPAN docs, they are very clear. It seems like you don't quite understand how Audio::Data represents and processes data. It's sample-based, not some group of functional representations (which could, theoretically, happily co-exist... but even so the usage syntax would probably be different than what you have).
~e
| [reply] [d/l] [select] |
You can mix sounds using SDL::Mixer, see Tk Game Sound demo where I use Tk as a front end. But if you just want DTMF tones, you can try Audio::Beep. ( scripts must be run as root ),
or Audio::Wav
#!/usr/bin/perl -w
#Usage: $0 [DTMF tones] [play]
#i.e. dtmf.pl 18005551212 1
use strict;
use Audio::Wav;
my @tones;
my %dtmf = (
'1' => [ 697, 1209 ],
'2' => [ 697, 1336 ],
'3' => [ 697, 1477 ],
'A' => [ 697, 1633 ],
'4' => [ 770, 1209 ],
'5' => [ 770, 1336 ],
'6' => [ 770, 1477 ],
'B' => [ 770, 1633 ],
'7' => [ 852, 1209 ],
'8' => [ 852, 1336 ],
'9' => [ 852, 1477 ],
'C' => [ 852, 1633 ],
'*' => [ 941, 1209 ],
'0' => [ 941, 1336 ],
'#' => [ 941, 1477 ],
'D' => [ 941, 1633 ],
);
if (@ARGV > 0) {
@tones = split'',$ARGV[0];
} else {
@tones = sort keys %dtmf;
}
my $play = $ARGV[1] || '5551212';
my $sample_rate = 22050;
my $bits_sample = 16; #my sblive needs 16
my $num_channels = 1;
my $pi = 4 * atan2 1, 1;
my $duration = 0.5 * $sample_rate;
my $wav = new Audio::Wav;
my $details = {
'bits_sample' => $bits_sample,
'sample_rate' => $sample_rate,
'channels' => $num_channels,
};
my $write = $wav -> write( 'dtmf.wav', $details );
for my $tone (@tones) {
my @hz = map { $pi * $_ } @{$dtmf{$tone}};
add_tone(@hz);
}
$write -> finish();
Win32::Sound::Play('dtmf.wav') if $play && $main::can_play;
sub add_tone {
my (@hz) = @_;
for my $pos ( 0 .. $duration ) {
my $time = $pos / $sample_rate;
my $val = 63 * sin($time * $hz[0]) + 63 * sin($time * $hz[1]);
$write -> write( $val );
}
}
BEGIN {
if ($^O =~ /MSWin32/) {
require Win32::Sound;
our $can_play = 1;
}
}
I'm not really a human, but I play one on earth.
flash japh
| [reply] [d/l] |
I really don't know how to do it, but when I was looking at the Audio::Data documentation I noticed that it had overloaded the operators, this may be what you need in order to make the DTMF. I was thinking allong the lines of using the + operator to mix the two tones.
| [reply] |