Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/344.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 将wav/wave文件读入短[]数组_Java_Wav_Javasound - Fatal编程技术网

Java 将wav/wave文件读入短[]数组

Java 将wav/wave文件读入短[]数组,java,wav,javasound,Java,Wav,Javasound,是否有将wav文件读入短[]数组的api? 我正在尝试将wav文件读入短数组 我找不到任何用于此的内置API通过AudioInputStream将其引入,就像通常用于声音一样 对于从流中获取的每个缓冲区负载,一次迭代两个字节(如果是16位编码),并使用您喜欢的算法将这两个字节转换为单个短整数(取决于文件是Big-Endian还是Little-Endian) 然后,通过附加到首选的短数组形式保存结果,而不是像在更常见的播放情况下那样发布到SourceDataLine 引用Java教程: 因为Jav

是否有将wav文件读入短[]数组的api? 我正在尝试将wav文件读入短数组


我找不到任何用于此的内置API

通过AudioInputStream将其引入,就像通常用于声音一样

对于从流中获取的每个缓冲区负载,一次迭代两个字节(如果是16位编码),并使用您喜欢的算法将这两个字节转换为单个短整数(取决于文件是Big-Endian还是Little-Endian)

然后,通过附加到首选的短数组形式保存结果,而不是像在更常见的播放情况下那样发布到SourceDataLine

引用Java教程:

因为JavaSoundAPI让您可以作为一个用户访问音频数据 字节数组,您可以选择任何方式更改这些字节

您可以查看Java声音教程“读取声音文件”一节中的代码,并注意注释:“在这里,对音频字节数组中的音频数据做一些有用的操作…”

例如,有用的东西可能是:

    myShortArray[i] = (short)(( buffer[i*2] & 0xff )|( buffer[i*2 + 1] << 8 ));

myshortaray[i]=(short)((buffer[i*2]&0xff)|(buffer[i*2+1])好的,我就是这么做的

public static void main(String[] args) {
    try {
        File srcFile = new File("test.wav");
        FileInputStream in = new FileInputStream(srcFile);
        ObjectOutputStream output =  new ObjectOutputStream(new FileOutputStream("gilad-OutPut.bin"));
        byte[] buf = new byte[80000];
        short[] shortArr = new short[buf.length/2];
        in.read(buf);
        for (int i = 0; i <buf.length/2 ; i++)
        {
            output.writeShort( (short)( ( buf[i*2] & 0xff )|( buf[i*2 + 1] << 8 ) ) );
            shortArr[i] = ( (short)( ( buf[i*2] & 0xff )|( buf[i*2 + 1] << 8 ) ) );
        }

        in.close();

    } catch (Exception e) {
        System.err.println(e);
    }

}
publicstaticvoidmain(字符串[]args){
试一试{
File srcFile=新文件(“test.wav”);
FileInputStream in=新的FileInputStream(srcFile);
ObjectOutputStream输出=新的ObjectOutputStream(新的FileOutputStream(“gilad output.bin”);
字节[]buf=新字节[80000];
short[]shortArr=新的short[buf.长度/2];
in.read(buf);

对于(int i=0;i这一个很好,对android也很好:

我已经加入了阅读短文和阅读频道短文

必须删除缩进以符合字符限制

Wave.java:

package com.doodkin.learnwave;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;

//from: http://www.labbookpages.co.uk/audio/javaWavFiles.html
//added short and readchannel

public class Wave {
// Wav file IO class
// A.Greensted
// http://www.labbookpages.co.uk

// File format is based on the information from
// http://www.sonicspot.com/guide/wavefiles.html
// http://www.blitter.com/~russtopia/MIDI/~jglatt/tech/wave.htm

// Version 1.0

//import java.io.*;

public static class WavFile
{
private enum IOState {READING, WRITING, CLOSED};
private final static int BUFFER_SIZE = 4096;

private final static int FMT_CHUNK_ID = 0x20746D66;
private final static int DATA_CHUNK_ID = 0x61746164;
private final static int RIFF_CHUNK_ID = 0x46464952;
private final static int RIFF_TYPE_ID = 0x45564157;

private File file;                      // File that will be read from or written to
private IOState ioState;                // Specifies the IO State of the Wav File (used for snaity checking)
private int bytesPerSample;         // Number of bytes required to store a single sample
private long numFrames;                 // Number of frames within the data section
private FileOutputStream oStream;   // Output stream used for writting data
private FileInputStream iStream;        // Input stream used for reading data
private double floatScale;              // Scaling factor used for int <-> float conversion             
private double floatOffset;         // Offset factor used for int <-> float conversion              
private boolean wordAlignAdjust;        // Specify if an extra byte at the end of the data chunk is required for word alignment

// Wav Header
private int numChannels;                // 2 bytes unsigned, 0x0001 (1) to 0xFFFF (65,535)
private long sampleRate;                // 4 bytes unsigned, 0x00000001 (1) to 0xFFFFFFFF (4,294,967,295)
// Although a java int is 4 bytes, it is signed, so need to use a long
private int blockAlign;                 // 2 bytes unsigned, 0x0001 (1) to 0xFFFF (65,535)
private int validBits;                  // 2 bytes unsigned, 0x0002 (2) to 0xFFFF (65,535)

// Buffering
private byte[] buffer;                  // Local buffer used for IO
private int bufferPointer;              // Points to the current position in local buffer
private int bytesRead;                  // Bytes read after last read into local buffer
private long frameCounter;              // Current number of frames read or written

// Cannot instantiate WavFile directly, must either use newWavFile() or openWavFile()
private WavFile()
{
buffer = new byte[BUFFER_SIZE];
}

public int getNumChannels()
{
return numChannels;
}

public long getNumFrames()
{
return numFrames;
}

public long getFramesRemaining()
{
return numFrames - frameCounter;
}

public long getSampleRate()
{
return sampleRate;
}

public int getValidBits()
{
return validBits;
}

public static WavFile newWavFile(File file, int numChannels, long numFrames, int validBits, long sampleRate) throws IOException, WavFileException
{
// Instantiate new Wavfile and initialise
WavFile wavFile = new WavFile();
wavFile.file = file;
wavFile.numChannels = numChannels;
wavFile.numFrames = numFrames;
wavFile.sampleRate = sampleRate;
wavFile.bytesPerSample = (validBits + 7) / 8;
wavFile.blockAlign = wavFile.bytesPerSample * numChannels;
wavFile.validBits = validBits;

// Sanity check arguments
if (numChannels < 1 || numChannels > 65535) throw new WavFileException("Illegal number of channels, valid range 1 to 65536");
if (numFrames < 0) throw new WavFileException("Number of frames must be positive");
if (validBits < 2 || validBits > 65535) throw new WavFileException("Illegal number of valid bits, valid range 2 to 65536");
if (sampleRate < 0) throw new WavFileException("Sample rate must be positive");

// Create output stream for writing data
wavFile.oStream = new FileOutputStream(file);

// Calculate the chunk sizes
long dataChunkSize = wavFile.blockAlign * numFrames;
long mainChunkSize =    4 + // Riff Type
8 + // Format ID and size
16 +    // Format data
8 +     // Data ID and size
dataChunkSize;

// Chunks must be word aligned, so if odd number of audio data bytes
// adjust the main chunk size
if (dataChunkSize % 2 == 1) {
mainChunkSize += 1;
wavFile.wordAlignAdjust = true;
}
else {
wavFile.wordAlignAdjust = false;
}

// Set the main chunk size
putLE(RIFF_CHUNK_ID,    wavFile.buffer, 0, 4);
putLE(mainChunkSize,    wavFile.buffer, 4, 4);
putLE(RIFF_TYPE_ID, wavFile.buffer, 8, 4);

// Write out the header
wavFile.oStream.write(wavFile.buffer, 0, 12);

// Put format data in buffer
long averageBytesPerSecond = sampleRate * wavFile.blockAlign;

putLE(FMT_CHUNK_ID,             wavFile.buffer, 0, 4);      // Chunk ID
putLE(16,                           wavFile.buffer, 4, 4);      // Chunk Data Size
putLE(1,                                wavFile.buffer, 8, 2);      // Compression Code (Uncompressed)
putLE(numChannels,              wavFile.buffer, 10, 2);     // Number of channels
putLE(sampleRate,                   wavFile.buffer, 12, 4);     // Sample Rate
putLE(averageBytesPerSecond,    wavFile.buffer, 16, 4);     // Average Bytes Per Second
putLE(wavFile.blockAlign,       wavFile.buffer, 20, 2);     // Block Align
putLE(validBits,                    wavFile.buffer, 22, 2);     // Valid Bits

// Write Format Chunk
wavFile.oStream.write(wavFile.buffer, 0, 24);

// Start Data Chunk
putLE(DATA_CHUNK_ID,                wavFile.buffer, 0, 4);      // Chunk ID
putLE(dataChunkSize,                wavFile.buffer, 4, 4);      // Chunk Data Size

// Write Format Chunk
wavFile.oStream.write(wavFile.buffer, 0, 8);

// Calculate the scaling factor for converting to a normalised double
if (wavFile.validBits > 8)
{
// If more than 8 validBits, data is signed
// Conversion required multiplying by magnitude of max positive value
wavFile.floatOffset = 0;
wavFile.floatScale = Long.MAX_VALUE >> (64 - wavFile.validBits);
}
else
{
// Else if 8 or less validBits, data is unsigned
// Conversion required dividing by max positive value
wavFile.floatOffset = 1;
wavFile.floatScale = 0.5 * ((1 << wavFile.validBits) - 1);
}

// Finally, set the IO State
wavFile.bufferPointer = 0;
wavFile.bytesRead = 0;
wavFile.frameCounter = 0;
wavFile.ioState = IOState.WRITING;

return wavFile;
}

public static WavFile openWavFile(File file) throws IOException, WavFileException
{
// Instantiate new Wavfile and store the file reference
WavFile wavFile = new WavFile();
wavFile.file = file;

// Create a new file input stream for reading file data
wavFile.iStream = new FileInputStream(file);

// Read the first 12 bytes of the file
int bytesRead = wavFile.iStream.read(wavFile.buffer, 0, 12);
if (bytesRead != 12) throw new WavFileException("Not enough wav file bytes for header");

// Extract parts from the header
long riffChunkID = getLE(wavFile.buffer, 0, 4);
long chunkSize = getLE(wavFile.buffer, 4, 4);
long riffTypeID = getLE(wavFile.buffer, 8, 4);

// Check the header bytes contains the correct signature
if (riffChunkID != RIFF_CHUNK_ID) throw new WavFileException("Invalid Wav Header data, incorrect riff chunk ID");
if (riffTypeID != RIFF_TYPE_ID) throw new WavFileException("Invalid Wav Header data, incorrect riff type ID");

// Check that the file size matches the number of bytes listed in header
if (file.length() != chunkSize+8) {
throw new WavFileException("Header chunk size (" + chunkSize + ") does not match file size (" + file.length() + ")");
}

boolean foundFormat = false;
boolean foundData = false;

// Search for the Format and Data Chunks
while (true)
{
// Read the first 8 bytes of the chunk (ID and chunk size)
bytesRead = wavFile.iStream.read(wavFile.buffer, 0, 8);
if (bytesRead == -1) throw new WavFileException("Reached end of file without finding format chunk");
if (bytesRead != 8) throw new WavFileException("Could not read chunk header");

// Extract the chunk ID and Size
long chunkID = getLE(wavFile.buffer, 0, 4);
chunkSize = getLE(wavFile.buffer, 4, 4);

// Word align the chunk size
// chunkSize specifies the number of bytes holding data. However,
// the data should be word aligned (2 bytes) so we need to calculate
// the actual number of bytes in the chunk
long numChunkBytes = (chunkSize%2 == 1) ? chunkSize+1 : chunkSize;

if (chunkID == FMT_CHUNK_ID)
{
// Flag that the format chunk has been found
foundFormat = true;

// Read in the header info
bytesRead = wavFile.iStream.read(wavFile.buffer, 0, 16);

// Check this is uncompressed data
int compressionCode = (int) getLE(wavFile.buffer, 0, 2);
if (compressionCode != 1) throw new WavFileException("Compression Code " + compressionCode + " not supported");

// Extract the format information
wavFile.numChannels = (int) getLE(wavFile.buffer, 2, 2);
wavFile.sampleRate = getLE(wavFile.buffer, 4, 4);
wavFile.blockAlign = (int) getLE(wavFile.buffer, 12, 2);
wavFile.validBits = (int) getLE(wavFile.buffer, 14, 2);

if (wavFile.numChannels == 0) throw new WavFileException("Number of channels specified in header is equal to zero");
if (wavFile.blockAlign == 0) throw new WavFileException("Block Align specified in header is equal to zero");
if (wavFile.validBits < 2) throw new WavFileException("Valid Bits specified in header is less than 2");
if (wavFile.validBits > 64) throw new WavFileException("Valid Bits specified in header is greater than 64, this is greater than a long can hold");

// Calculate the number of bytes required to hold 1 sample
wavFile.bytesPerSample = (wavFile.validBits + 7) / 8;
if (wavFile.bytesPerSample * wavFile.numChannels != wavFile.blockAlign)
throw new WavFileException("Block Align does not agree with bytes required for validBits and number of channels");

// Account for number of format bytes and then skip over
// any extra format bytes
numChunkBytes -= 16;
if (numChunkBytes > 0) wavFile.iStream.skip(numChunkBytes);
}
else if (chunkID == DATA_CHUNK_ID)
{
// Check if we've found the format chunk,
// If not, throw an exception as we need the format information
// before we can read the data chunk
if (foundFormat == false) throw new WavFileException("Data chunk found before Format chunk");

// Check that the chunkSize (wav data length) is a multiple of the
// block align (bytes per frame)
if (chunkSize % wavFile.blockAlign != 0) throw new WavFileException("Data Chunk size is not multiple of Block Align");

// Calculate the number of frames
wavFile.numFrames = chunkSize / wavFile.blockAlign;

// Flag that we've found the wave data chunk
foundData = true;

break;
}
else
{
// If an unknown chunk ID is found, just skip over the chunk data
wavFile.iStream.skip(numChunkBytes);
}
}

// Throw an exception if no data chunk has been found
if (foundData == false) throw new WavFileException("Did not find a data chunk");

// Calculate the scaling factor for converting to a normalised double
if (wavFile.validBits > 8)
{
// If more than 8 validBits, data is signed
// Conversion required dividing by magnitude of max negative value
wavFile.floatOffset = 0;
wavFile.floatScale = 1 << (wavFile.validBits - 1);
}
else
{
// Else if 8 or less validBits, data is unsigned
// Conversion required dividing by max positive value
wavFile.floatOffset = -1;
wavFile.floatScale = 0.5 * ((1 << wavFile.validBits) - 1);
}

wavFile.bufferPointer = 0;
wavFile.bytesRead = 0;
wavFile.frameCounter = 0;
wavFile.ioState = IOState.READING;

return wavFile;
}

// Get and Put little endian data from local buffer
// ------------------------------------------------
private static long getLE(byte[] buffer, int pos, int numBytes)
{
numBytes --;
pos += numBytes;

long val = buffer[pos] & 0xFF;
for (int b=0 ; b<numBytes ; b++) val = (val << 8) + (buffer[--pos] & 0xFF);

return val;
}

private static void putLE(long val, byte[] buffer, int pos, int numBytes)
{
for (int b=0 ; b<numBytes ; b++)
{
buffer[pos] = (byte) (val & 0xFF);
val >>= 8;
pos ++;
}
}

// Sample Writing and Reading
// --------------------------
private void writeSample(long val) throws IOException
{
for (int b=0 ; b<bytesPerSample ; b++)
{
if (bufferPointer == BUFFER_SIZE)
{
oStream.write(buffer, 0, BUFFER_SIZE);
bufferPointer = 0;
}

buffer[bufferPointer] = (byte) (val & 0xFF);
val >>= 8;
bufferPointer ++;
}
}

private long readSample() throws IOException, WavFileException
{
long val = 0;

for (int b=0 ; b<bytesPerSample ; b++)
{
if (bufferPointer == bytesRead) 
{
int read = iStream.read(buffer, 0, BUFFER_SIZE);
if (read == -1) throw new WavFileException("Not enough data available");
bytesRead = read;
bufferPointer = 0;
}

int v = buffer[bufferPointer];
if (b < bytesPerSample-1 || bytesPerSample == 1) v &= 0xFF;
val += v << (b * 8);

bufferPointer ++;
}

return val;
}


// Short
// ----mono:
public int readFramesChanel(short[] sampleBuffer, int numFramesToRead,int channel) throws IOException, WavFileException
{
return readFramesChanel(sampleBuffer, 0, numFramesToRead,channel);
}

public int readFramesChanel(short[] sampleBuffer, int offset, int numFramesToRead,int channel) throws IOException, WavFileException
{
if (ioState != IOState.READING) throw new IOException("Cannot read from WavFile instance");

for (int f=0 ; f<numFramesToRead ; f++)
{
if (frameCounter == numFrames) return f;

for (int c=0 ; c<numChannels ; c++)
{
if(channel==c)
{
sampleBuffer[offset] = (short) readSample();
offset ++;
}
else
readSample();
}

frameCounter ++;
}

return numFramesToRead;
}
// ----
public int readFrames(short[] sampleBuffer, int numFramesToRead) throws IOException, WavFileException
{
return readFrames(sampleBuffer, 0, numFramesToRead);
}

public int readFrames(short[] sampleBuffer, int offset, int numFramesToRead) throws IOException, WavFileException
{
if (ioState != IOState.READING) throw new IOException("Cannot read from WavFile instance");

for (int f=0 ; f<numFramesToRead ; f++)
{
if (frameCounter == numFrames) return f;

for (int c=0 ; c<numChannels ; c++)
{
sampleBuffer[offset] = (short) readSample();
offset ++;
}

frameCounter ++;
}

return numFramesToRead;
}

public int readFrames(short[][] sampleBuffer, int numFramesToRead) throws IOException, WavFileException
{
return readFrames(sampleBuffer, 0, numFramesToRead);
}

public int readFrames(short[][] sampleBuffer, int offset, int numFramesToRead) throws IOException, WavFileException
{
if (ioState != IOState.READING) throw new IOException("Cannot read from WavFile instance");

for (int f=0 ; f<numFramesToRead ; f++)
{
if (frameCounter == numFrames) return f;

for (int c=0 ; c<numChannels ; c++) sampleBuffer[c][offset] = (short) readSample();

offset ++;
frameCounter ++;
}

return numFramesToRead;
}

public int writeFrames(short[] sampleBuffer, int numFramesToWrite) throws IOException, WavFileException
{
return writeFrames(sampleBuffer, 0, numFramesToWrite);
}

public int writeFrames(short[] sampleBuffer, int offset, int numFramesToWrite) throws IOException, WavFileException
{
if (ioState != IOState.WRITING) throw new IOException("Cannot write to WavFile instance");

for (int f=0 ; f<numFramesToWrite ; f++)
{
if (frameCounter == numFrames) return f;

for (int c=0 ; c<numChannels ; c++)
{
writeSample(sampleBuffer[offset]);
offset ++;
}

frameCounter ++;
}

return numFramesToWrite;
}

public int writeFrames(short[][] sampleBuffer, int numFramesToWrite) throws IOException, WavFileException
{
return writeFrames(sampleBuffer, 0, numFramesToWrite);
}

public int writeFrames(short[][] sampleBuffer, int offset, int numFramesToWrite) throws IOException, WavFileException
{
if (ioState != IOState.WRITING) throw new IOException("Cannot write to WavFile instance");

for (int f=0 ; f<numFramesToWrite ; f++)
{
if (frameCounter == numFrames) return f;

for (int c=0 ; c<numChannels ; c++) writeSample(sampleBuffer[c][offset]);

offset ++;
frameCounter ++;
}

return numFramesToWrite;
}

// Integer
// -------
public int readFrames(int[] sampleBuffer, int numFramesToRead) throws IOException, WavFileException
{
return readFrames(sampleBuffer, 0, numFramesToRead);
}

public int readFrames(int[] sampleBuffer, int offset, int numFramesToRead) throws IOException, WavFileException
{
if (ioState != IOState.READING) throw new IOException("Cannot read from WavFile instance");

for (int f=0 ; f<numFramesToRead ; f++)
{
if (frameCounter == numFrames) return f;

for (int c=0 ; c<numChannels ; c++)
{
sampleBuffer[offset] = (int) readSample();
offset ++;
}

frameCounter ++;
}

return numFramesToRead;
}

public int readFrames(int[][] sampleBuffer, int numFramesToRead) throws IOException, WavFileException
{
return readFrames(sampleBuffer, 0, numFramesToRead);
}

public int readFrames(int[][] sampleBuffer, int offset, int numFramesToRead) throws IOException, WavFileException
{
if (ioState != IOState.READING) throw new IOException("Cannot read from WavFile instance");

for (int f=0 ; f<numFramesToRead ; f++)
{
if (frameCounter == numFrames) return f;

for (int c=0 ; c<numChannels ; c++) sampleBuffer[c][offset] = (int) readSample();

offset ++;
frameCounter ++;
}

return numFramesToRead;
}

public int writeFrames(int[] sampleBuffer, int numFramesToWrite) throws IOException, WavFileException
{
return writeFrames(sampleBuffer, 0, numFramesToWrite);
}

public int writeFrames(int[] sampleBuffer, int offset, int numFramesToWrite) throws IOException, WavFileException
{
if (ioState != IOState.WRITING) throw new IOException("Cannot write to WavFile instance");

for (int f=0 ; f<numFramesToWrite ; f++)
{
if (frameCounter == numFrames) return f;

for (int c=0 ; c<numChannels ; c++)
{
writeSample(sampleBuffer[offset]);
offset ++;
}

frameCounter ++;
}

return numFramesToWrite;
}

public int writeFrames(int[][] sampleBuffer, int numFramesToWrite) throws IOException, WavFileException
{
return writeFrames(sampleBuffer, 0, numFramesToWrite);
}

public int writeFrames(int[][] sampleBuffer, int offset, int numFramesToWrite) throws IOException, WavFileException
{
if (ioState != IOState.WRITING) throw new IOException("Cannot write to WavFile instance");

for (int f=0 ; f<numFramesToWrite ; f++)
{
if (frameCounter == numFrames) return f;

for (int c=0 ; c<numChannels ; c++) writeSample(sampleBuffer[c][offset]);

offset ++;
frameCounter ++;
}

return numFramesToWrite;
}

// Long
// ----
public int readFrames(long[] sampleBuffer, int numFramesToRead) throws IOException, WavFileException
{
return readFrames(sampleBuffer, 0, numFramesToRead);
}

public int readFrames(long[] sampleBuffer, int offset, int numFramesToRead) throws IOException, WavFileException
{
if (ioState != IOState.READING) throw new IOException("Cannot read from WavFile instance");

for (int f=0 ; f<numFramesToRead ; f++)
{
if (frameCounter == numFrames) return f;

for (int c=0 ; c<numChannels ; c++)
{
sampleBuffer[offset] = readSample();
offset ++;
}

frameCounter ++;
}

return numFramesToRead;
}

public int readFrames(long[][] sampleBuffer, int numFramesToRead) throws IOException, WavFileException
{
return readFrames(sampleBuffer, 0, numFramesToRead);
}

public int readFrames(long[][] sampleBuffer, int offset, int numFramesToRead) throws IOException, WavFileException
{
if (ioState != IOState.READING) throw new IOException("Cannot read from WavFile instance");

for (int f=0 ; f<numFramesToRead ; f++)
{
if (frameCounter == numFrames) return f;

for (int c=0 ; c<numChannels ; c++) sampleBuffer[c][offset] = readSample();

offset ++;
frameCounter ++;
}

return numFramesToRead;
}

public int writeFrames(long[] sampleBuffer, int numFramesToWrite) throws IOException, WavFileException
{
return writeFrames(sampleBuffer, 0, numFramesToWrite);
}

public int writeFrames(long[] sampleBuffer, int offset, int numFramesToWrite) throws IOException, WavFileException
{
if (ioState != IOState.WRITING) throw new IOException("Cannot write to WavFile instance");

for (int f=0 ; f<numFramesToWrite ; f++)
{
if (frameCounter == numFrames) return f;

for (int c=0 ; c<numChannels ; c++)
{
writeSample(sampleBuffer[offset]);
offset ++;
}

frameCounter ++;
}

return numFramesToWrite;
}

public int writeFrames(long[][] sampleBuffer, int numFramesToWrite) throws IOException, WavFileException
{
return writeFrames(sampleBuffer, 0, numFramesToWrite);
}

public int writeFrames(long[][] sampleBuffer, int offset, int numFramesToWrite) throws IOException, WavFileException
{
if (ioState != IOState.WRITING) throw new IOException("Cannot write to WavFile instance");

for (int f=0 ; f<numFramesToWrite ; f++)
{
if (frameCounter == numFrames) return f;

for (int c=0 ; c<numChannels ; c++) writeSample(sampleBuffer[c][offset]);

offset ++;
frameCounter ++;
}

return numFramesToWrite;
}

// Double
// ------
public int readFrames(double[] sampleBuffer, int numFramesToRead) throws IOException, WavFileException
{
return readFrames(sampleBuffer, 0, numFramesToRead);
}

public int readFrames(double[] sampleBuffer, int offset, int numFramesToRead) throws IOException, WavFileException
{
if (ioState != IOState.READING) throw new IOException("Cannot read from WavFile instance");

for (int f=0 ; f<numFramesToRead ; f++)
{
if (frameCounter == numFrames) return f;

for (int c=0 ; c<numChannels ; c++)
{
sampleBuffer[offset] = floatOffset + (double) readSample() / floatScale;
offset ++;
}

frameCounter ++;
}

return numFramesToRead;
}

public int readFrames(double[][] sampleBuffer, int numFramesToRead) throws IOException, WavFileException
{
return readFrames(sampleBuffer, 0, numFramesToRead);
}

public int readFrames(double[][] sampleBuffer, int offset, int numFramesToRead) throws IOException, WavFileException
{
if (ioState != IOState.READING) throw new IOException("Cannot read from WavFile instance");

for (int f=0 ; f<numFramesToRead ; f++)
{
if (frameCounter == numFrames) return f;

for (int c=0 ; c<numChannels ; c++) sampleBuffer[c][offset] = floatOffset + (double) readSample() / floatScale;

offset ++;
frameCounter ++;
}

return numFramesToRead;
}

public int writeFrames(double[] sampleBuffer, int numFramesToWrite) throws IOException, WavFileException
{
return writeFrames(sampleBuffer, 0, numFramesToWrite);
}

public int writeFrames(double[] sampleBuffer, int offset, int numFramesToWrite) throws IOException, WavFileException
{
if (ioState != IOState.WRITING) throw new IOException("Cannot write to WavFile instance");

for (int f=0 ; f<numFramesToWrite ; f++)
{
if (frameCounter == numFrames) return f;

for (int c=0 ; c<numChannels ; c++)
{
writeSample((long) (floatScale * (floatOffset + sampleBuffer[offset])));
offset ++;
}

frameCounter ++;
}

return numFramesToWrite;
}

public int writeFrames(double[][] sampleBuffer, int numFramesToWrite) throws IOException, WavFileException
{
return writeFrames(sampleBuffer, 0, numFramesToWrite);
}

public int writeFrames(double[][] sampleBuffer, int offset, int numFramesToWrite) throws IOException, WavFileException
{
if (ioState != IOState.WRITING) throw new IOException("Cannot write to WavFile instance");

for (int f=0 ; f<numFramesToWrite ; f++)
{
if (frameCounter == numFrames) return f;

for (int c=0 ; c<numChannels ; c++) writeSample((long) (floatScale * (floatOffset + sampleBuffer[c][offset])));

offset ++;
frameCounter ++;
}

return numFramesToWrite;
}


public void close() throws IOException
{
// Close the input stream and set to null
if (iStream != null)
{
iStream.close();
iStream = null;
}

if (oStream != null) 
{
// Write out anything still in the local buffer
if (bufferPointer > 0) oStream.write(buffer, 0, bufferPointer);

// If an extra byte is required for word alignment, add it to the end
if (wordAlignAdjust) oStream.write(0);

// Close the stream and set to null
oStream.close();
oStream = null;
}

// Flag that the stream is closed
ioState = IOState.CLOSED;
}

public void display()
{
display(System.out);
}

public void display(PrintStream out)
{
out.printf("File: %s\n", file);
out.printf("Channels: %d, Frames: %d\n", numChannels, numFrames);
out.printf("IO State: %s\n", ioState);
out.printf("Sample Rate: %d, Block Align: %d\n", sampleRate, blockAlign);
out.printf("Valid Bits: %d, Bytes per sample: %d\n", validBits, bytesPerSample);
}

public static void main(String[] args)
{
if (args.length < 1)
{
System.err.println("Must supply filename");
System.exit(1);
}

try
{
for (String filename : args)
{
WavFile readWavFile = openWavFile(new File(filename));
readWavFile.display();

long numFrames = readWavFile.getNumFrames();
int numChannels = readWavFile.getNumChannels();
int validBits = readWavFile.getValidBits();
long sampleRate = readWavFile.getSampleRate();

WavFile writeWavFile = newWavFile(new File("out.wav"), numChannels, numFrames, validBits, sampleRate);

final int BUF_SIZE = 5001;

//                  int[] buffer = new int[BUF_SIZE * numChannels];
//                  long[] buffer = new long[BUF_SIZE * numChannels];
double[] buffer = new double[BUF_SIZE * numChannels];

int framesRead = 0;
int framesWritten = 0;

do
{
framesRead = readWavFile.readFrames(buffer, BUF_SIZE);
framesWritten = writeWavFile.writeFrames(buffer, BUF_SIZE);
System.out.printf("%d %d\n", framesRead, framesWritten);
}
while (framesRead != 0);

readWavFile.close();
writeWavFile.close();
}

WavFile writeWavFile = newWavFile(new File("out2.wav"), 1, 10, 23, 44100);
double[] buffer = new double[10];
writeWavFile.writeFrames(buffer, 10);
writeWavFile.close();
}
catch (Exception e)
{
System.err.println(e);
e.printStackTrace();
}
}
}

public static class WavFileException extends Exception
{
/**
* 
*/
private static final long serialVersionUID = 8236151366330602556L;

public WavFileException()
{
super();
}

public WavFileException(String message)
{
super(message);
}

public WavFileException(String message, Throwable cause)
{
super(message, cause);
}

public WavFileException(Throwable cause) 
{
super(cause);
}
}

//import java.io.*;
/*
public static class ReadExample
{
public static void main(String[] args)
{
try
{
// Open the wav file specified as the first argument
WavFile wavFile = WavFile.openWavFile(new File(args[0]));

// Display information about the wav file
wavFile.display();

// Get the number of audio channels in the wav file
int numChannels = wavFile.getNumChannels();

// Create a buffer of 100 frames
double[] buffer = new double[100 * numChannels];

int framesRead;
double min = Double.MAX_VALUE;
double max = Double.MIN_VALUE;

do
{
// Read frames into buffer
framesRead = wavFile.readFrames(buffer, 100);

// Loop through frames and look for minimum and maximum value
for (int s=0 ; s<framesRead * numChannels ; s++)
{
if (buffer[s] > max) max = buffer[s];
if (buffer[s] < min) min = buffer[s];
}
}
while (framesRead != 0);

// Close the wavFile
wavFile.close();

// Output the minimum and maximum value
System.out.printf("Min: %f, Max: %f\n", min, max);
}
catch (Exception e)
{
System.err.println(e);
}
}
}

//import java.io.*;


public static class WriteExample
{
public static void main(String[] args)
{
try
{
int sampleRate = 44100;     // Samples per second
double duration = 5.0;      // Seconds

// Calculate the number of frames required for specified duration
long numFrames = (long)(duration * sampleRate);

// Create a wav file with the name specified as the first argument
WavFile wavFile = WavFile.newWavFile(new File(args[0]), 2, numFrames, 16, sampleRate);

// Create a buffer of 100 frames
double[][] buffer = new double[2][100];

// Initialise a local frame counter
long frameCounter = 0;

// Loop until all frames written
while (frameCounter < numFrames)
{
// Determine how many frames to write, up to a maximum of the buffer size
long remaining = wavFile.getFramesRemaining();
int toWrite = (remaining > 100) ? 100 : (int) remaining;

// Fill the buffer, one tone per channel
for (int s=0 ; s<toWrite ; s++, frameCounter++)
{
buffer[0][s] = Math.sin(2.0 * Math.PI * 400 * frameCounter / sampleRate);
buffer[1][s] = Math.sin(2.0 * Math.PI * 500 * frameCounter / sampleRate);
}

// Write the buffer
wavFile.writeFrames(buffer, toWrite);
}

// Close the wavFile
wavFile.close();
}
catch (Exception e)
{
System.err.println(e);
}
}
}
*/

};
package com.doodkin.learnwave;
导入java.io.File;
导入java.io.FileInputStream;
导入java.io.FileOutputStream;
导入java.io.IOException;
导入java.io.PrintStream;
//发件人:http://www.labbookpages.co.uk/audio/javaWavFiles.html
//增加了短通道和读通道
公共课浪潮{
//Wav文件IO类
//A.格林斯特德
// http://www.labbookpages.co.uk
//文件格式基于来自的信息
// http://www.sonicspot.com/guide/wavefiles.html
// http://www.blitter.com/~russtopia/MIDI/~jglatt/tech/wave.htm
//版本1.0
//导入java.io.*;
公共静态类文件
{
私有枚举IOState{读取、写入、关闭};
私有最终静态int缓冲区大小=4096;
私有最终静态int FMT_CHUNK_ID=0x20746D66;
私有最终静态整型数据块ID=0x61746164;
私有最终静态int-RIFF\u CHUNK\u ID=0x46464952;
私有最终静态int-RIFF_-TYPE_-ID=0x45564157;
私有文件;//将被读取或写入的文件
private IOState IOState;//指定Wav文件的IO状态(用于snaity检查)
private int bytesPerSample;//存储单个样本所需的字节数
private long numFrames;//数据段中的帧数
私有文件输出流oStream;//用于写入数据的输出流
私有文件InputStream iStream;//用于读取数据的输入流
private double floatScale;//用于整数浮点转换的比例因子
private double floatOffset;//用于整数浮点转换的偏移因子
private boolean wordAlignAdjust;//指定是否需要数据块末尾的额外字节进行字对齐
//Wav头
private int numChannels;//2个无符号字节,0x0001(1)到0xFFFF(65535)
私有长采样器;//4个无符号字节,0x00000001(1)到0xFFFFFF(4294967295)
//尽管java int是4字节,但它是有符号的,所以需要使用长字符串
private int blockAlign;//2个无符号字节,0x0001(1)到0xFFFF(65535)
private int validBits;//2个无符号字节,0x0002(2)到0xFFFF(65535)
//缓冲
专用字节[]缓冲区;//用于IO的本地缓冲区
private int bufferPointer;//指向本地缓冲区中的当前位置
private int bytesRead;//上次读入本地缓冲区后读取的字节数
private long frameCounter;//当前读取或写入的帧数
//无法直接实例化WavFile,必须使用newWavFile()或openWavFile()
私有文件()
{
缓冲区=新字节[缓冲区大小];
}
public int getNumChannels()
{
返回numChannels;
}
公共长getNumFrames()
{
返回numFrames;
}
公共长GetFramesMaining()
{
返回numFrames-帧计数器;
}
公共长getSampleRate()
{
回程取样器;
}
public int getValidBits()
{
返回有效位;
}
公共静态WavFile newWavFile(文件文件,int numChannels,long numFrames,int validBits,long sampleRate)抛出IOException,WavFileException
{
//实例化新文件并初始化
WavFile WavFile=新的WavFile();
wavFile.file=文件;
wavFile.numChannels=numChannels;
wavFile.numFrames=numFrames;
wavFile.sampleRate=sampleRate;
wavFile.bytesPerSample=(validBits+7)/8;
wavFile.blockAlign=wavFile.bytesPerSample*numChannels;
wavFile.validBits=validBits;
//健全性检查参数
如果(numChannels<1 | | numChannels>65535)抛出新的WavFileException(“通道数非法,有效范围1到65536”);
如果(numFrames<0)抛出新的WavFileException(“帧数必须为正”);
如果(validBits<2 | | validBits>65535)抛出新的WavFileException(“有效位数非法,有效范围2到65536”);
如果(sampleRate<0)抛出新的WavFileException(“采样率必须为正”);
//创建用于写入数据的输出流
wavFile.oStream=新文件输出流(文件);
//计算块大小
long dataChunkSize=wavFile.blockAlign*numFrames;
long mainChunkSize=4+//Riff类型
8+//格式ID和大小
16+//格式化数据
8+//数据ID和大小
// Short
    public int readFramesChanel(short[] sampleBuffer, int numFramesToRead,int channel) throws IOException, WavFileException
    {
        return readFramesChanel(sampleBuffer, 0, numFramesToRead,channel);
    }

    public int readFramesChanel(short[] sampleBuffer, int offset, int numFramesToRead,int channel) throws IOException, WavFileException
    {
        if (ioState != WavFile.IOState.READING) throw new IOException("Cannot read from WavFile instance");

        for (int f=0 ; f<numFramesToRead ; f++)
        {
            if (frameCounter == numFrames) return f;

            for (int c=0 ; c<numChannels ; c++)
            {
                if(channel==c)
                {
                    sampleBuffer[offset] = (short) readSample();
                    offset ++;
                }
                else
                    readSample();
            }

            frameCounter ++;
        }

        return numFramesToRead;
    }
    // ----
    public int readFrames(short[] sampleBuffer, int numFramesToRead) throws IOException, WavFileException
    {
        return readFrames(sampleBuffer, 0, numFramesToRead);
    }

    public int readFrames(short[] sampleBuffer, int offset, int numFramesToRead) throws IOException, WavFileException
    {
        if (ioState != WavFile.IOState.READING) throw new IOException("Cannot read from WavFile instance");

        for (int f=0 ; f<numFramesToRead ; f++)
        {
            if (frameCounter == numFrames) return f;

            for (int c=0 ; c<numChannels ; c++)
            {
                sampleBuffer[offset] = (short) readSample();
                offset ++;
            }

            frameCounter ++;
        }

        return numFramesToRead;
    }

    public int readFrames(short[][] sampleBuffer, int numFramesToRead) throws IOException, WavFileException
    {
        return readFrames(sampleBuffer, 0, numFramesToRead);
    }

    public int readFrames(short[][] sampleBuffer, int offset, int numFramesToRead) throws IOException, WavFileException
    {
        if (ioState != WavFile.IOState.READING) throw new IOException("Cannot read from WavFile instance");

        for (int f=0 ; f<numFramesToRead ; f++)
        {
            if (frameCounter == numFrames) return f;

            for (int c=0 ; c<numChannels ; c++) sampleBuffer[c][offset] = (short) readSample();

            offset ++;
            frameCounter ++;
        }

        return numFramesToRead;
    }

    public int writeFrames(short[] sampleBuffer, int numFramesToWrite) throws IOException, WavFileException
    {
        return writeFrames(sampleBuffer, 0, numFramesToWrite);
    }

    public int writeFrames(short[] sampleBuffer, int offset, int numFramesToWrite) throws IOException, WavFileException
    {
        if (ioState != WavFile.IOState.WRITING) throw new IOException("Cannot write to WavFile instance");

        for (int f=0 ; f<numFramesToWrite ; f++)
        {
            if (frameCounter == numFrames) return f;

            for (int c=0 ; c<numChannels ; c++)
            {
                writeSample(sampleBuffer[offset]);
                offset ++;
            }

            frameCounter ++;
        }

        return numFramesToWrite;
    }

    public int writeFrames(short[][] sampleBuffer, int numFramesToWrite) throws IOException, WavFileException
    {
        return writeFrames(sampleBuffer, 0, numFramesToWrite);
    }

    public int writeFrames(short[][] sampleBuffer, int offset, int numFramesToWrite) throws IOException, WavFileException
    {
        if (ioState != WavFile.IOState.WRITING) throw new IOException("Cannot write to WavFile instance");

        for (int f=0 ; f<numFramesToWrite ; f++)
        {
            if (frameCounter == numFrames) return f;

            for (int c=0 ; c<numChannels ; c++) writeSample(sampleBuffer[c][offset]);

            offset ++;
            frameCounter ++;
        }

        return numFramesToWrite;
    }