Esempio n. 1
0
 /**
  * Generate a wav file given the $letters in the code
  * @todo Add ability to merge 2 sound files together to have random background sounds
  * @param array $letters
  * @return string The binary contents of the wav file
  */
 protected function generateWAV($letters)
 {
     $wavCaptcha = new WavFile();
     $first = true;
     // reading first wav file
     foreach ($letters as $letter) {
         $letter = strtoupper($letter);
         try {
             $l = new WavFile($this->audio_path . '/' . $letter . '.wav');
             if ($first) {
                 // set sample rate, bits/sample, and # of channels for file based on first letter
                 $wavCaptcha->setSampleRate($l->getSampleRate())->setBitsPerSample($l->getBitsPerSample())->setNumChannels($l->getNumChannels());
                 $first = false;
             }
             // append letter to the captcha audio
             $wavCaptcha->appendWav($l);
             // random length of silence between $audio_gap_min and $audio_gap_max
             if ($this->audio_gap_max > 0 && $this->audio_gap_max > $this->audio_gap_min) {
                 $wavCaptcha->insertSilence(mt_rand($this->audio_gap_min, $this->audio_gap_max) / 1000.0);
             }
         } catch (Exception $ex) {
             // failed to open file, or the wav file is broken or not supported
             // 2 wav files were not compatible, different # channels, bits/sample, or sample rate
             throw $ex;
         }
     }
     /********* Set up audio filters *****************************/
     $filters = array();
     if ($this->audio_use_noise == true) {
         // use background audio - find random file
         $noiseFile = $this->getRandomNoiseFile();
         if ($noiseFile !== false && is_readable($noiseFile)) {
             try {
                 $wavNoise = new WavFile($noiseFile, false);
             } catch (Exception $ex) {
                 throw $ex;
             }
             // start at a random offset from the beginning of the wavfile
             // in order to add more randomness
             $randOffset = 0;
             if ($wavNoise->getNumBlocks() > 2 * $wavCaptcha->getNumBlocks()) {
                 $randBlock = mt_rand(0, $wavNoise->getNumBlocks() - $wavCaptcha->getNumBlocks());
                 $wavNoise->readWavData($randBlock * $wavNoise->getBlockAlign(), $wavCaptcha->getNumBlocks() * $wavNoise->getBlockAlign());
             } else {
                 $wavNoise->readWavData();
                 $randOffset = mt_rand(0, $wavNoise->getNumBlocks() - 1);
             }
             $mixOpts = array('wav' => $wavNoise, 'loop' => true, 'blockOffset' => $randOffset);
             $filters[WavFile::FILTER_MIX] = $mixOpts;
             $filters[WavFile::FILTER_NORMALIZE] = $this->audio_mix_normalization;
         }
     }
     if ($this->degrade_audio == true) {
         // add random noise.
         // any noise level below 95% is intensely distorted and not pleasant to the ear
         $filters[WavFile::FILTER_DEGRADE] = mt_rand(95, 98) / 100.0;
     }
     if (!empty($filters)) {
         $wavCaptcha->filter($filters);
         // apply filters to captcha audio
     }
     return $wavCaptcha->__toString();
 }
Esempio n. 2
0
 /**
  * Generate a wav file given the $letters in the code
  *
  * @param array $letters  The letters making up the captcha
  * @return string The audio content in WAV format
  */
 protected function generateWAV($letters)
 {
     $wavCaptcha = new WavFile();
     $first = true;
     // reading first wav file
     if ($this->audio_use_sox && !is_executable($this->sox_binary_path)) {
         throw new Exception("Path to SoX binary is incorrect or not executable");
     }
     foreach ($letters as $letter) {
         $letter = strtoupper($letter);
         try {
             $letter_file = realpath($this->audio_path) . DIRECTORY_SEPARATOR . $letter . '.wav';
             if ($this->audio_use_sox) {
                 $sox_cmd = sprintf("%s %s -t wav - %s", $this->sox_binary_path, $letter_file, $this->getSoxEffectChain());
                 $data = `{$sox_cmd}`;
                 $l = new WavFile();
                 $l->setIgnoreChunkSizes(true);
                 $l->setWavData($data);
             } else {
                 $l = new WavFile($letter_file);
             }
             if ($first) {
                 // set sample rate, bits/sample, and # of channels for file based on first letter
                 $wavCaptcha->setSampleRate($l->getSampleRate())->setBitsPerSample($l->getBitsPerSample())->setNumChannels($l->getNumChannels());
                 $first = false;
             }
             // append letter to the captcha audio
             $wavCaptcha->appendWav($l);
             // random length of silence between $audio_gap_min and $audio_gap_max
             if ($this->audio_gap_max > 0 && $this->audio_gap_max > $this->audio_gap_min) {
                 $wavCaptcha->insertSilence(mt_rand($this->audio_gap_min, $this->audio_gap_max) / 1000.0);
             }
         } catch (Exception $ex) {
             // failed to open file, or the wav file is broken or not supported
             // 2 wav files were not compatible, different # channels, bits/sample, or sample rate
             throw new Exception("Error generating audio captcha on letter '{$letter}': " . $ex->getMessage());
         }
     }
     /********* Set up audio filters *****************************/
     $filters = array();
     if ($this->audio_use_noise == true) {
         // use background audio - find random file
         $wavNoise = false;
         $randOffset = 0;
         /*
         // uncomment to try experimental SoX noise generation.
         // warning: sounds may be considered annoying
         if ($this->audio_use_sox) {
             $duration = $wavCaptcha->getDataSize() / ($wavCaptcha->getBitsPerSample() / 8) /
                         $wavCaptcha->getNumChannels() / $wavCaptcha->getSampleRate();
             $duration = round($duration, 2);
             $wavNoise = new WavFile();
             $wavNoise->setIgnoreChunkSizes(true);
             $noiseData = $this->getSoxNoiseData($duration,
                                                 $wavCaptcha->getNumChannels(),
                                                 $wavCaptcha->getSampleRate(),
                                                 $wavCaptcha->getBitsPerSample());
             $wavNoise->setWavData($noiseData, true);
         
         } else
         */
         if (($noiseFile = $this->getRandomNoiseFile()) !== false) {
             try {
                 $wavNoise = new WavFile($noiseFile, false);
             } catch (Exception $ex) {
                 throw $ex;
             }
             // start at a random offset from the beginning of the wavfile
             // in order to add more randomness
             $randOffset = 0;
             if ($wavNoise->getNumBlocks() > 2 * $wavCaptcha->getNumBlocks()) {
                 $randBlock = mt_rand(0, $wavNoise->getNumBlocks() - $wavCaptcha->getNumBlocks());
                 $wavNoise->readWavData($randBlock * $wavNoise->getBlockAlign(), $wavCaptcha->getNumBlocks() * $wavNoise->getBlockAlign());
             } else {
                 $wavNoise->readWavData();
                 $randOffset = mt_rand(0, $wavNoise->getNumBlocks() - 1);
             }
         }
         if ($wavNoise !== false) {
             $mixOpts = array('wav' => $wavNoise, 'loop' => true, 'blockOffset' => $randOffset);
             $filters[WavFile::FILTER_MIX] = $mixOpts;
             $filters[WavFile::FILTER_NORMALIZE] = $this->audio_mix_normalization;
         }
     }
     if ($this->degrade_audio == true) {
         // add random noise.
         // any noise level below 95% is intensely distorted and not pleasant to the ear
         $filters[WavFile::FILTER_DEGRADE] = mt_rand(95, 98) / 100.0;
     }
     if (!empty($filters)) {
         $wavCaptcha->filter($filters);
         // apply filters to captcha audio
     }
     return $wavCaptcha->__toString();
 }