/** * The sum of the Hanning window * @param samples A representative sample * @return The sum of the hanning window */ public double getWindowSum( final SampleChunk samples ) { return this.getWindowSum( samples.getNumberOfSamples() / samples.getFormat().getNumChannels(), samples.getFormat().getNumChannels() ); }
@Override public AudioFormat getFormat() { final SampleChunk sc = this.nextSampleChunk(); this.reset(); return sc.getFormat(); } };
/** * Appends the given samples to the end of this sample chunk. It is expected * that the given samples are in the same format as this sample chunk; if * they are not an exception is thrown. Side-affects this sample chunk and * will return a reference to this sample chunk. * * @param sample * the samples to add * @return This sample chunk with the bytes appended */ public SampleChunk append(final SampleChunk sample) { // Check the sample formats are the same if (!sample.getFormat().equals(this.format)) throw new IllegalArgumentException("Sample types are not equivalent"); // Get the samples from the given chunk final byte[] x1 = sample.getSamplesAsByteBuffer().array(); // Create an array for the concatenated pair final byte[] newSamples = new byte[this.samples.length + x1.length]; synchronized (this.samples) { System.arraycopy(this.samples, 0, newSamples, 0, this.samples.length); } System.arraycopy(x1, 0, newSamples, this.samples.length, x1.length); // Update this object this.samples = newSamples; return this; }
/** * Generate a cache of the COS function used for the Hanning. * @param sample An example of the sample that will have the Hanning * function applied. */ private void generateWeightTableCache( final SampleChunk sample ) { this.generateWeightTableCache( sample.getNumberOfSamples()/sample.getFormat().getNumChannels(), sample.getFormat().getNumChannels() ); }
/** * Generate a cache of the COS function used for the Hanning. * @param sample An example of the sample that will have the Hanning * function applied. */ private void generateWeightTableCache( final SampleChunk sample ) { this.generateWeightTableCache( sample.getNumberOfSamples()/sample.getFormat().getNumChannels(), sample.getFormat().getNumChannels() ); }
/** * The sum of the Hanning window * @param samples A representative sample * @return The sum of the hanning window */ public double getWindowSum( final SampleChunk samples ) { return this.getWindowSum( samples.getNumberOfSamples() / samples.getFormat().getNumChannels(), samples.getFormat().getNumChannels() ); }
@Override public AudioFormat getFormat() { final SampleChunk sc = this.nextSampleChunk(); this.reset(); return sc.getFormat(); } };
/** * {@inheritDoc} * @see org.openimaj.audio.processor.AudioProcessor#process(org.openimaj.audio.SampleChunk) */ @Override public SampleChunk process( final SampleChunk sample ) throws Exception { if( sample.getFormat().getSampleRateKHz() != this.outputFormat.getSampleRateKHz() ) throw new IllegalArgumentException( "The sample rate of the " + "output format is not the same as the sample chunk. Use a " + "sample rate converter first before using the bit depth" + "converter." ); if( sample.getFormat().getNumChannels() != this.outputFormat.getNumChannels() ) throw new IllegalArgumentException( "The number of channels in the " + "output format is not the same as the sample chunk. Use a " + "channel converter first before using the bit-depth " + "converter." ); if( sample.getFormat().getNBits() == this.outputFormat.getNBits() ) return sample; final SampleChunk sc = this.bitDepthConverter.process( sample, this.outputFormat ); sc.setStartTimecode( sample.getStartTimecode() ); return sc; } }
/** * {@inheritDoc} * @see org.openimaj.audio.processor.AudioProcessor#process(org.openimaj.audio.SampleChunk) */ @Override public SampleChunk process( final SampleChunk sample ) throws Exception { if( sample.getFormat().getNBits() != this.outputFormat.getNBits() ) throw new IllegalArgumentException( "The number of bits in the " + "output format is not the same as the sample chunk. Use a " + "resampling conversion first before using the sample-rate " + "converter." ); if( sample.getFormat().getNumChannels() != this.outputFormat.getNumChannels() ) throw new IllegalArgumentException( "The number of channels in the " + "output format is not the same as the sample chunk. Use a " + "channel converter first before using the sample-rate " + "converter." ); if( sample.getFormat().getSampleRateKHz() == this.outputFormat.getSampleRateKHz() ) return sample; final SampleChunk sc = this.sampleConverter.process( sample, this.outputFormat ); sc.setStartTimecode( sample.getStartTimecode() ); return sc; } }
/** * {@inheritDoc} * @see org.openimaj.audio.processor.AudioProcessor#process(org.openimaj.audio.SampleChunk) */ @Override public SampleChunk process( final SampleChunk sample ) throws Exception { if( sample.getFormat().getNBits() != this.outputFormat.getNBits() ) throw new IllegalArgumentException( "The number of bits in the " + "output format is not the same as the sample chunk. Use a " + "resampling conversion first before using the sample-rate " + "converter." ); if( sample.getFormat().getNumChannels() != this.outputFormat.getNumChannels() ) throw new IllegalArgumentException( "The number of channels in the " + "output format is not the same as the sample chunk. Use a " + "channel converter first before using the sample-rate " + "converter." ); if( sample.getFormat().getSampleRateKHz() == this.outputFormat.getSampleRateKHz() ) return sample; final SampleChunk sc = this.sampleConverter.process( sample, this.outputFormat ); sc.setStartTimecode( sample.getStartTimecode() ); return sc; } }
/** * {@inheritDoc} * @see org.openimaj.audio.processor.AudioProcessor#process(org.openimaj.audio.SampleChunk) */ @Override public SampleChunk process( final SampleChunk sample ) throws Exception { if( sample.getFormat().getSampleRateKHz() != this.outputFormat.getSampleRateKHz() ) throw new IllegalArgumentException( "The sample rate of the " + "output format is not the same as the sample chunk. Use a " + "sample rate converter first before using the bit depth" + "converter." ); if( sample.getFormat().getNumChannels() != this.outputFormat.getNumChannels() ) throw new IllegalArgumentException( "The number of channels in the " + "output format is not the same as the sample chunk. Use a " + "channel converter first before using the bit-depth " + "converter." ); if( sample.getFormat().getNBits() == this.outputFormat.getNBits() ) return sample; final SampleChunk sc = this.bitDepthConverter.process( sample, this.outputFormat ); sc.setStartTimecode( sample.getStartTimecode() ); return sc; } }
/** * {@inheritDoc} * @see org.openimaj.audio.processor.AudioProcessor#process(org.openimaj.audio.SampleChunk) */ @Override public SampleChunk process( final SampleChunk sample ) throws Exception { if( this.filters == null ) { this.format = sample.getFormat(); this.setupFilters(); } this.outputPower = 0; for( final FeedForwardCombFilter filter : this.filters ) { // Process the sample with each filter filter.process( sample ); this.outputPower += filter.getOutputPower(); } return sample; }
/** * {@inheritDoc} * @see org.openimaj.audio.processor.AudioProcessor#process(org.openimaj.audio.SampleChunk) */ @Override public SampleChunk process( final SampleChunk sample ) throws Exception { if( this.filters == null ) { this.format = sample.getFormat(); this.setupFilters(); } this.outputPower = 0; for( final FeedForwardCombFilter filter : this.filters ) { // Process the sample with each filter filter.process( sample ); this.outputPower += filter.getOutputPower(); } return sample; }
/** * {@inheritDoc} * @see org.openimaj.audio.processor.FixedSizeSampleAudioProcessor#process(org.openimaj.audio.SampleChunk) */ @Override public SampleChunk process( final SampleChunk sample ) throws Exception { final SampleBuffer sb = sample.getSampleBuffer(); for( int c = 0; c < sample.getFormat().getNumChannels(); c++ ) { float acc = 0; for( int i = 0; i < this.coefficients.length; i++ ) acc += sb.get(i) * this.coefficients[i]; sb.set( 0, acc ); } return sample; } }
/** * {@inheritDoc} * @see org.openimaj.audio.processor.FixedSizeSampleAudioProcessor#process(org.openimaj.audio.SampleChunk) */ @Override public SampleChunk process( final SampleChunk sample ) throws Exception { final SampleBuffer sb = sample.getSampleBuffer(); for( int c = 0; c < sample.getFormat().getNumChannels(); c++ ) { float acc = 0; for( int i = 0; i < this.coefficients.length; i++ ) acc += sb.get(i) * this.coefficients[i]; sb.set( 0, acc ); } return sample; } }
/** * Processes a single sample chunk: calculates the FFT, gets the magnitudes, * copies the format (if it's the first chunk), and then goes on to update the image. * * @param s The sample chunk to process */ public void process( final SampleChunk s ) { // Process the FFT this.fftp.process( s.getSampleBuffer() ); // Get the magnitudes to show in the spectrogram final float[] f = this.fftp.getNormalisedMagnitudes( 1f/Integer.MAX_VALUE )[0]; // Store the format of this sample chunk if we don't have one yet. // This allows us to continue to draw the frequency bands on the image // (if it's configured to do that). if( this.audioFormat == null ) this.audioFormat = s.getFormat().clone(); // Store this FFT into the data member. Note this calls a method in this class. this.setData( f ); }
@Override public SampleChunk nextSampleChunk() { if( this.listIndex >= samples.size() ) return null; if( this.l == null || this.index >= this.l.size() ) { this.l = samples.get(this.listIndex); this.index = 0; this.listIndex++; this.timecodeOffset += this.currentTimecode; } // Get the current sample chunk final SampleChunk sc = this.l.get(this.index).getSampleChunk(); // Work out the timecode at the end of the sample chunk this.currentTimecode = (long)(sc.getStartTimecode().getTimecodeInMilliseconds() + sc.getNumberOfSamples() / sc.getFormat().getSampleRateKHz()); // Add the offset into the current timecode. sc.getStartTimecode().setTimecodeInMilliseconds( sc.getStartTimecode().getTimecodeInMilliseconds() + this.timecodeOffset ); this.index++; return sc; }
private void fireFrequencyEvent(final float[] fft,final SampleChunk sample) { final double binSize = (sample.getFormat().getSampleRateKHz()*1000) / (fft.length/2); if(this.fftReal == null || fft.length/4 != this.fftReal.length){ this.fftReal = new float[fft.length/4]; this.fftImag = new float[fft.length/4]; } // Extract the spectra for( int i = 0; i < fft.length/4; i++ ) { final float re = fft[i*2]; final float im = fft[i*2+1]; this.fftReal[i] = re; this.fftImag[i] = im; } for(final IndependentPair<Listener,Pair<Integer>> l : this.listeners){ final Pair<Integer> range = l.secondObject(); final int low = (int) (range.firstObject()/binSize); final int high = (int) (range.secondObject()/binSize); l.firstObject().consumeFrequency(this.fftReal,this.fftImag,low,high); } }
private void fireFrequencyEvent(final float[] fft,final SampleChunk sample) { final double binSize = (sample.getFormat().getSampleRateKHz()*1000) / (fft.length/2); if(this.fftReal == null || fft.length/4 != this.fftReal.length){ this.fftReal = new float[fft.length/4]; this.fftImag = new float[fft.length/4]; } // Extract the spectra for( int i = 0; i < fft.length/4; i++ ) { final float re = fft[i*2]; final float im = fft[i*2+1]; this.fftReal[i] = re; this.fftImag[i] = im; } for(final IndependentPair<Listener,Pair<Integer>> l : this.listeners){ final Pair<Integer> range = l.secondObject(); final int low = (int) (range.firstObject()/binSize); final int high = (int) (range.secondObject()/binSize); l.firstObject().consumeFrequency(this.fftReal,this.fftImag,low,high); } }
@Override public SampleChunk nextSampleChunk() { if( this.listIndex >= samples.size() ) return null; if( this.l == null || this.index >= this.l.size() ) { this.l = samples.get(this.listIndex); this.index = 0; this.listIndex++; this.timecodeOffset += this.currentTimecode; } // Get the current sample chunk final SampleChunk sc = this.l.get(this.index).getSampleChunk(); // Work out the timecode at the end of the sample chunk this.currentTimecode = (long)(sc.getStartTimecode().getTimecodeInMilliseconds() + sc.getNumberOfSamples() / sc.getFormat().getSampleRateKHz()); // Add the offset into the current timecode. sc.getStartTimecode().setTimecodeInMilliseconds( sc.getStartTimecode().getTimecodeInMilliseconds() + this.timecodeOffset ); this.index++; return sc; }