• R/O
  • HTTP
  • SSH
  • HTTPS

CsWin10Desktop3: Commit

Visual C# 7.0, Windows10 Desktop App


Commit MetaInfo

Revisión980511349dc5e7261d402d26aeac3680b2ae746d (tree)
Tiempo2017-10-15 20:49:22
Autorくまかみ工房 <kumakamikoubou@gmai...>
Commiterくまかみ工房

Log Message

CSCore.IWaveSource と ISampleSource の解釈が間違っていたので修正。

CSCore のサンプルのバグについても修正。

Cambiar Resumen

Diferencia

--- a/FDK/FDK.csproj
+++ b/FDK/FDK.csproj
@@ -132,9 +132,9 @@
132132 <Compile Include="カウンタ\経過時間測定.cs" />
133133 <Compile Include="メディア\XML.cs" />
134134 <Compile Include="メディア\グラフィックデバイス.cs" />
135- <Compile Include="メディア\サウンド\WASAPI\MediaFoundationSampleSource.cs" />
135+ <Compile Include="メディア\サウンド\WASAPI\MediaFoundationWaveSource.cs" />
136136 <Compile Include="メディア\サウンド\WASAPI\Mixer.cs" />
137- <Compile Include="メディア\サウンド\WASAPI\NVorbisSampleSource2.cs" />
137+ <Compile Include="メディア\サウンド\WASAPI\NVorbisResampledWaveSource.cs" />
138138 <Compile Include="メディア\サウンド\WASAPI\NVorbisSampleSource.cs" />
139139 <Compile Include="メディア\サウンド\WASAPI\SampleSourceFactory.cs" />
140140 <Compile Include="メディア\サウンド\WASAPI\Sound.cs" />
--- a/FDK/FDKUtilities.cs
+++ b/FDK/FDKUtilities.cs
@@ -100,6 +100,17 @@ namespace FDK
100100 }
101101
102102 /// <summary>
103+ /// 指定された位置を、それを超えないブロック境界に揃えて返す。
104+ /// </summary>
105+ /// <param name="position">位置[byte]。</param>
106+ /// <param name="blockAlign">ブロック境界[byte]。</param>
107+ /// <returns></returns>
108+ public static long 位置をブロック境界単位にそろえて返す( long position, long blockAlign )
109+ {
110+ return ( position - ( position % blockAlign ) );
111+ }
112+
113+ /// <summary>
103114 /// このメソッドの 呼び出し元のメソッド名 を返す。デバッグログ用。
104115 /// </summary>
105116 public static string 現在のメソッド名
--- a/FDK/メディア/サウンド/WASAPI/MediaFoundationSampleSource.cs
+++ b/FDK/メディア/サウンド/WASAPI/MediaFoundationWaveSource.cs
@@ -13,7 +13,7 @@ namespace FDK.メディア.サウンド.WASAPI
1313 /// <summary>
1414 /// 指定されたメディアファイル(動画, 音楽)をデコードして、<see cref="CSCore.IWaveSource"/> オブジェクトを生成する。
1515 /// </summary>
16- public class MediaFoundationSampleSource : IWaveSource
16+ public class MediaFoundationWaveSource : IWaveSource
1717 {
1818 /// <summary>
1919 /// シーク能力があるなら true 。
@@ -30,27 +30,20 @@ namespace FDK.メディア.サウンド.WASAPI
3030 } = null;
3131
3232 /// <summary>
33- /// デコード後のオーディオデータの長さ[byte]。
33+ /// デコード後のオーディオデータのすべての長さ[byte]。
3434 /// </summary>
3535 public long Length
3636 => this._EncodedWaveData.Length;
3737
3838 /// <summary>
39- /// 現在の位置。
40- /// 先頭からのオフセット[byte]で表す。
39+ /// 現在の再生位置[byte]。
4140 /// </summary>
4241 public long Position
4342 {
4443 get
4544 => this._Position;
46-
4745 set
48- {
49- if( ( 0 > value ) || ( ( this.Length > 0 ) && ( this.Length < value ) ) ) // ※ Length == 0 なら例外は出さない
50- throw new ArgumentOutOfRangeException( $"Position に指定された値が不正です。[{value}]" );
51-
52- this._Position = value;
53- }
46+ => this._Position = FDKUtilities.位置をブロック境界単位にそろえて返す( value, this.WaveFormat.BlockAlign );
5447 }
5548
5649
@@ -58,7 +51,7 @@ namespace FDK.メディア.サウンド.WASAPI
5851 /// コンストラクタ。
5952 /// 指定されたファイルを指定されたフォーマットでデコードし、内部にオンメモリで保管する。
6053 /// </summary>
61- public MediaFoundationSampleSource( string path, WaveFormat deviceFormat )
54+ public MediaFoundationWaveSource( string path, WaveFormat deviceFormat )
6255 {
6356 this.WaveFormat = new WaveFormat(
6457 deviceFormat.SampleRate, // 指定されたレート
@@ -149,35 +142,21 @@ namespace FDK.メディア.サウンド.WASAPI
149142 }
150143
151144 /// <summary>
152- /// 連続したsampleを読み込み、<see cref="Position"/> を読み込んだsampleの数だけ進める。
145+ /// 連続したデータを読み込み、<see cref="Position"/> を読み込んだ数だけ進める。
153146 /// </summary>
154- /// <param name="buffer">
155- /// 読み込んだsampleを格納するための配列。
156- /// このメソッドから戻ると、<paramref name="buffer"/> には <paramref name="offset"/> ~ (<paramref name="offset"/> + <paramref name="offset"/> - 1) の数の要素が格納されている。
157- /// </param>
158- /// <param name="offset">
159- /// <paramref name="buffer"/> に格納を始める位置[先頭からのsample]。
160- /// </param>
161- /// <param name="count">
162- /// 読み込む最大のsample数。
163- /// </param>
164- /// <returns>
165- /// <paramref name="buffer"/> に読み込んだsampleの総数。
166- /// </returns>
147+ /// <param name="buffer">読み込んだデータを格納するための配列。</param>
148+ /// <param name="offset"><paramref name="buffer"/> に格納を始める位置。</param>
149+ /// <param name="count">読み込む最大のデータ数。</param>
150+ /// <returns><paramref name="buffer"/> に読み込んだデータの総数。</returns>
167151 public int Read( byte[] buffer, int offset, int count )
168152 {
169153 // ※ 音がめちゃくちゃになるとうざいので、このメソッド内では例外を出さないこと。
170154 if( ( null == this._EncodedWaveData ) || ( null == buffer ) )
171155 return 0;
172156
173- // offset を 0~buffer.Length-1 に収める。
174- if( 0 > offset )
175- offset = 0;
176- else if( buffer.Length - 1 < offset )
177- offset = buffer.Length - 1;
178-
179- // count は、Length-Position, buffer.Length-offset, count のうちの最小値とする。
180- count = Math.Min( Math.Min( (int)( this.Length - this._Position ), count ), ( buffer.Length - offset ) );
157+ long 読み込み可能な最大count = ( this.Length - this._Position );
158+ if( count > 読み込み可能な最大count )
159+ count = (int) 読み込み可能な最大count;
181160
182161 if( 0 < count )
183162 {
--- a/FDK/メディア/サウンド/WASAPI/NVorbisSampleSource2.cs
+++ b/FDK/メディア/サウンド/WASAPI/NVorbisResampledWaveSource.cs
@@ -13,7 +13,7 @@ namespace FDK.メディア.サウンド.WASAPI
1313 /// 指定されたメディアファイル(動画, 音楽)を Vorbis としてデコードして、CSCore.IWaveSource オブジェクトを生成する。
1414 /// リサンプラーあり版。
1515 /// </summary>
16- public class NVorbisSampleSource2 : IWaveSource
16+ public class NVorbisResampledWaveSource : IWaveSource
1717 {
1818 public bool CanSeek => true; // オンメモリなので常にサポートできる。
1919
@@ -27,29 +27,28 @@ namespace FDK.メディア.サウンド.WASAPI
2727 } = null;
2828
2929 /// <summary>
30- /// デコード後のオーディオデータの長さ[byte]。
30+ /// デコード後のオーディオデータのすべての長さ[byte]。
3131 /// </summary>
3232 public long Length
3333 => this._EncodedWaveData.Length;
3434
3535 /// <summary>
36- /// 現在の位置。
37- /// 先頭からのオフセット[byte]で表す。
36+ /// 現在の再生位置[byte]。
3837 /// </summary>
3938 public long Position
4039 {
4140 get
4241 => this._Position;
4342 set
44- {
45- if( ( 0 > value ) || ( ( this.Length > 0 ) && ( this.Length < value ) ) ) // ※ Length == 0 なら例外は出さない
46- throw new ArgumentOutOfRangeException( $"Position に指定された値が不正です。[{value}]" );
47-
48- this._Position = value;
49- }
43+ => this._Position = FDKUtilities.位置をブロック境界単位にそろえて返す( value, this.WaveFormat.BlockAlign );
5044 }
5145
52- public NVorbisSampleSource2( Stream stream, WaveFormat deviceFormat )
46+
47+ /// <summary>
48+ /// コンストラクタ。
49+ /// 指定されたVorbisファイルを指定されたフォーマットでデコードし、内部にオンメモリで保管する。
50+ /// </summary>
51+ public NVorbisResampledWaveSource( Stream stream, WaveFormat deviceFormat )
5352 {
5453 this.WaveFormat = new WaveFormat(
5554 deviceFormat.SampleRate,
@@ -61,28 +60,30 @@ namespace FDK.メディア.サウンド.WASAPI
6160 using( var vorbisSource = new NVorbisSampleSource( stream, deviceFormat ) )
6261 using( var resampler = new DmoResampler( vorbisSource.ToWaveSource(), this.WaveFormat ) )
6362 {
64- this._EncodedWaveData = new byte[ resampler.Length ];
65- resampler.Read( this._EncodedWaveData, 0, (int) resampler.Length );
63+ // resampler.Length はサンプル単位ではなくフレーム単位。
64+ var サイズbyte = resampler.Length * resampler.WaveFormat.Channels; // 実際のサイズはチャンネル倍ある。
65+
66+ this._EncodedWaveData = new byte[ サイズbyte ];
67+ resampler.Read( this._EncodedWaveData, 0, (int) サイズbyte ); // でもこっちはバイト単位。
6668 }
6769 }
68- public void Dispose()
69- {
70- this._EncodedWaveData = null;
71- }
70+
71+ /// <summary>
72+ /// 連続したデータを読み込み、<see cref="Position"/> を読み込んだ数だけ進める。
73+ /// </summary>
74+ /// <param name="buffer">読み込んだデータを格納するための配列。</param>
75+ /// <param name="offset"><paramref name="buffer"/> に格納を始める位置。</param>
76+ /// <param name="count">読み込む最大のデータ数。</param>
77+ /// <returns><paramref name="buffer"/> に読み込んだデータの総数。</returns>
7278 public int Read( byte[] buffer, int offset, int count )
7379 {
7480 // ※ 音がめちゃくちゃになるとうざいので、このメソッド内では例外を出さないこと。
7581 if( ( null == this._EncodedWaveData ) || ( null == buffer ) )
7682 return 0;
7783
78- // offset を 0~buffer.Length-1 に収める。
79- if( 0 > offset )
80- offset = 0;
81- else if( buffer.Length - 1 < offset )
82- offset = buffer.Length - 1;
83-
84- // count は、Length-Position, buffer.Length-offset, count のうちの最小値とする。
85- count = Math.Min( Math.Min( (int) ( this.Length - this._Position ), count ), ( buffer.Length - offset ) );
84+ long 読み込み可能な最大count = ( this.Length - this._Position );
85+ if( count > 読み込み可能な最大count )
86+ count = (int) 読み込み可能な最大count;
8687
8788 if( 0 < count )
8889 {
@@ -99,6 +100,14 @@ namespace FDK.メディア.サウンド.WASAPI
99100 return count;
100101 }
101102
103+ /// <summary>
104+ /// 解放する。
105+ /// </summary>
106+ public void Dispose()
107+ {
108+ this._EncodedWaveData = null;
109+ }
110+
102111 private byte[] _EncodedWaveData = null;
103112 private long _Position = 0;
104113 }
--- a/FDK/メディア/サウンド/WASAPI/NVorbisSampleSource.cs
+++ b/FDK/メディア/サウンド/WASAPI/NVorbisSampleSource.cs
@@ -29,14 +29,13 @@ namespace FDK.メディア.サウンド.WASAPI
2929 {
3030 get
3131 => ( this.CanSeek ) ? this._vorbisReader.DecodedPosition : 0;
32-
3332 set
3433 => this._vorbisReader.DecodedPosition = ( this.CanSeek ) ?
3534 value : throw new InvalidOperationException( "DecodedNVorbisSource is not seekable." );
3635 }
3736
3837 public long Length
39- => ( this.CanSeek ) ? this._vorbisReader.TotalSamples : 0;
38+ => ( this.CanSeek ) ? this._vorbisReader.TotalSamples * this.WaveFormat.Channels : 0; // TotalSamples はフレーム数を返す。
4039
4140
4241 public NVorbisSampleSource( Stream stream, WaveFormat deviceFormat )
--- a/FDK/メディア/サウンド/WASAPI/SampleSourceFactory.cs
+++ b/FDK/メディア/サウンド/WASAPI/SampleSourceFactory.cs
@@ -24,7 +24,7 @@ namespace FDK.メディア.サウンド.WASAPI
2424 {
2525 using( var audioStream = new FileStream( path, FileMode.Open ) )
2626 {
27- return new NVorbisSampleSource2( audioStream, device.WaveFormat )
27+ return new NVorbisResampledWaveSource( audioStream, device.WaveFormat )
2828 .ToSampleSource();
2929 }
3030 }
@@ -53,7 +53,7 @@ namespace FDK.メディア.サウンド.WASAPI
5353 //----------------
5454 try
5555 {
56- return new MediaFoundationSampleSource( path, device.WaveFormat )
56+ return new MediaFoundationWaveSource( path, device.WaveFormat )
5757 .ToSampleSource();
5858 }
5959 catch
--- a/FDK/メディア/サウンド/WASAPI/Sound.cs
+++ b/FDK/メディア/サウンド/WASAPI/Sound.cs
@@ -24,17 +24,14 @@ namespace FDK.メディア.サウンド.WASAPI
2424 /// シークが可能なら true。
2525 /// </summary>
2626 public bool CanSeek
27- => this._SampleSource.CanSeek;
27+ => this._BaseSampleSource.CanSeek;
2828
2929 /// <summary>
3030 /// このサウンドのフォーマット。
3131 /// </summary>
3232 public WaveFormat WaveFormat
33- => this._SampleSource.WaveFormat;
33+ => this._BaseSampleSource.WaveFormat;
3434
35- /// <summary>
36- /// 現在の再生位置。sample単位。
37- /// </summary>
3835 /// <remarks>
3936 /// 1つの <see cref="SampleSource"/>を複数の<see cref="Sound"/>インスタンスで共有できるように、
4037 /// このプロパティは<see cref="Sound"/>インスタンスごとに独立して管理する。
@@ -47,11 +44,8 @@ namespace FDK.メディア.サウンド.WASAPI
4744 => this._Position = Math.Min( Math.Max( value, 0 ), this.Length );
4845 }
4946
50- /// <summary>
51- /// 全体の長さ。sample単位。
52- /// </summary>
5347 public long Length
54- => this._SampleSource.Length;
48+ => this._BaseSampleSource.Length;
5549
5650 /// <summary>
5751 /// 音量。0.0(無音)~1.0(原音)~...上限なし
@@ -75,26 +69,26 @@ namespace FDK.メディア.サウンド.WASAPI
7569 public Sound( SoundDevice device, ISampleSource sampleSource )
7670 : this( device )
7771 {
78- this._SampleSource = sampleSource;
72+ this._BaseSampleSource = sampleSource;
7973 }
8074 public void Dispose()
8175 {
8276 this.Stop();
8377
8478 //this._SampleSource?.Dispose(); Dispose は外部で。(SampleSource は複数の Sound で共有されている可能性があるため。)
85- this._SampleSource = null;
79+ this._BaseSampleSource = null;
8680
8781 this._DeviceRef = null;
8882 }
89- public void Play( long 再生開始位置sample = 0 )
83+ public void Play( long 再生開始位置frame = 0 )
9084 {
9185 if( this._DeviceRef.TryGetTarget( out SoundDevice device ) )
9286 {
93- // SampleSource の位置を、再生開始位置へ移動。
94- if( this._SampleSource.CanSeek )
87+ // BaseSampleSource の位置を、再生開始位置へ移動。
88+ if( this._BaseSampleSource.CanSeek )
9589 {
96- this._Position = 再生開始位置sample;
97- //this._SampleSource.Position = 再生開始位置sample; --> ここではまだ設定しない。Read() で設定する。
90+ this._Position = 再生開始位置frame * this.WaveFormat.Channels;
91+ //this._BaseSampleSource.Position = this._Position; --> ここではまだ設定しない。Read() で設定する。
9892 }
9993 else
10094 {
@@ -106,20 +100,16 @@ namespace FDK.メディア.サウンド.WASAPI
106100 }
107101 }
108102 public void Play( double 再生開始位置sec )
109- => this.Play( this._秒ToSample( 再生開始位置sec ) );
103+ => this.Play( this._秒ToFrame( 再生開始位置sec ) );
110104 public int Read( float[] buffer, int offset, int count )
111105 {
112- if( this._SampleSource.Length == this._Position )
106+ if( this._BaseSampleSource.Length == this._Position )
113107 return 0; // 同じ場合でも Read() が 2 とか返してきて永遠に終わらないことがあるので、ここで阻止する。
114108
115- // 同じ SampleSource を複数の Sound で共有するために、Position は Sound ごとに管理している。
116- this._SampleSource.Position = this._Position;
117-
118- // 読み込み。
119- var readCount = this._SampleSource.Read( buffer, offset, count );
120-
121- // こちら側の Position も更新。
122- this._Position = this._SampleSource.Position;
109+ // 1つの BaseSampleSource を複数の Sound で共有するために、Position は Sound ごとに管理している。
110+ this._BaseSampleSource.Position = this._Position;
111+ var readCount = this._BaseSampleSource.Read( buffer, offset, count ); // 読み込み。
112+ this._Position = this._BaseSampleSource.Position;
123113
124114 return readCount;
125115 }
@@ -132,23 +122,19 @@ namespace FDK.メディア.サウンド.WASAPI
132122 }
133123
134124 private WeakReference<SoundDevice> _DeviceRef = null;
135- private ISampleSource _SampleSource = null;
125+ private ISampleSource _BaseSampleSource = null;
136126 private long _Position = 0;
137127 private float _Volume = 1.0f;
138128
139- private long _秒ToSample( double 時間sec )
129+ private long _秒ToFrame( double 時間sec )
140130 {
141- var wf = this._SampleSource.WaveFormat;
142-
143- int 時間sample = (int) ( 時間sec * wf.SampleRate * wf.Channels + 0.5 ); // +0.5 で四捨五入ができる
144-
145- return FDKUtilities.位置をブロック境界単位にそろえて返す( 時間sample, wf.BlockAlign );
131+ var wf = this._BaseSampleSource.WaveFormat;
132+ return (long) ( 時間sec * wf.SampleRate + 0.5 ); // +0.5 で四捨五入ができる
146133 }
147- private double _SampleTo秒( long 時間sample )
134+ private double _FrameTo秒( long 時間frame )
148135 {
149- var wf = this._SampleSource.WaveFormat;
150-
151- return 時間sample / ( wf.Channels * wf.SampleRate );
136+ var wf = this._BaseSampleSource.WaveFormat;
137+ return (double) 時間frame / wf.SampleRate;
152138 }
153139 }
154140 }
Show on old repository browser