#!/usr/bin/perl #------------------------------------------------------------------------------ # Create ringtone file for Grandstream BT100 phone, using uLaw input. # # Author: Tony Mountifield # Date: 28 May 2004 # File: makering.pl # History: # 28/05/2004 Initial version. # 29/05/2004 Added checks for input file size being even and not too large. # 30/05/2004 Phone will not accept files larger than 65536 bytes. #------------------------------------------------------------------------------ # # Usage: # Use sox to convert any audio input file to uLaw and pipe to this prog, e.g. # # sox inputfile -r 8000 -c 1 -t ul - rate | makering.pl ring1.bin # # (try using /usr/share/sounds/phone.wav for the inputfile) # # Check the output file by using the following command: # # tail +513c ring1.bin | play -t ul - # # Finally, put the ring file in /tftpboot on the phone's TFTP server, # and reboot the phone. # #------------------------------------------------------------------------------ # # Credits: # Based on analysis by Stephen R. Besch # # Copyright: placed into the public domain by the author # # Warranty: none! # #------------------------------------------------------------------------------ $filename = shift or die "need output filename\n"; undef $/; # slurp whole file at once... $audio = <>; # ... like this $filesize = 512 + length $audio; if ($filesize & 1) { # length odd, add a zero byte (should never happen) $audio .= chr(0); } die "Audio file too large\n" if $filesize > 65536; # this is the format for the header $headerfmt = "n n n C4 n C C C C a22 n x216 n n x36 a216"; # get the current date and time ($min, $hour, $day, $month, $year) = (localtime)[1..5]; $year += 1900; $month += 1; # create the header, with zero for the checksum $header = pack $headerfmt, 0, # 0000 $filesize/2, 0, # put checksum in later 1,0,0,1, # version $year, $month, $day, $hour, $min, $filename, 0, # 0000 or 00C8 - why? 256, # 0100 $filesize/2, "Grandstream standard music ring"; # sanity check $headerlen = length $header; die "header length wrong ($headerlen)\n" unless $headerlen == 512; # add the audio $header .= $audio; # compute the checksum $checksum = unpack "%16n*", $header; #printf "checksum before = %04x\n", $checksum; # insert it in the correct place substr($header,4,2) = pack "n",-$checksum; # ensure the new checksum is zero $checksum = unpack "%16n*", $header; #printf "checksum after = %04x\n", $checksum; die "checksum failed\n" unless $checksum == 0; # write the file open F, ">$filename" or die "can't open output file $filename: $!\n"; print F $header; close F; # end