internal class Mixer : CSCore.ISampleSource
{
/// <summary>
- /// 音量。0.0(無音)~1.0(原音)。
+ /// 音量。0.0(無音)~1.0(原音)。
/// </summary>
public float Volume
{
this._WaveFormat = deviceWaveFormat;
}
+ /// <summary>
+ /// ミキサに登録されているサウンドをすべて停止し解放する。
+ /// </summary>
public void Dispose()
{
lock( this._スレッド間同期 )
if( null == sound )
throw new ArgumentNullException();
- if( ( sound.SampleSource.WaveFormat.Channels != this._WaveFormat.Channels ) ||
- ( sound.SampleSource.WaveFormat.SampleRate != this._WaveFormat.SampleRate ) ||
- ( sound.SampleSource.WaveFormat.WaveFormatTag != AudioEncoding.IeeeFloat ) ) // IWaveSource.ToSampleSource() で作成した ISampleSource ならすべて 32bit-float であるはず。
+ if( ( sound.SampleSource.WaveFormat.Channels != this._WaveFormat.Channels ) || // 同じチャンネル数、
+ ( sound.SampleSource.WaveFormat.SampleRate != this._WaveFormat.SampleRate ) || // 同じ周波数、
+ ( sound.SampleSource.WaveFormat.WaveFormatTag != AudioEncoding.IeeeFloat ) ) // 常に 32bit-float であること。
{
- // これらの変換は面倒なのでサポートしない。
+ // 違った場合の変換はサポートしない。
throw new ArgumentException( "ミキサーと同じチャンネル数、サンプルレート、かつ 32bit float 型である必要があります。" );
}
/// <summary>
/// Sound がミキサーに登録されているかを調べる。
/// </summary>
- /// <returns>Sound がミキサーに追加済みなら true 。</returns>
+ /// <returns>
+ /// Sound がミキサーに追加済みなら true 。
+ /// </returns>
public bool Contains( Sound sound )
{
if( null == sound )
/// <summary>
/// バッファにサウンドデータを出力する。
/// </summary>
- /// <returns>実際に出力したサンプル数。</returns>
+ /// <returns>
+ /// 実際に出力したサンプル数。
+ /// </returns>
public int Read( float[] バッファ, int バッファの出力開始位置, int 出力サンプル数 )
{
// ミキサに登録されている Sound の入力とこのメソッドが出力するデータはいずれも常に 32bit-float であり、
lock( this._スレッド間同期 )
{
// 中間バッファが十分あることを確認する。足りなければ新しく確保して戻ってくる。
- this._ä¸é\96\93ã\83\90ã\83\83ã\83\95ã\82¡ = this._ä¸é\96\93ã\83\90ã\83\83ã\83\95ã\82¡.CheckBuffer( å\87ºå\8a\9bã\82µã\83³ã\83\97ã\83«æ\95° ); // ã\82µã\83³ã\83\97ã\83«æ\95°ã\81§ã\81\82ã\81£ã\81¦、フレーム数(サンプル数×チャンネル数)ではない。
+ this._ä¸é\96\93ã\83\90ã\83\83ã\83\95ã\82¡ = this._ä¸é\96\93ã\83\90ã\83\83ã\83\95ã\82¡.CheckBuffer( å\87ºå\8a\9bã\82µã\83³ã\83\97ã\83«æ\95° ); // ã\82µã\83³ã\83\97ã\83«æ\95°ã\81§ã\81\82ã\82\8a、フレーム数(サンプル数×チャンネル数)ではない。
- // 無音を出力する。
+ // まずは無音で埋める。
Array.Clear( バッファ, 0, 出力サンプル数 );
- // ã\83\9fã\82ã\82µã\81«ç\99»é\8c²ã\81\95ã\82\8cã\81¦ã\81\84ã\82\8bã\81\99ã\81¹ã\81¦ã\81® Sound ã\82\92å\87ºå\8a\9bする。
+ // ã\81\9dã\81®ä¸\8aã\81«ã\80\81ã\83\9fã\82ã\82µã\81«ç\99»é\8c²ã\81\95ã\82\8cã\81¦ã\81\84ã\82\8bã\81\99ã\81¹ã\81¦ã\81® Sound ã\82\92å\8a ç®\97å\90\88æ\88\90する。
if( 0 < this._Sounds.Count )
{
for( int m = this._Sounds.Count - 1; m >= 0; m-- ) // リストから Remove する場合があるので、リストの後ろから進める。
// 中間バッファにサウンドデータを受け取る。
int 受け取ったサンプル数 = sound.SampleSource.Read( this._中間バッファ, 0, 出力サンプル数 );
- // 中間バッファから出力バッファへ転送する。
+ // 中間バッファから出力バッファへ合成する。
for( int i = バッファの出力開始位置, n = 0; n < 受け取ったサンプル数; i++, n++ )
{
float data = this._中間バッファ[ n ] // 原音
- * sound.Volume // 個別音量
- * this._Volume; // ã\83\9fã\82ã\82µé\9f³é\87\8f
+ * sound.Volume // 個別音量(Sound)
+ * this._Volume; // ã\83\9eã\82¹ã\82¿é\9f³é\87\8fï¼\88ã\83\9fã\82ã\82µï¼\89
- // ベースに無音を出力済みなので、上書きじゃなく常に加算。
+ // 先に無音を出力済みなので、上書きかどうかを気にしないで常に加算。
バッファ[ i ] += data;
}
}
private float _Volume = 1.0f;
+
private CSCore.WaveFormat _WaveFormat = null;
+
private readonly List<Sound> _Sounds = new List<Sound>();
+
private float[] _中間バッファ = null;
+
private readonly object _スレッド間同期 = new object();
}
}