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; 034 035/** 036 * This class encapsulates the information that determines the format 037 * of audio data. 038 * 039 * @author David Dupplaw (dpd@ecs.soton.ac.uk) 040 * @created 8 Jun 2011 041 * 042 */ 043public class AudioFormat 044{ 045 /** The number of channels for each sample */ 046 private int nChannels = 0; 047 048 /** The number of bits in each sample */ 049 private int nBits = 0; 050 051 /** The sample rate in KHz */ 052 private double sampleRateKHz = 0; 053 054 /** Whether the data is signed */ 055 private boolean isSigned = true; 056 057 /** Whether the data is big-endian */ 058 private boolean isBigEndian = false; 059 060 /** 061 * Construct a new audio format object with the 062 * given number of bits and sample rate. 063 * 064 * @param nBits The number of bits in each sample 065 * @param sampleRate The sample rate in kilohertz 066 * @param nChannels The number of channels 067 */ 068 public AudioFormat( int nBits, double sampleRate, int nChannels ) 069 { 070 this.nBits = nBits; 071 this.sampleRateKHz = sampleRate; 072 this.setNumChannels( nChannels ); 073 } 074 075 /** 076 * Get the number of bits in each sample. 077 * @return The number of bits in each sample. 078 */ 079 public int getNBits() 080 { 081 return nBits; 082 } 083 084 /** 085 * Sets the number of bits in this audio format. This is expected to 086 * be a multiple of 8, but can be -1 for a non-integer format. 087 * 088 * @param nBits The number of bits. 089 * @return this audio format 090 */ 091 public AudioFormat setNBits( int nBits ) 092 { 093 this.nBits = nBits; 094 return this; 095 } 096 097 /** 098 * Get the rate at which the audio should be replayed 099 * @return The audio sample rate in kilohertz. 100 */ 101 public double getSampleRateKHz() 102 { 103 return sampleRateKHz; 104 } 105 106 /** 107 * Set the sample rate at which the audio should be replayed 108 * @param s The sample rate 109 * @return this audio format 110 */ 111 public AudioFormat setSampleRateKHz( double s ) 112 { 113 this.sampleRateKHz = s; 114 return this; 115 } 116 117 /** 118 * Set the number of channels in this format. 119 * @param nChannels the number of channels 120 * @return this audio format 121 */ 122 public AudioFormat setNumChannels( int nChannels ) 123 { 124 this.nChannels = nChannels; 125 return this; 126 } 127 128 /** 129 * Get the number of channels in this format. 130 * @return the number of channels 131 */ 132 public int getNumChannels() 133 { 134 return nChannels; 135 } 136 137 /** 138 * Set whether the data is signed or not. 139 * @param isSigned Whether the data is signed. 140 * @return this audio format 141 */ 142 public AudioFormat setSigned( boolean isSigned ) 143 { 144 this.isSigned = isSigned; 145 return this; 146 } 147 148 /** 149 * Returns whether the data is signed or unsigned. 150 * @return TRUE if the data is signed; FALSE otherwise; 151 */ 152 public boolean isSigned() 153 { 154 return isSigned; 155 } 156 157 /** 158 * Set whether the data is big-endian or not. 159 * @param isBigEndian Whether the data is big-endian 160 * @return this audio format 161 */ 162 public AudioFormat setBigEndian( boolean isBigEndian ) 163 { 164 this.isBigEndian = isBigEndian; 165 return this; 166 } 167 168 /** 169 * Returns whether the data is big or little endian. 170 * @return TRUE if the data is big-endian; FALSE if little-endian 171 */ 172 public boolean isBigEndian() 173 { 174 return isBigEndian; 175 } 176 177 /** 178 * {@inheritDoc} 179 */ 180 @Override 181 public String toString() 182 { 183 return "[Audio: "+getSampleRateKHz()+"KHz, "+getNBits()+"bit, "+ 184 getNumChannels()+" channel"+(getNumChannels()>1?"s":"")+ 185 ", "+(isSigned?"signed":"unsigned")+", "+ 186 (isBigEndian?"big-endian":"little-endian")+"]"; 187 } 188 189 /** 190 * {@inheritDoc} 191 * @see java.lang.Object#equals(java.lang.Object) 192 */ 193 @Override 194 public boolean equals( Object obj ) 195 { 196 if( obj instanceof AudioFormat ) 197 { 198 AudioFormat af = (AudioFormat)obj; 199 if( isBigEndian == af.isBigEndian && 200 isSigned == af.isSigned && 201 nChannels == af.nChannels && 202 nBits == af.nBits && 203 sampleRateKHz == af.sampleRateKHz ) 204 return true; 205 } 206 207 return false; 208 } 209 210 /** 211 * {@inheritDoc} 212 */ 213 @Override 214 public AudioFormat clone() 215 { 216 AudioFormat af = new AudioFormat( 217 getNBits(), getSampleRateKHz(), getNumChannels() ); 218 af.setBigEndian( isBigEndian ); 219 af.setSigned( isSigned ); 220 return af; 221 } 222 223 /** 224 * Get a Java Sound API AudioFormat object using this object's 225 * properties. 226 * 227 * @return The Java Sound API Audio Format object. 228 */ 229 public javax.sound.sampled.AudioFormat getJavaAudioFormat() 230 { 231 // Convert the OpenIMAJ audio format to a Java Sound audio format object 232 return new javax.sound.sampled.AudioFormat( 233 (int)this.getSampleRateKHz() * 1000, 234 this.getNBits(), this.getNumChannels(), 235 this.isSigned(), this.isBigEndian() ); 236 } 237}