Ryuclaw.Mac/Ryuclaw.Audio.Shared/WaveStreamer.cs

80 lines
2.8 KiB
C#
Raw Permalink Normal View History

2023-08-28 16:38:06 +00:00
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();
}
}
}