View Javadoc

1   /**
2    * Copyright (c) 2011, The University of Southampton and the individual contributors.
3    * All rights reserved.
4    *
5    * Redistribution and use in source and binary forms, with or without modification,
6    * are permitted provided that the following conditions are met:
7    *
8    *   * 	Redistributions of source code must retain the above copyright notice,
9    * 	this list of conditions and the following disclaimer.
10   *
11   *   *	Redistributions in binary form must reproduce the above copyright notice,
12   * 	this list of conditions and the following disclaimer in the documentation
13   * 	and/or other materials provided with the distribution.
14   *
15   *   *	Neither the name of the University of Southampton nor the names of its
16   * 	contributors may be used to endorse or promote products derived from this
17   * 	software without specific prior written permission.
18   *
19   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20   * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21   * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
23   * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25   * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
26   * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27   * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28   * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29   */
30  package org.openimaj.audio.analysis;
31  
32  import java.nio.ByteBuffer;
33  import java.nio.ShortBuffer;
34  
35  import org.openimaj.audio.AudioStream;
36  import org.openimaj.audio.SampleChunk;
37  import org.openimaj.audio.processor.FixedSizeSampleAudioProcessor;
38  
39  /**
40   * 	Calculate the effective sound pressure by calculating the RMS of samples over
41   * 	a temporal window. This will sum across all channels in the sample chunk.
42   * 
43   *	@author Jonathon Hare (jsh2@ecs.soton.ac.uk)
44   */
45  public class EffectiveSoundPressure extends FixedSizeSampleAudioProcessor
46  {
47  	private double rms = 0;
48  
49  	/**
50  	 * Default constructor
51  	 */
52  	public EffectiveSoundPressure()
53  	{
54  		super( 1 );
55  	}
56  
57  	/**
58  	 * 	Contstructor for ad-hoc processing. Note that the window and overlap
59  	 * 	size is given in samples (not in milliseconds as the other constructor).
60  	 * 
61  	 * 	@param windowSizeSamples Size of the processing window in samples
62  	 * 	@param overlapSamples The overlap of the windows in samples
63  	 */
64  	public EffectiveSoundPressure( final int windowSizeSamples, final int overlapSamples )
65  	{
66  		super( windowSizeSamples );
67  		this.setWindowStep( overlapSamples );
68  	}
69  
70  	/**
71  	 * 	Construct with given stream and window parameters. Note that the window
72  	 * 	parameters are given in milliseconds and converted into a number of
73  	 * 	samples by the method.
74  	 * 
75  	 * 	@param stream The audio stream
76  	 * 	@param windowSizeMillis The window size in milliseconds
77  	 * 	@param overlapMillis The overlap between windows in milliseconds
78  	 */
79  	public EffectiveSoundPressure( final AudioStream stream, final int windowSizeMillis,
80  			final int overlapMillis )
81  	{
82  		super( stream, (int) (stream.getFormat().getSampleRateKHz()
83  				* windowSizeMillis * stream.getFormat().getNumChannels()) );
84  		this.setWindowStep( (int) (stream.getFormat().getSampleRateKHz() * 
85  				overlapMillis * stream.getFormat().getNumChannels()) );
86  	}
87  
88  	/**
89  	 *	{@inheritDoc}
90  	 * 	@see org.openimaj.audio.processor.FixedSizeSampleAudioProcessor#process(org.openimaj.audio.SampleChunk)
91  	 */
92  	@Override
93  	public SampleChunk process( final SampleChunk sample ) throws Exception
94  	{
95  		long accum = 0;
96  		final int size;
97  
98  		switch (sample.getFormat().getNBits())
99  		{
100 			case 16:
101 			{
102 				final ShortBuffer b = sample.getSamplesAsByteBuffer().asShortBuffer();
103 				size = b.limit();
104 				for( int x = 0; x < size; x++ )
105 					accum += b.get( x ) * b.get( x );
106 				break;
107 			}
108 			case 8:
109 			{
110 				final ByteBuffer b = sample.getSamplesAsByteBuffer();
111 				size = b.limit();
112 				for( int x = 0; x < size; x++ )
113 					accum += b.get( x ) * b.get( x );
114 				break;
115 			}
116 			default:
117 				throw new Exception( "Unsupported Format" );
118 		}
119 
120 		this.rms = Math.sqrt( (double) accum / (double) size );
121 
122 		return sample;
123 	}
124 
125 	/**
126 	 * @return The effective sound pressure
127 	 */
128 	public double getEffectiveSoundPressure()
129 	{
130 		return this.rms;
131 	}
132 }