示例#1
0
 /**
  * Convert sample data to different bits per sample.
  *
  * @param int $bitsPerSample  (Required) The new number of bits per sample;
  * @throws WavFileException
  */
 public function convertBitsPerSample($bitsPerSample)
 {
     if ($this->getBitsPerSample() == $bitsPerSample) {
         return $this;
     }
     $tempWav = new WavFile($this->getNumChannels(), $this->getSampleRate(), $bitsPerSample);
     $tempWav->filter(array(self::FILTER_MIX => $this), 0, $this->getNumBlocks());
     $this->setSamples()->setBitsPerSample($bitsPerSample);
     // implicit setValidBitsPerSample(), setAudioFormat(), setAudioSubFormat(), setFmtChunkSize(), setFactChunkSize(), setSize(), setActualSize(), setDataOffset(), setByteRate(), setBlockAlign(), setNumBlocks()
     $this->_samples = $tempWav->_samples;
     $this->setDataSize();
     // implicit setSize(), setActualSize(), setNumBlocks()
     return $this;
 }
示例#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();
 }
示例#3
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();
 }
示例#4
0
 protected function _createAudio()
 {
     if (is_null($this->_key)) {
         throw new \Exception('Key must be generated');
     }
     // TODO need get IT, DE and ES audio files
     //http://www.gilles-joyeux.fr/MP3/NEn.mp3 letters
     //http://www.gilles-joyeux.fr/MP3/ten.mp3 numbers
     // revoir les sons S et F en anglais ...
     try {
         $globalWavFile = new \WavFile();
         // Set sample rate, bits/sample, and Num of channels // TODO setter and getter this params ?
         $globalWavFile->setSampleRate(8000);
         $globalWavFile->setBitsPerSample(8);
         $globalWavFile->setNumChannels(1);
         $letters = str_split(strtoupper($this->_key));
         foreach ($letters as $letter) {
             if (!file_exists($this->_audioLangDirectory . $letter . '.wav')) {
                 throw new \Exception('Audio file : "' . $this->_audioLangDirectory . $letter . '.wav' . '" miss');
             }
             $l = new \WavFile($this->_audioLangDirectory . $letter . '.wav');
             // append letter to the captcha audio
             $globalWavFile->appendWav($l);
             // random silence  between letters
             $globalWavFile->insertSilence(mt_rand($this->_audioLettersGapMin, $this->_audioLettersGapMax) / 1000.0);
             //rand min and max
         }
         // Add filters
         $filters = array();
         // noise by sound file
         if ($this->_audioNoise) {
             // use background audio
             $wavNoise = new \WavFile($this->_audioNoiseFile, false);
             $wavNoise->setSampleRate($globalWavFile->getSampleRate())->setBitsPerSample($globalWavFile->getBitsPerSample())->setNumChannels($globalWavFile->getNumChannels());
             // start at a random offset from the beginning of the wav file in order to add more randomness
             $randOffset = 0;
             if ($wavNoise->getNumBlocks() > 2 * $globalWavFile->getNumBlocks()) {
                 $randBlock = rand(0, $wavNoise->getNumBlocks() - $globalWavFile->getNumBlocks());
                 $wavNoise->readWavData($randBlock * $wavNoise->getBlockAlign(), $globalWavFile->getNumBlocks() * $wavNoise->getBlockAlign());
             } else {
                 $wavNoise->readWavData();
                 $randOffset = rand(0, $wavNoise->getNumBlocks() - 1);
             }
             $mixOpts = array('wav' => $wavNoise, 'loop' => true, 'blockOffset' => $randOffset);
             $filters[\WavFile::FILTER_MIX] = $mixOpts;
             $filters[\WavFile::FILTER_NORMALIZE] = $this->_audioNoiseMixNormalization;
         }
         // add random noise. Any noise level below 95% is intensely distorted and not pleasing to the ear
         if ($this->_audioDegrade) {
             $filters[\WavFile::FILTER_DEGRADE] = rand(95, 98) / 100.0;
         }
         // apply filters to audio file
         if (count($filters) > 0) {
             $globalWavFile->filter($filters);
         }
         // save
         $this->_audioContents = $globalWavFile->makeHeader();
         $this->_audioContents .= $globalWavFile->getDataSubchunk();
         unset($globalWavFile);
     } catch (\Exception $e) {
         Logger::getInstance()->debug('Security captcha generate audio file for form : "' . $this->getFormName() . '" error : "' . $e . '"', 'security');
         if (file_exists($this->_audioLangDirectory . 'error.wav')) {
             $this->_audioContents = file_get_contents($this->_audioLangDirectory . 'error.wav');
         }
     }
 }