public int read(InputStream in) throws IOException {
		/* RIFF header */
		readId( in, "RIFF" );
		@SuppressWarnings("unused")
		int numBytes = readInt( in ) - 36;
		readId( in, "WAVE" );

        /* fmt chunk */
		readId( in, "fmt " );
		if ( 16 != readInt( in ) ) {
			throw new IOException( "fmt chunk length not 16" );
		}
		mFormat = readShort( in );
		mNumChannels = readShort( in );
		mSampleRate = readInt( in );
		int byteRate = readInt( in );
		short blockAlign = readShort( in );
		mBitsPerSample = readShort( in );
		if ( byteRate != mNumChannels * mSampleRate * mBitsPerSample / 8 ) {
			throw new IOException( "fmt.ByteRate field inconsistent" );
		}
		if ( blockAlign != mNumChannels * mBitsPerSample / 8 ) {
			throw new IOException( "fmt.BlockAlign field inconsistent" );
		}

        /* data chunk */
		readId( in, "data" );
		mNumBytes = readInt( in );

		return HEADER_LENGTH;
	}