com.google.android.exoplayer2.audio.WavUtil Java Examples

The following examples show how to use com.google.android.exoplayer2.audio.WavUtil. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: WavHeaderReader.java    From MediaSDK with Apache License 2.0 5 votes vote down vote up
/**
 * Skips to the data in the given WAV input stream. After calling, the input stream's position
 * will point to the start of sample data in the WAV, and the data bounds of the provided {@link
 * WavHeader} will have been set.
 *
 * <p>If an exception is thrown, the input position will be left pointing to a chunk header and
 * the bounds of the provided {@link WavHeader} will not have been set.
 *
 * @param input Input stream to skip to the data chunk in. Its peek position must be pointing to a
 *     valid chunk header.
 * @param wavHeader WAV header to populate with data bounds.
 * @throws ParserException If an error occurs parsing chunks.
 * @throws IOException If reading from the input fails.
 * @throws InterruptedException If interrupted while reading from input.
 */
public static void skipToData(ExtractorInput input, WavHeader wavHeader)
    throws IOException, InterruptedException {
  Assertions.checkNotNull(input);
  Assertions.checkNotNull(wavHeader);

  // Make sure the peek position is set to the read position before we peek the first header.
  input.resetPeekPosition();

  ParsableByteArray scratch = new ParsableByteArray(ChunkHeader.SIZE_IN_BYTES);
  // Skip all chunks until we hit the data header.
  ChunkHeader chunkHeader = ChunkHeader.peek(input, scratch);
  while (chunkHeader.id != WavUtil.DATA_FOURCC) {
    if (chunkHeader.id != WavUtil.RIFF_FOURCC && chunkHeader.id != WavUtil.FMT_FOURCC) {
      Log.w(TAG, "Ignoring unknown WAV chunk: " + chunkHeader.id);
    }
    long bytesToSkip = ChunkHeader.SIZE_IN_BYTES + chunkHeader.size;
    // Override size of RIFF chunk, since it describes its size as the entire file.
    if (chunkHeader.id == WavUtil.RIFF_FOURCC) {
      bytesToSkip = ChunkHeader.SIZE_IN_BYTES + 4;
    }
    if (bytesToSkip > Integer.MAX_VALUE) {
      throw new ParserException("Chunk is too large (~2GB+) to skip; id: " + chunkHeader.id);
    }
    input.skipFully((int) bytesToSkip);
    chunkHeader = ChunkHeader.peek(input, scratch);
  }
  // Skip past the "data" header.
  input.skipFully(ChunkHeader.SIZE_IN_BYTES);

  int dataStartPosition = (int) input.getPosition();
  long dataEndPosition = dataStartPosition + chunkHeader.size;
  long inputLength = input.getLength();
  if (inputLength != C.LENGTH_UNSET && dataEndPosition > inputLength) {
    Log.w(TAG, "Data exceeds input length: " + dataEndPosition + ", " + inputLength);
    dataEndPosition = inputLength;
  }
  wavHeader.setDataBounds(dataStartPosition, dataEndPosition);
}
 
Example #2
Source File: WavHeaderReader.java    From Telegram-FOSS with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Skips to the data in the given WAV input stream. After calling, the input stream's position
 * will point to the start of sample data in the WAV, and the data bounds of the provided {@link
 * WavHeader} will have been set.
 *
 * <p>If an exception is thrown, the input position will be left pointing to a chunk header and
 * the bounds of the provided {@link WavHeader} will not have been set.
 *
 * @param input Input stream to skip to the data chunk in. Its peek position must be pointing to a
 *     valid chunk header.
 * @param wavHeader WAV header to populate with data bounds.
 * @throws ParserException If an error occurs parsing chunks.
 * @throws IOException If reading from the input fails.
 * @throws InterruptedException If interrupted while reading from input.
 */
public static void skipToData(ExtractorInput input, WavHeader wavHeader)
    throws IOException, InterruptedException {
  Assertions.checkNotNull(input);
  Assertions.checkNotNull(wavHeader);

  // Make sure the peek position is set to the read position before we peek the first header.
  input.resetPeekPosition();

  ParsableByteArray scratch = new ParsableByteArray(ChunkHeader.SIZE_IN_BYTES);
  // Skip all chunks until we hit the data header.
  ChunkHeader chunkHeader = ChunkHeader.peek(input, scratch);
  while (chunkHeader.id != WavUtil.DATA_FOURCC) {
    if (chunkHeader.id != WavUtil.RIFF_FOURCC && chunkHeader.id != WavUtil.FMT_FOURCC) {
      Log.w(TAG, "Ignoring unknown WAV chunk: " + chunkHeader.id);
    }
    long bytesToSkip = ChunkHeader.SIZE_IN_BYTES + chunkHeader.size;
    // Override size of RIFF chunk, since it describes its size as the entire file.
    if (chunkHeader.id == WavUtil.RIFF_FOURCC) {
      bytesToSkip = ChunkHeader.SIZE_IN_BYTES + 4;
    }
    if (bytesToSkip > Integer.MAX_VALUE) {
      throw new ParserException("Chunk is too large (~2GB+) to skip; id: " + chunkHeader.id);
    }
    input.skipFully((int) bytesToSkip);
    chunkHeader = ChunkHeader.peek(input, scratch);
  }
  // Skip past the "data" header.
  input.skipFully(ChunkHeader.SIZE_IN_BYTES);

  int dataStartPosition = (int) input.getPosition();
  long dataEndPosition = dataStartPosition + chunkHeader.size;
  long inputLength = input.getLength();
  if (inputLength != C.LENGTH_UNSET && dataEndPosition > inputLength) {
    Log.w(TAG, "Data exceeds input length: " + dataEndPosition + ", " + inputLength);
    dataEndPosition = inputLength;
  }
  wavHeader.setDataBounds(dataStartPosition, dataEndPosition);
}
 
Example #3
Source File: WavHeaderReader.java    From Telegram with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Skips to the data in the given WAV input stream. After calling, the input stream's position
 * will point to the start of sample data in the WAV, and the data bounds of the provided {@link
 * WavHeader} will have been set.
 *
 * <p>If an exception is thrown, the input position will be left pointing to a chunk header and
 * the bounds of the provided {@link WavHeader} will not have been set.
 *
 * @param input Input stream to skip to the data chunk in. Its peek position must be pointing to a
 *     valid chunk header.
 * @param wavHeader WAV header to populate with data bounds.
 * @throws ParserException If an error occurs parsing chunks.
 * @throws IOException If reading from the input fails.
 * @throws InterruptedException If interrupted while reading from input.
 */
public static void skipToData(ExtractorInput input, WavHeader wavHeader)
    throws IOException, InterruptedException {
  Assertions.checkNotNull(input);
  Assertions.checkNotNull(wavHeader);

  // Make sure the peek position is set to the read position before we peek the first header.
  input.resetPeekPosition();

  ParsableByteArray scratch = new ParsableByteArray(ChunkHeader.SIZE_IN_BYTES);
  // Skip all chunks until we hit the data header.
  ChunkHeader chunkHeader = ChunkHeader.peek(input, scratch);
  while (chunkHeader.id != WavUtil.DATA_FOURCC) {
    if (chunkHeader.id != WavUtil.RIFF_FOURCC && chunkHeader.id != WavUtil.FMT_FOURCC) {
      Log.w(TAG, "Ignoring unknown WAV chunk: " + chunkHeader.id);
    }
    long bytesToSkip = ChunkHeader.SIZE_IN_BYTES + chunkHeader.size;
    // Override size of RIFF chunk, since it describes its size as the entire file.
    if (chunkHeader.id == WavUtil.RIFF_FOURCC) {
      bytesToSkip = ChunkHeader.SIZE_IN_BYTES + 4;
    }
    if (bytesToSkip > Integer.MAX_VALUE) {
      throw new ParserException("Chunk is too large (~2GB+) to skip; id: " + chunkHeader.id);
    }
    input.skipFully((int) bytesToSkip);
    chunkHeader = ChunkHeader.peek(input, scratch);
  }
  // Skip past the "data" header.
  input.skipFully(ChunkHeader.SIZE_IN_BYTES);

  int dataStartPosition = (int) input.getPosition();
  long dataEndPosition = dataStartPosition + chunkHeader.size;
  long inputLength = input.getLength();
  if (inputLength != C.LENGTH_UNSET && dataEndPosition > inputLength) {
    Log.w(TAG, "Data exceeds input length: " + dataEndPosition + ", " + inputLength);
    dataEndPosition = inputLength;
  }
  wavHeader.setDataBounds(dataStartPosition, dataEndPosition);
}
 
Example #4
Source File: WavHeaderReader.java    From MediaSDK with Apache License 2.0 4 votes vote down vote up
/**
 * Peeks and returns a {@code WavHeader}.
 *
 * @param input Input stream to peek the WAV header from.
 * @throws ParserException If the input file is an incorrect RIFF WAV.
 * @throws IOException If peeking from the input fails.
 * @throws InterruptedException If interrupted while peeking from input.
 * @return A new {@code WavHeader} peeked from {@code input}, or null if the input is not a
 *     supported WAV format.
 */
@Nullable
public static WavHeader peek(ExtractorInput input) throws IOException, InterruptedException {
  Assertions.checkNotNull(input);

  // Allocate a scratch buffer large enough to store the format chunk.
  ParsableByteArray scratch = new ParsableByteArray(16);

  // Attempt to read the RIFF chunk.
  ChunkHeader chunkHeader = ChunkHeader.peek(input, scratch);
  if (chunkHeader.id != WavUtil.RIFF_FOURCC) {
    return null;
  }

  input.peekFully(scratch.data, 0, 4);
  scratch.setPosition(0);
  int riffFormat = scratch.readInt();
  if (riffFormat != WavUtil.WAVE_FOURCC) {
    Log.e(TAG, "Unsupported RIFF format: " + riffFormat);
    return null;
  }

  // Skip chunks until we find the format chunk.
  chunkHeader = ChunkHeader.peek(input, scratch);
  while (chunkHeader.id != WavUtil.FMT_FOURCC) {
    input.advancePeekPosition((int) chunkHeader.size);
    chunkHeader = ChunkHeader.peek(input, scratch);
  }

  Assertions.checkState(chunkHeader.size >= 16);
  input.peekFully(scratch.data, 0, 16);
  scratch.setPosition(0);
  int type = scratch.readLittleEndianUnsignedShort();
  int numChannels = scratch.readLittleEndianUnsignedShort();
  int sampleRateHz = scratch.readLittleEndianUnsignedIntToInt();
  int averageBytesPerSecond = scratch.readLittleEndianUnsignedIntToInt();
  int blockAlignment = scratch.readLittleEndianUnsignedShort();
  int bitsPerSample = scratch.readLittleEndianUnsignedShort();

  int expectedBlockAlignment = numChannels * bitsPerSample / 8;
  if (blockAlignment != expectedBlockAlignment) {
    throw new ParserException("Expected block alignment: " + expectedBlockAlignment + "; got: "
        + blockAlignment);
  }

  @C.PcmEncoding int encoding = WavUtil.getEncodingForType(type, bitsPerSample);
  if (encoding == C.ENCODING_INVALID) {
    Log.e(TAG, "Unsupported WAV format: " + bitsPerSample + " bit/sample, type " + type);
    return null;
  }

  // If present, skip extensionSize, validBitsPerSample, channelMask, subFormatGuid, ...
  input.advancePeekPosition((int) chunkHeader.size - 16);

  return new WavHeader(
      numChannels, sampleRateHz, averageBytesPerSecond, blockAlignment, bitsPerSample, encoding);
}
 
Example #5
Source File: WavHeaderReader.java    From Telegram-FOSS with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Peeks and returns a {@code WavHeader}.
 *
 * @param input Input stream to peek the WAV header from.
 * @throws ParserException If the input file is an incorrect RIFF WAV.
 * @throws IOException If peeking from the input fails.
 * @throws InterruptedException If interrupted while peeking from input.
 * @return A new {@code WavHeader} peeked from {@code input}, or null if the input is not a
 *     supported WAV format.
 */
public static WavHeader peek(ExtractorInput input) throws IOException, InterruptedException {
  Assertions.checkNotNull(input);

  // Allocate a scratch buffer large enough to store the format chunk.
  ParsableByteArray scratch = new ParsableByteArray(16);

  // Attempt to read the RIFF chunk.
  ChunkHeader chunkHeader = ChunkHeader.peek(input, scratch);
  if (chunkHeader.id != WavUtil.RIFF_FOURCC) {
    return null;
  }

  input.peekFully(scratch.data, 0, 4);
  scratch.setPosition(0);
  int riffFormat = scratch.readInt();
  if (riffFormat != WavUtil.WAVE_FOURCC) {
    Log.e(TAG, "Unsupported RIFF format: " + riffFormat);
    return null;
  }

  // Skip chunks until we find the format chunk.
  chunkHeader = ChunkHeader.peek(input, scratch);
  while (chunkHeader.id != WavUtil.FMT_FOURCC) {
    input.advancePeekPosition((int) chunkHeader.size);
    chunkHeader = ChunkHeader.peek(input, scratch);
  }

  Assertions.checkState(chunkHeader.size >= 16);
  input.peekFully(scratch.data, 0, 16);
  scratch.setPosition(0);
  int type = scratch.readLittleEndianUnsignedShort();
  int numChannels = scratch.readLittleEndianUnsignedShort();
  int sampleRateHz = scratch.readLittleEndianUnsignedIntToInt();
  int averageBytesPerSecond = scratch.readLittleEndianUnsignedIntToInt();
  int blockAlignment = scratch.readLittleEndianUnsignedShort();
  int bitsPerSample = scratch.readLittleEndianUnsignedShort();

  int expectedBlockAlignment = numChannels * bitsPerSample / 8;
  if (blockAlignment != expectedBlockAlignment) {
    throw new ParserException("Expected block alignment: " + expectedBlockAlignment + "; got: "
        + blockAlignment);
  }

  @C.PcmEncoding int encoding = WavUtil.getEncodingForType(type, bitsPerSample);
  if (encoding == C.ENCODING_INVALID) {
    Log.e(TAG, "Unsupported WAV format: " + bitsPerSample + " bit/sample, type " + type);
    return null;
  }

  // If present, skip extensionSize, validBitsPerSample, channelMask, subFormatGuid, ...
  input.advancePeekPosition((int) chunkHeader.size - 16);

  return new WavHeader(
      numChannels, sampleRateHz, averageBytesPerSecond, blockAlignment, bitsPerSample, encoding);
}
 
Example #6
Source File: WavHeaderReader.java    From Telegram with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Peeks and returns a {@code WavHeader}.
 *
 * @param input Input stream to peek the WAV header from.
 * @throws ParserException If the input file is an incorrect RIFF WAV.
 * @throws IOException If peeking from the input fails.
 * @throws InterruptedException If interrupted while peeking from input.
 * @return A new {@code WavHeader} peeked from {@code input}, or null if the input is not a
 *     supported WAV format.
 */
public static WavHeader peek(ExtractorInput input) throws IOException, InterruptedException {
  Assertions.checkNotNull(input);

  // Allocate a scratch buffer large enough to store the format chunk.
  ParsableByteArray scratch = new ParsableByteArray(16);

  // Attempt to read the RIFF chunk.
  ChunkHeader chunkHeader = ChunkHeader.peek(input, scratch);
  if (chunkHeader.id != WavUtil.RIFF_FOURCC) {
    return null;
  }

  input.peekFully(scratch.data, 0, 4);
  scratch.setPosition(0);
  int riffFormat = scratch.readInt();
  if (riffFormat != WavUtil.WAVE_FOURCC) {
    Log.e(TAG, "Unsupported RIFF format: " + riffFormat);
    return null;
  }

  // Skip chunks until we find the format chunk.
  chunkHeader = ChunkHeader.peek(input, scratch);
  while (chunkHeader.id != WavUtil.FMT_FOURCC) {
    input.advancePeekPosition((int) chunkHeader.size);
    chunkHeader = ChunkHeader.peek(input, scratch);
  }

  Assertions.checkState(chunkHeader.size >= 16);
  input.peekFully(scratch.data, 0, 16);
  scratch.setPosition(0);
  int type = scratch.readLittleEndianUnsignedShort();
  int numChannels = scratch.readLittleEndianUnsignedShort();
  int sampleRateHz = scratch.readLittleEndianUnsignedIntToInt();
  int averageBytesPerSecond = scratch.readLittleEndianUnsignedIntToInt();
  int blockAlignment = scratch.readLittleEndianUnsignedShort();
  int bitsPerSample = scratch.readLittleEndianUnsignedShort();

  int expectedBlockAlignment = numChannels * bitsPerSample / 8;
  if (blockAlignment != expectedBlockAlignment) {
    throw new ParserException("Expected block alignment: " + expectedBlockAlignment + "; got: "
        + blockAlignment);
  }

  @C.PcmEncoding int encoding = WavUtil.getEncodingForType(type, bitsPerSample);
  if (encoding == C.ENCODING_INVALID) {
    Log.e(TAG, "Unsupported WAV format: " + bitsPerSample + " bit/sample, type " + type);
    return null;
  }

  // If present, skip extensionSize, validBitsPerSample, channelMask, subFormatGuid, ...
  input.advancePeekPosition((int) chunkHeader.size - 16);

  return new WavHeader(
      numChannels, sampleRateHz, averageBytesPerSecond, blockAlignment, bitsPerSample, encoding);
}