Coverage Report - fr.paris.lutece.plugins.captcha.modules.jcaptcha.service.sound.filter.EchoFilter
 
Classes in this File Line Coverage Branch Coverage Complexity
EchoFilter
0 %
0/32
0 %
0/14
2,75
 
 1  
 /*
 2  
  * Copyright (c) 2002-2014, Mairie de Paris
 3  
  * All rights reserved.
 4  
  *
 5  
  * Redistribution and use in source and binary forms, with or without
 6  
  * modification, are permitted provided that the following conditions
 7  
  * are met:
 8  
  *
 9  
  *  1. Redistributions of source code must retain the above copyright notice
 10  
  *     and the following disclaimer.
 11  
  *
 12  
  *  2. Redistributions in binary form must reproduce the above copyright notice
 13  
  *     and the following disclaimer in the documentation and/or other materials
 14  
  *     provided with the distribution.
 15  
  *
 16  
  *  3. Neither the name of 'Mairie de Paris' nor 'Lutece' nor the names of its
 17  
  *     contributors may be used to endorse or promote products derived from
 18  
  *     this software without specific prior written permission.
 19  
  *
 20  
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 21  
  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 22  
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 23  
  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
 24  
  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 25  
  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 26  
  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 27  
  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 28  
  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 29  
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 30  
  * POSSIBILITY OF SUCH DAMAGE.
 31  
  *
 32  
  * License 1.0
 33  
  */
 34  
 package fr.paris.lutece.plugins.captcha.modules.jcaptcha.service.sound.filter;
 35  
 
 36  
 import fr.paris.lutece.plugins.captcha.modules.jcaptcha.service.sound.LuteceWordToSound;
 37  
 
 38  
 
 39  
 /**
 40  
  *
 41  
  */
 42  
 public class EchoFilter extends SoundFilter
 43  
 {
 44  
     private short[] _delayBuffer;
 45  
     private int _delayBufferPos;
 46  
     private float _decay;
 47  
 
 48  
     /**
 49  
      * Creates an EchoFilter with the specified number of delay samples and the
 50  
      * specified decay rate.
 51  
      * <p>
 52  
      * The number of delay samples specifies how long before the echo is
 53  
      * initially heard. For a 1 second echo with mono, 44100Hz sound, use 44100
 54  
      * delay samples.
 55  
      * <p>
 56  
      * The decay value is how much the echo has decayed from the source. A decay
 57  
      * value of .5 means the echo heard is half as loud as the source.
 58  
      *
 59  
      * @param echoDelay the echoDelay
 60  
      * @param decay the decay
 61  
      */
 62  
     public EchoFilter( float echoDelay, float decay )
 63  0
     {
 64  0
         int numSampleDelay = ( Math.round( LuteceWordToSound.getSoundsSampleRate( ) * ( echoDelay / 1000 ) ) +
 65  
             1 );
 66  0
         _delayBuffer = new short[numSampleDelay];
 67  0
         _decay = decay / 100;
 68  0
     }
 69  
 
 70  
     /**
 71  
      * Gets the remaining size, in bytes, of samples that this filter can echo
 72  
      * after the sound is done playing. Ensures that the sound will have decayed
 73  
      * to below 1% of maximum volume (amplitude).
 74  
      *
 75  
      * @return the Remaining Size
 76  
      */
 77  
     public int getRemainingSize(  )
 78  
     {
 79  0
         float finalDecay = 0.01f;
 80  
 
 81  
         // derived from Math.pow(decay,x) <= finalDecay
 82  0
         int numRemainingBuffers = (int) Math.ceil( Math.log( finalDecay ) / Math.log( _decay ) );
 83  0
         int bufferSize = _delayBuffer.length;
 84  
 
 85  0
         return bufferSize * numRemainingBuffers;
 86  
     }
 87  
 
 88  
     /**
 89  
      * Clears this EchoFilter's internal delay buffer.
 90  
      */
 91  
     public void reset(  )
 92  
     {
 93  0
         for ( int i = 0; i < _delayBuffer.length; i++ )
 94  
         {
 95  0
             _delayBuffer[i] = 0;
 96  
         }
 97  
 
 98  0
         _delayBufferPos = 0;
 99  0
     }
 100  
 
 101  
     /**
 102  
      * Filters the sound samples to add an echo. The samples played are added to
 103  
      * the sound in the delay buffer multipied by the decay rate. The result is
 104  
      * then stored in the delay buffer, so multiple echoes are heard.
 105  
      *
 106  
      * @param samples the samples
 107  
      * @param offset the offset
 108  
      * @param length the length
 109  
      * @param sampleSizeInBits the sample size in bits
 110  
      */
 111  
     public void filter( byte[] samples, int offset, int length, int sampleSizeInBits )
 112  
     {
 113  0
         if ( sampleSizeInBits == SAMPLE_SIZE_8_BIT )
 114  
         {
 115  0
             for ( int i = offset; i < ( offset + length ); i++ )
 116  
             {
 117  
                 // update the sample
 118  0
                 short oldSample = get8bitSample( samples, i );
 119  0
                 short newSample = (short) ( oldSample + ( _decay * _delayBuffer[_delayBufferPos] ) );
 120  0
                 set8bitSample( samples, i, newSample );
 121  
                 // update the delay buffer
 122  0
                 _delayBuffer[_delayBufferPos] = newSample;
 123  0
                 _delayBufferPos++;
 124  
 
 125  0
                 if ( _delayBufferPos == _delayBuffer.length )
 126  
                 {
 127  0
                     _delayBufferPos = 0;
 128  
                 }
 129  
             }
 130  
         }
 131  0
         else if ( sampleSizeInBits == SAMPLE_SIZE_16_BIT )
 132  
         {
 133  0
             for ( int i = offset; i < ( offset + length ); i += 2 )
 134  
             {
 135  
                 // update the sample
 136  0
                 short oldSample = get16bitSample( samples, i );
 137  0
                 short newSample = (short) ( oldSample + ( _decay * _delayBuffer[_delayBufferPos] ) );
 138  0
                 set16bitSample( samples, i, newSample );
 139  
                 // update the delay buffer
 140  0
                 _delayBuffer[_delayBufferPos] = newSample;
 141  0
                 _delayBufferPos++;
 142  
 
 143  0
                 if ( _delayBufferPos == _delayBuffer.length )
 144  
                 {
 145  0
                     _delayBufferPos = 0;
 146  
                 }
 147  
             }
 148  
         }
 149  0
     }
 150  
 }