
jm.audio.io.AudioFileIn Maven / Gradle / Ivy
/*
Copyright (C) 2000 Andrew Sorensen & Andrew Brown
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or any
later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
package jm.audio.io;
import java.io.*;
import jm.audio.AOException;
import java.util.Vector;
import javax.sound.sampled.*;
import java.io.InputStream;
/**
* Audio file reading class for jMusic.
* The class utilises the JavaSound file reading classes.
* It works indepdently of the jMusic audio architecture used
* for rendering scores, and is intended for use by simple file
* manipulation utility programs operating asychronously (non real time).
* This class deals with some the current (at time of writing) incompletness
* in the javaSound package, including converting bytes from a file into
* floats for both big and little endian formats, and support for 24 bit files.
* @author Andrew Brown, Andrew Sorensen and Tim opie
*/
public class AudioFileIn {
// the name of the file to read from.
private String fileName;
// the file object to read from
private File file;
private AudioFileFormat fileFormat;
private AudioFormat format;
// Is the file data little or big endian?
private boolean bigEndian;
// the number of channels in the file, 1 == mono, 2 = stereo etc.
private int channels;
// The file's sample rate as samples per second.
private int sampleRate;
// The number of samples in the file
private long duration;
// The number of bytes long each sample is. 1 = 8 bit, 2 = 16 bit etc.
private int sampleSize;
// Audio intput stream, will hold the byte array of sample data.
private AudioInputStream is;
// the float Array with the sample in it
private float[] sampleData;
// Is the file an audio file?
private boolean audioFileSpecified = true;
/**
* This constructor opens a file and prepares it to be read.
* @param fileName The name of the file to read, e.g., filename.aif
*/
public AudioFileIn(String fileName) {
this.fileName = fileName;
try {
this.file = new File(fileName);
this.fileFormat = AudioSystem.getAudioFileFormat(this.file);
this.format = this.fileFormat.getFormat();
this.bigEndian = this.format.isBigEndian();
channels = format.getChannels();
sampleRate = (int)format.getSampleRate();
this.duration = (long)this.fileFormat.getFrameLength() * this.channels;
this.sampleSize = (format.getSampleSizeInBits())/8;
}catch(UnsupportedAudioFileException uafe) {
System.err.println("jMusic AudioFileIn warning: '" + fileName
+ "' may not be an audio file.");
System.err.println("Reading it in as raw data...");
this.audioFileSpecified = false;
this.channels = 1;
this.sampleSize = 1;
this.sampleRate = 0;
}catch(IOException ioe) {
System.err.println("jMusic AudioFileIn error: Cannot read the specified file: " + fileName);
System.err.println("Most likely the file does not exist at this location. Exiting...");
System.exit(0);
}
}
// get the sample data from the file and put it into a float arrray.
private void readFile() {
if (audioFileSpecified) {
try {
this.is = AudioSystem.getAudioInputStream(this.file);
byte[] tmp = new byte[(int)this.duration * this.sampleSize];
this.is.read(tmp);
this.is.close();
ByteArrayInputStream bis = new ByteArrayInputStream(tmp);
// convert to floats
this.sampleData = new float[(int)this.duration];
byte[] sampleWord = new byte[sampleSize];
for(int i=0; i 0x7F){
ret = ~ret;
ret &= 0x7F;
ret = ~ret + 1;
}
sample = (float)((float)ret/(float)Byte.MAX_VALUE);
break;
case 2:
if(ret > 0x7FFF) {
ret = ~ret;
ret &= 0x7FFF;
ret = ~ret + 1;
}
sample = (float)((float)ret/(float)Short.MAX_VALUE);
break;
case 3:
if(ret > 0x7FFFFF) {
ret = ~ret;
ret &= 0x7FFFFF;
ret = ~ret + 1;
}
sample = (float)((float)ret/8388608f);
break;
case 4:
sample = (float)((double)ret/(double)Integer.MAX_VALUE);
break;
default:
System.err.println("Format not accepted");
}
return sample;
}
/**
* Provides a single array with the raw sample data in the format of the
* source file. Check the number of channels and file type if required.
* @return sampleData the audio data as an array of floating point values.
*/
public float[] getSampleData() {
readFile();
return this.sampleData;
}
/**
* Supplies the number of channels in the audio file/data.
* @return channels The number of audio channels, 1 = mono, 2 = stereo etc.
*/
public int getChannels() {
return this.channels;
}
/**
* Return the type of file, wav, aif, au etc.
* @return fileType The type of file as a string.
*/
public String getFileType() {
if (audioFileSpecified)
return fileFormat.toString();
else return new String("Non-audio");
}
/**
* Access the sample rate.
* @return sampleRate The number of samples per second.
*/
public int getSampleRate() {
return this.sampleRate;
}
/**
* Access the sample size as a number of bits per sample.
* @return bitDepth The number of bits per sample, 8, 16, 24, 32 etc.
*/
public int getSampleBitDepth() {
return this.sampleSize * 8;
}
/**
* Indicates the type of encoding used by the file.
* @return encodingInfo A string containing the encoding type.
*/
public String getEncoding() {
return this.format.getEncoding().toString();
}
/**
* Access the number of samples in the file.
* @return duration - The total number of samples.
*/
public int getDuration() {
return (int)this.duration;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy