annotate forum/Sources/Subs-Sound.php @ 85:6d7b61434be7 website

Add a copy of this here, just in case!
author Chris Cannam
date Mon, 20 Jan 2014 11:02:36 +0000
parents e3e11437ecea
children
rev   line source
Chris@76 1 <?php
Chris@76 2
Chris@76 3 /**
Chris@76 4 * Simple Machines Forum (SMF)
Chris@76 5 *
Chris@76 6 * @package SMF
Chris@76 7 * @author Simple Machines http://www.simplemachines.org
Chris@76 8 * @copyright 2011 Simple Machines
Chris@76 9 * @license http://www.simplemachines.org/about/smf/license.php BSD
Chris@76 10 *
Chris@76 11 * @version 2.0
Chris@76 12 */
Chris@76 13
Chris@76 14 if (!defined('SMF'))
Chris@76 15 die('Hacking attempt...');
Chris@76 16
Chris@76 17 /* This file handles sound processing. In order to make sure the visual
Chris@76 18 verification is still accessible for all users, a sound clip is being addded
Chris@76 19 that reads the letters that are being shown.
Chris@76 20
Chris@76 21 void createWaveFile(string word)
Chris@76 22 - creates a wave file that spells the letters of 'word'.
Chris@76 23 - Tries the user's language first, and defaults to english.
Chris@76 24 - Returns false on failure.
Chris@76 25 - used by VerificationCode() (Register.php).
Chris@76 26 */
Chris@76 27
Chris@76 28 function createWaveFile($word)
Chris@76 29 {
Chris@76 30 global $settings, $user_info, $context;
Chris@76 31
Chris@76 32 // Allow max 2 requests per 20 seconds.
Chris@76 33 if (($ip = cache_get_data('wave_file/' . $user_info['ip'], 20)) > 2 || ($ip2 = cache_get_data('wave_file/' . $user_info['ip2'], 20)) > 2)
Chris@76 34 die(header('HTTP/1.1 400 Bad Request'));
Chris@76 35 cache_put_data('wave_file/' . $user_info['ip'], $ip ? $ip + 1 : 1, 20);
Chris@76 36 cache_put_data('wave_file/' . $user_info['ip2'], $ip2 ? $ip2 + 1 : 1, 20);
Chris@76 37
Chris@76 38 // Fixate randomization for this word.
Chris@76 39 mt_srand(end(unpack('n', md5($word . session_id()))));
Chris@76 40
Chris@76 41 // Try to see if there's a sound font in the user's language.
Chris@76 42 if (file_exists($settings['default_theme_dir'] . '/fonts/sound/a.' . $user_info['language'] . '.wav'))
Chris@76 43 $sound_language = $user_info['language'];
Chris@76 44
Chris@76 45 // English should be there.
Chris@76 46 elseif (file_exists($settings['default_theme_dir'] . '/fonts/sound/a.english.wav'))
Chris@76 47 $sound_language = 'english';
Chris@76 48
Chris@76 49 // Guess not...
Chris@76 50 else
Chris@76 51 return false;
Chris@76 52
Chris@76 53 // File names are in lower case so lets make sure that we are only using a lower case string
Chris@76 54 $word = strtolower($word);
Chris@76 55
Chris@76 56 // Loop through all letters of the word $word.
Chris@76 57 $sound_word = '';
Chris@76 58 for ($i = 0; $i < strlen($word); $i++)
Chris@76 59 {
Chris@76 60 $sound_letter = implode('', file($settings['default_theme_dir'] . '/fonts/sound/' . $word{$i} . '.' . $sound_language . '.wav'));
Chris@76 61 if (strpos($sound_letter, 'data') === false)
Chris@76 62 return false;
Chris@76 63
Chris@76 64 $sound_letter = substr($sound_letter, strpos($sound_letter, 'data') + 8);
Chris@76 65 switch ($word{$i} === 's' ? 0 : mt_rand(0, 2))
Chris@76 66 {
Chris@76 67 case 0:
Chris@76 68 for ($j = 0, $n = strlen($sound_letter); $j < $n; $j++)
Chris@76 69 for ($k = 0, $m = round(mt_rand(15, 25) / 10); $k < $m; $k++)
Chris@76 70 $sound_word .= $word{$i} === 's' ? $sound_letter{$j} : chr(mt_rand(max(ord($sound_letter{$j}) - 1, 0x00), min(ord($sound_letter{$j}) + 1, 0xFF)));
Chris@76 71 break;
Chris@76 72
Chris@76 73 case 1:
Chris@76 74 for ($j = 0, $n = strlen($sound_letter) - 1; $j < $n; $j += 2)
Chris@76 75 $sound_word .= (mt_rand(0, 3) == 0 ? '' : $sound_letter{$j}) . (mt_rand(0, 3) === 0 ? $sound_letter{$j + 1} : $sound_letter{$j}) . (mt_rand(0, 3) === 0 ? $sound_letter{$j} : $sound_letter{$j + 1}) . $sound_letter{$j + 1} . (mt_rand(0, 3) == 0 ? $sound_letter{$j + 1} : '');
Chris@76 76 $sound_word .= str_repeat($sound_letter{$n}, 2);
Chris@76 77 break;
Chris@76 78
Chris@76 79 case 2:
Chris@76 80 $shift = 0;
Chris@76 81 for ($j = 0, $n = strlen($sound_letter); $j < $n; $j++)
Chris@76 82 {
Chris@76 83 if (mt_rand(0, 10) === 0)
Chris@76 84 $shift += mt_rand(-3, 3);
Chris@76 85 for ($k = 0, $m = round(mt_rand(15, 25) / 10); $k < $m; $k++)
Chris@76 86 $sound_word .= chr(min(max(ord($sound_letter{$j}) + $shift, 0x00), 0xFF));
Chris@76 87 }
Chris@76 88 break;
Chris@76 89
Chris@76 90 }
Chris@76 91
Chris@76 92 $sound_word .= str_repeat(chr(0x80), mt_rand(10000, 10500));
Chris@76 93 }
Chris@76 94
Chris@76 95 $data_size = strlen($sound_word);
Chris@76 96 $file_size = $data_size + 0x24;
Chris@76 97 $sample_rate = 16000;
Chris@76 98
Chris@76 99 // Disable compression.
Chris@76 100 ob_end_clean();
Chris@76 101 header('Content-Encoding: none');
Chris@76 102
Chris@76 103 // Output the wav.
Chris@76 104 header('Content-type: audio/x-wav');
Chris@76 105 header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 525600 * 60) . ' GMT');
Chris@76 106 header('Content-Length: ' . ($file_size + 0x08));
Chris@76 107
Chris@76 108 echo pack('nnVnnnnnnnnVVnnnnV', 0x5249, 0x4646, $file_size, 0x5741, 0x5645, 0x666D, 0x7420, 0x1000, 0x0000, 0x0100, 0x0100, $sample_rate, $sample_rate, 0x0100, 0x0800, 0x6461, 0x7461, $data_size), $sound_word;
Chris@76 109
Chris@76 110 // Noting more to add.
Chris@76 111 die();
Chris@76 112 }
Chris@76 113
Chris@76 114 ?>