私有欄位
#region 私有成員
private const int MaxLatencyMs = 300;
private const int NumberRecordNotifications = 4;
private readonly CircularBuffer circularBuffer;
private readonly int m_BufferBytes;
private readonly bool m_OwnsDevice;
private readonly int notifySize;
private readonly BufferPositionNotify[] positionNotify;
private bool isRunning;
private SecondaryBuffer m_Buffer;
private Device m_Device;
private int nextWriteOffset;
private AutoResetEvent notificationEvent;
private Notify notify;
private Thread notifyThread;
#endregion
多重建構子
#region 建構函數
public SoundPlayer(Control owner, WaveFormat format) : this(owner, null, format) { }
public SoundPlayer(Control owner, Device device, WaveFormat format)
{
positionNotify = new BufferPositionNotify[5];
notificationEvent = null; notify = null; notifyThread = null; notifySize = 0;
m_Device = device;
if (m_Device == null) { m_Device = new Device(); m_Device.SetCooperativeLevel(owner, CooperativeLevel.Normal); m_OwnsDevice = true; }
// 通知大小 = 每秒位元組數 / 8 (經驗值),下限 1024,對齊 BlockAlign
notifySize = (1024 > (format.AverageBytesPerSecond / 8)) ? 1024 : (format.AverageBytesPerSecond / 8);
notifySize -= notifySize % format.BlockAlign;
m_BufferBytes = notifySize * 4; // 總緩衝區 = 4 通知區塊
BufferDescription desc = new BufferDescription(format)
{
ControlVolume = true,
ControlPositionNotify = true,
CanGetCurrentPosition = true,
Control3D = false,
ControlEffects = false,
ControlFrequency = true,
ControlPan = true,
GlobalFocus = true,
BufferBytes = m_BufferBytes
};
m_Buffer = new SecondaryBuffer(desc, m_Device);
circularBuffer = new CircularBuffer(m_BufferBytes * 10); // 10 倍緩衝
InitNotifications();
m_Buffer.Play(0, BufferPlayFlags.Looping);
}
public SoundPlayer(Control owner, int sr, short bps, short ch) : this(owner, null, DirectSoundManager.CreateWaveFormat(sr, bps, ch)) { }
public SoundPlayer(Control owner, Device device, int sr, short bps, short ch) : this(owner, device, DirectSoundManager.CreateWaveFormat(sr, bps, ch)) { }
#endregion
關鍵參數說明
notifySize:每次通知處理的資料量,影響延遲與 CPU 平衡。
m_BufferBytes:DirectSound 緩衝區總大小 (4 通知區塊)。
circularBuffer:容量為 DirectSound 緩衝區 10 倍,吸收網路抖動。
BufferPlayFlags.Looping:啟用循環播放,寫入指標自動回繞。