001/**
002 * Copyright (c) 2011, The University of Southampton and the individual contributors.
003 * All rights reserved.
004 *
005 * Redistribution and use in source and binary forms, with or without modification,
006 * are permitted provided that the following conditions are met:
007 *
008 *   *  Redistributions of source code must retain the above copyright notice,
009 *      this list of conditions and the following disclaimer.
010 *
011 *   *  Redistributions in binary form must reproduce the above copyright notice,
012 *      this list of conditions and the following disclaimer in the documentation
013 *      and/or other materials provided with the distribution.
014 *
015 *   *  Neither the name of the University of Southampton nor the names of its
016 *      contributors may be used to endorse or promote products derived from this
017 *      software without specific prior written permission.
018 *
019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
020 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
021 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
022 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
023 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
024 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
025 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
026 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
027 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
028 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
029 */
030/**
031 *
032 */
033package org.openimaj.audio.samples;
034
035import org.openimaj.audio.AudioFormat;
036import org.openimaj.audio.SampleChunk;
037import org.openimaj.audio.timecode.AudioTimecode;
038
039/**
040 * This class provides a consistent API for access samples of different sizes
041 * (e.g. 8-bit and 16-bit). Subclasses implement get and set methods for samples
042 * in a sample byte buffer. The getters and setters return and take floats in
043 * all cases, so it is up to the implementing class to decide how best to
044 * convert the incoming value to an appropriate value for the sample buffer. The
045 * values given and expected should be normalised between
046 * {@link Integer#MAX_VALUE} and {@link Integer#MIN_VALUE}. Despite using
047 * floats, this allows us to detect clipping. Return values are signed such that
048 * an empty signal has sample value 0. If the audio has multiple channels they
049 * will occur in the same order as the original file (likely to be multiplexed -
050 * so <c>get(0)</c> will be channel 1 and <c>get(1)</c> will be channel 2,
051 * etc.).
052 *
053 * @author David Dupplaw (dpd@ecs.soton.ac.uk)
054 * @created 23rd November 2011
055 */
056public interface SampleBuffer extends Iterable<Float> {
057        /**
058         * Get the sample at the given index. The sample will be a float and have a
059         * value between {@link Integer#MAX_VALUE} and {@link Integer#MIN_VALUE}.
060         * That sample will be signed.
061         *
062         * @param index
063         *            The index of the sample to retrieve
064         * @return The sample value as an float
065         */
066        public float get(int index);
067
068        /**
069         * Set the sample value at the given index. The sample value should be
070         * scaled between {@link Integer#MAX_VALUE} and {@link Integer#MIN_VALUE}
071         * (i.e. it should be signed).
072         *
073         * @param index
074         *            The index of the sample to set.
075         * @param sample
076         *            The sample value to set.
077         */
078        public void set(int index, float sample);
079
080        /**
081         * Returns the size of this buffer. Divide by the number of channels to get
082         * the number of samples per channel.
083         *
084         * @return the size of this buffer.
085         */
086        public int size();
087
088        /**
089         * Returns the audio format for this set of samples.
090         *
091         * @return The {@link AudioFormat} for this set of samples.
092         */
093        public AudioFormat getFormat();
094
095        /**
096         * Reset the audio format for the samples in this buffer.
097         *
098         * @param af
099         *            The {@link AudioFormat}
100         */
101        public void setFormat(AudioFormat af);
102
103        /**
104         * Return a sample chunk that contains the data from this sample buffer.
105         * Note that any timestamps will be unset in the new sample chunk.
106         *
107         * @return A {@link SampleChunk} containing data in this buffer.
108         */
109        public SampleChunk getSampleChunk();
110
111        /**
112         * Return a sample chunk that contains the data from a specific channel in
113         * this sample buffer. The channel is numbered from 0 (so mono audio streams
114         * will only have 1 channel accessed with getSampleChunk(0)).
115         *
116         * Note that any timestamps will be unset in the new sample chunk.
117         *
118         * @param channel
119         *            The channel
120         *
121         * @return A {@link SampleChunk} containing data in this buffer.
122         */
123        public SampleChunk getSampleChunk(int channel);
124
125        /**
126         * Returns the normalised (0..1) sample buffer data as a double array.
127         *
128         * @return A double array containing the normalised samples
129         */
130        public double[] asDoubleArray();
131
132        /**
133         * Returns the samples in their channels as normalise (0..1) sample buffer
134         * data.
135         *
136         * @return The array where the first dimension is the channels.
137         */
138        public float[][] asFloatChannelArray();
139
140        /**
141         * Returns the normalised (0..1) sample buffer data as a float array.
142         *
143         * @return A double array containing the normalised samples
144         */
145        public float[] asFloatArray();
146
147        /**
148         * Returns the samples in their channels as normalise (0..1) sample buffer
149         * data.
150         *
151         * @return The array where the first dimension is the channels.
152         */
153        public double[][] asDoubleChannelArray();
154
155        /**
156         * Returns the sample value at the given index without scaling - that is, at
157         * it's original sample value. This can be useful for debugging, or if the
158         * sample buffer is being used for non-audio applications.
159         *
160         * @param index
161         *            The index to retrieve
162         * @return The value unscaled
163         */
164        public float getUnscaled(int index);
165
166        /**
167         * Returns the timecode of the start of this sample buffer. May return null
168         * if the timecode is unknown or has no meaning in this context.
169         *
170         * @return The timecode a the start of this buffer.
171         */
172        public AudioTimecode getStartTimecode();
173}