read static method

Wav read(
  1. Uint8List bytes
)

Read a Wav from a byte buffer.

Not all formats are supported. See WavFormat for a canonical list. Unrecognized metadata will be ignored.

Implementation

static Wav read(Uint8List bytes) {
  // Utils for reading.
  var byteReader = BytesReader(bytes)
    ..assertString(_kStrRiff)
    ..readUint32() // File size.
    ..assertString(_kStrWave)
    ..findChunk(_kStrFmt);

  final fmtSize = roundUpToEven(byteReader.readUint32());
  var formatCode = byteReader.readUint16();
  final numChannels = byteReader.readUint16();
  final samplesPerSecond = byteReader.readUint32();
  byteReader.readUint32(); // Bytes per second.
  final bytesPerSampleAllChannels = byteReader.readUint16();
  final bitsPerSample = byteReader.readUint16();

  if (formatCode == _kWavExtensible) {
    // Size of the extension
    // 22 for wav extensible, 0 otherwise
    final cbSize = byteReader.readUint16();

    if (cbSize == _kExCbSize) {
      final validBitsPerSample = byteReader.readUint16();
      if (validBitsPerSample != bitsPerSample) {
        throw UnimplementedError(
          'wValidBitsPerSample is different from wBitsPerSample.'
          ' Please file a bug on package:wav.',
        );
      }

      // channel mask
      byteReader.readUint32();

      // The rest 16 bytes are the GUID including the data format code.
      // The first two bytes are the data format code.
      // We convert the extensible format into the subformat.
      formatCode = byteReader.readUint16();

      byteReader.skip(14);
    } else {
      throw FormatException(
        'Extension size of WAVE_FORMAT_EXTENSIBLE should be $_kExCbSize',
      );
    }
  } else if (fmtSize > _kFormatSize) {
    byteReader.skip(fmtSize - _kFormatSize);
  }

  byteReader.findChunk(_kStrData);
  final dataSize = byteReader.readUint32();
  final numSamples = dataSize ~/ bytesPerSampleAllChannels;
  final channels = <Float64List>[];
  for (int i = 0; i < numChannels; ++i) {
    channels.add(Float64List(numSamples));
  }
  final format = _getFormat(formatCode, bitsPerSample);

  // Read samples.
  final readSample = byteReader.getSampleReader(format);
  for (int i = 0; i < numSamples; ++i) {
    for (int j = 0; j < numChannels; ++j) {
      channels[j][i] = readSample();
    }
  }
  return Wav(channels, samplesPerSecond, format);
}