80 lines
2.8 KiB
C#
80 lines
2.8 KiB
C#
using System;
|
|
using System.IO;
|
|
|
|
namespace Ryuclaw.Audio.Shared
|
|
{
|
|
public class WaveStreamer : IDisposable
|
|
{
|
|
private readonly FileStream _fileStream;
|
|
private readonly BinaryReader _reader;
|
|
|
|
private long _dataPosition; // This will store the position where audio data begins in the file.
|
|
private int _dataLength; // This will store the length of the audio data.
|
|
|
|
private WaveHeader _header;
|
|
|
|
public WaveStreamer(string filePath)
|
|
{
|
|
_header = new WaveHeader();
|
|
_fileStream = new FileStream(filePath, FileMode.Open);
|
|
_reader = new BinaryReader(_fileStream);
|
|
LoadHeader();
|
|
}
|
|
|
|
private void LoadHeader()
|
|
{
|
|
// RIFF header
|
|
string chunkID = new string(_reader.ReadChars(4));
|
|
if (chunkID != "RIFF") throw new Exception("Not a valid WAV file.");
|
|
|
|
var ChunkSize = _reader.ReadInt32(); // Chunk size
|
|
string format = new string(_reader.ReadChars(4));
|
|
if (format != "WAVE") throw new Exception("Not a valid WAV file.");
|
|
|
|
// fmt sub-chunk
|
|
string subchunk1ID = new string(_reader.ReadChars(4));
|
|
if (subchunk1ID != "fmt ") throw new Exception("Expected fmt chunk.");
|
|
|
|
int subChunk1Size = _reader.ReadInt32();
|
|
short audioFormat = _reader.ReadInt16();
|
|
var NumChannels = _reader.ReadInt16();
|
|
var SampleRate = _reader.ReadInt32();
|
|
var ByteRate = _reader.ReadInt32(); // Byte rate
|
|
var BlockAlign = _reader.ReadInt16(); // Block align
|
|
var BitsPerSample = _reader.ReadInt16();
|
|
_header = new WaveHeader(SampleRate, ChunkSize, ByteRate, BitsPerSample, NumChannels, BlockAlign);
|
|
if (audioFormat != 1 || subChunk1Size != 16)
|
|
{
|
|
throw new Exception("Only PCM format WAV files are supported.");
|
|
}
|
|
|
|
// data sub-chunk
|
|
string subchunk2ID = new string(_reader.ReadChars(4));
|
|
if (subchunk2ID != "data") throw new Exception("Expected data chunk.");
|
|
|
|
_dataLength = _reader.ReadInt32();
|
|
_dataPosition = _fileStream.Position; // Store the position where audio data begins.
|
|
}
|
|
|
|
public byte[] ReadData(int byteCount)
|
|
{
|
|
_fileStream.Seek(_dataPosition, SeekOrigin.Begin);
|
|
byte[] buffer = _reader.ReadBytes(byteCount); // Read a chunk of audio data.
|
|
_dataPosition = _fileStream.Position; // Update the position to start from next time.
|
|
return buffer;
|
|
}
|
|
|
|
public bool HasDataLeft()
|
|
{
|
|
return _fileStream.Position < _dataPosition + _dataLength;
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
_reader.Dispose();
|
|
_fileStream.Dispose();
|
|
}
|
|
}
|
|
}
|
|
|