Revisión | a34ce689c7fc802c5e5e6e5684263dff715310c3 (tree) |
---|---|
Tiempo | 2017-05-20 18:03:38 |
Autor | yyagi <yyagi.dtxmania@gmai...> |
Commiter | yyagi |
WASAPI共有の対応用。Win10での遅延小モードが使えると尚良し。取り急ぎログ出力を強化し、希望バッファサイズを100msから10msにした。
@@ -33,8 +33,8 @@ using System.Resources; | ||
33 | 33 | // すべての値を指定するか、下のように '*' を使ってビルドおよびリビジョン番号を |
34 | 34 | // 既定値にすることができます: |
35 | 35 | // [assembly: AssemblyVersion("1.0.*")] |
36 | -[assembly: AssemblyVersion( "108.0.0.0" )] | |
37 | -[assembly: AssemblyFileVersion( "108.0.0.0" )] | |
36 | +[assembly: AssemblyVersion("109.0.0.0")] | |
37 | +[assembly: AssemblyFileVersion("109.0.0.0")] | |
38 | 38 | [assembly: NeutralResourcesLanguageAttribute("ja-JP")] |
39 | 39 | |
40 | 40 | // このアセンブリは「ライブラリ」である(難読化ツールへの指示)。 |
@@ -133,7 +133,7 @@ namespace FDK | ||
133 | 133 | /// <summary> |
134 | 134 | /// <para>WASAPI 共有モード出力における再生遅延[ms]。ユーザが決定する。</para> |
135 | 135 | /// </summary> |
136 | - public static int SoundDelaySharedWASAPI = 100; | |
136 | + public static int SoundDelaySharedWASAPI = 10; | |
137 | 137 | /// <summary> |
138 | 138 | /// <para>排他WASAPIバッファの更新間隔。出力間隔ではないので注意。</para> |
139 | 139 | /// <para>→ 自動設定されるのでSoundDelay よりも小さい値であること。(小さすぎる場合はBASSによって自動修正される。)</para> |
@@ -143,7 +143,7 @@ namespace FDK | ||
143 | 143 | /// <para>共有WASAPIバッファの更新間隔。出力間隔ではないので注意。</para> |
144 | 144 | /// <para>SoundDelay よりも小さい値であること。(小さすぎる場合はBASSによって自動修正される。)</para> |
145 | 145 | /// </summary> |
146 | - public static int SoundUpdatePeriodSharedWASAPI = 6; | |
146 | + public static int SoundUpdatePeriodSharedWASAPI = 3; | |
147 | 147 | /// <summary> |
148 | 148 | /// WASAPI利用時に、サウンドバッファの更新をevent drivenにするか、pollingにするかの設定。 |
149 | 149 | /// デフォルト設定はpolling。event drivenにすることで、よりラグを小さくできるが、CPU負荷は若干上昇する。 |
@@ -172,29 +172,29 @@ namespace FDK | ||
172 | 172 | |
173 | 173 | // BASS の初期化。 |
174 | 174 | |
175 | - int n周波数 = 44100; // 仮決め。lデバイス(≠ドライバ)がネイティブに対応している周波数であれば何でもいい?ようだ。BASSWASAPIでデバイスの周波数は変えられる。いずれにしろBASSMXで自動的にリサンプリングされる。 | |
176 | - // BASS_Initは、WASAPI初期化の直前に行うよう変更。WASAPIのmix周波数を使って初期化することで、余計なリサンプリング処理を省き高速化するため。 | |
177 | - //if( !Bass.BASS_Init( nデバイス, n周波数, BASSInit.BASS_DEVICE_DEFAULT, IntPtr.Zero ) ) | |
178 | - // throw new Exception( string.Format( "BASS (WASAPI) の初期化に失敗しました。(BASS_Init)[{0}]", Bass.BASS_ErrorGetCode().ToString() ) ); | |
175 | + int n周波数 = 44100; // 仮決め。lデバイス(≠ドライバ)がネイティブに対応している周波数であれば何でもいい?ようだ。BASSWASAPIでデバイスの周波数は変えられる。いずれにしろBASSMXで自動的にリサンプリングされる。 | |
176 | + // BASS_Initは、WASAPI初期化の直前に行うよう変更。WASAPIのmix周波数を使って初期化することで、余計なリサンプリング処理を省き高速化するため。 | |
177 | + //if( !Bass.BASS_Init( nデバイス, n周波数, BASSInit.BASS_DEVICE_DEFAULT, IntPtr.Zero ) ) | |
178 | + // throw new Exception( string.Format( "BASS (WASAPI) の初期化に失敗しました。(BASS_Init)[{0}]", Bass.BASS_ErrorGetCode().ToString() ) ); | |
179 | 179 | |
180 | 180 | |
181 | 181 | #region [ デバッグ用: WASAPIデバイスのenumerateと、ログ出力 ] |
182 | 182 | // (デバッグ用) |
183 | - //Trace.TraceInformation( "WASAPIデバイス一覧:" ); | |
184 | - //int a, count = 0; | |
185 | - //BASS_WASAPI_DEVICEINFO wasapiDevInfo; | |
186 | - //for ( a = 0; ( wasapiDevInfo = BassWasapi.BASS_WASAPI_GetDeviceInfo( a ) ) != null; a++ ) | |
187 | - //{ | |
188 | - // if ( ( wasapiDevInfo.flags & BASSWASAPIDeviceInfo.BASS_DEVICE_INPUT ) == 0 // device is an output device (not input) | |
189 | - // && ( wasapiDevInfo.flags & BASSWASAPIDeviceInfo.BASS_DEVICE_ENABLED ) != 0 ) // and it is enabled | |
190 | - // { | |
191 | - // Trace.TraceInformation( "WASAPI Device #{0}: {1}: IsDefault={2}, defPeriod={3}s, minperiod={4}s, mixchans={5}, mixfreq={6}", | |
192 | - // a, | |
193 | - // wasapiDevInfo.name, | |
194 | - // wasapiDevInfo.IsDefault, wasapiDevInfo.defperiod, wasapiDevInfo.minperiod, wasapiDevInfo.mixchans, wasapiDevInfo.mixfreq ); | |
195 | - // count++; // count it | |
196 | - // } | |
197 | - //} | |
183 | + Trace.TraceInformation("WASAPIデバイス一覧:"); | |
184 | + int a, count = 0; | |
185 | + BASS_WASAPI_DEVICEINFO wasapiDevInfo; | |
186 | + for (a = 0; (wasapiDevInfo = BassWasapi.BASS_WASAPI_GetDeviceInfo(a)) != null; a++) | |
187 | + { | |
188 | + if ((wasapiDevInfo.flags & BASSWASAPIDeviceInfo.BASS_DEVICE_INPUT) == 0 // device is an output device (not input) | |
189 | + && (wasapiDevInfo.flags & BASSWASAPIDeviceInfo.BASS_DEVICE_ENABLED) != 0) // and it is enabled | |
190 | + { | |
191 | + Trace.TraceInformation("WASAPI Device #{0}: {1}: IsDefault={2}, defPeriod={3}s, minperiod={4}s, mixchans={5}, mixfreq={6}", | |
192 | + a, | |
193 | + wasapiDevInfo.name, | |
194 | + wasapiDevInfo.IsDefault, wasapiDevInfo.defperiod, wasapiDevInfo.minperiod, wasapiDevInfo.mixchans, wasapiDevInfo.mixfreq); | |
195 | + count++; // count it | |
196 | + } | |
197 | + } | |
198 | 198 | #endregion |
199 | 199 | |
200 | 200 | // BASS WASAPI の初期化。 |
@@ -242,7 +242,7 @@ namespace FDK | ||
242 | 242 | //var flags = ( mode == Eデバイスモード.排他 ) ? BASSWASAPIInit.BASS_WASAPI_AUTOFORMAT | BASSWASAPIInit.BASS_WASAPI_EVENT | BASSWASAPIInit.BASS_WASAPI_EXCLUSIVE : BASSWASAPIInit.BASS_WASAPI_AUTOFORMAT | BASSWASAPIInit.BASS_WASAPI_EVENT; |
243 | 243 | if ( COS.bIsWin7OrLater && CSound管理.bSoundUpdateByEventWASAPI ) |
244 | 244 | { |
245 | - flags |= BASSWASAPIInit.BASS_WASAPI_EVENT; // Win7以降の場合は、WASAPIをevent drivenで動作させてCPU負荷減、レイテインシ改善 | |
245 | + flags |= BASSWASAPIInit.BASS_WASAPI_EVENT; // Win7以降の場合は、WASAPIをevent drivenで動作させてレイテインシ改善可能 | |
246 | 246 | } |
247 | 247 | if ( BassWasapi.BASS_WASAPI_Init( nDevNo, n周波数, nチャンネル数, flags, ( n希望バッファサイズms / 1000.0f ), ( n更新間隔ms / 1000.0f ), this.tWasapiProc, IntPtr.Zero ) ) |
248 | 248 | { |
@@ -268,14 +268,15 @@ namespace FDK | ||
268 | 268 | this.n実バッファサイズms = (long) ( wasapiInfo.buflen * 1000.0f / n1秒のバイト数 ); |
269 | 269 | this.n実出力遅延ms = 0; // 初期値はゼロ |
270 | 270 | Trace.TraceInformation( "使用デバイス: #" + nDevNo + " : " + deviceInfo.name + ", flags=" + deviceInfo.flags ); |
271 | - Trace.TraceInformation( "BASS を初期化しました。(WASAPI排他モード, {0}Hz, {1}ch, フォーマット:{2}, バッファ{3}bytes [{4}ms(希望{5}ms)], 更新間隔{6}ms)", | |
271 | + Trace.TraceInformation( "BASS を初期化しました。(WASAPI排他モード, {0}Hz, {1}ch, フォーマット:{2}, バッファ{3}bytes [{4}ms(希望{5}ms)], 更新間隔{6}ms, イベント動作={7})", | |
272 | 272 | wasapiInfo.freq, |
273 | 273 | wasapiInfo.chans, |
274 | 274 | wasapiInfo.format.ToString(), |
275 | 275 | wasapiInfo.buflen, |
276 | 276 | n実バッファサイズms.ToString(), |
277 | 277 | n希望バッファサイズms.ToString(), |
278 | - n更新間隔ms.ToString() ); | |
278 | + n更新間隔ms.ToString(), | |
279 | + wasapiInfo.IsEventDriven.ToString() ); | |
279 | 280 | Trace.TraceInformation( "デバイスの最小更新時間={0}ms, 既定の更新時間={1}ms", deviceInfo.minperiod * 1000, deviceInfo.defperiod * 1000 ); |
280 | 281 | this.bIsBASSFree = false; |
281 | 282 | //----------------- |
@@ -289,16 +290,38 @@ namespace FDK | ||
289 | 290 | |
290 | 291 | this.n実出力遅延ms = 0; // 初期値はゼロ |
291 | 292 | var devInfo = BassWasapi.BASS_WASAPI_GetDeviceInfo( BassWasapi.BASS_WASAPI_GetDevice() ); // 共有モードの場合、更新間隔はデバイスのデフォルト値に固定される。 |
292 | - Trace.TraceInformation( "BASS を初期化しました。(WASAPI共有モード, {0}ms, 更新間隔{1}ms)", n希望バッファサイズms, devInfo.defperiod * 1000.0f ); | |
293 | + //Trace.TraceInformation( "BASS を初期化しました。(WASAPI共有モード, {0}ms, 更新間隔{1}ms)", n希望バッファサイズms, devInfo.defperiod * 1000.0f ); | |
294 | + var wasapiInfo = BassWasapi.BASS_WASAPI_GetInfo(); | |
295 | + int n1サンプルのバイト数 = 2 * wasapiInfo.chans; // default; | |
296 | + switch (wasapiInfo.format) // BASS WASAPI で扱うサンプルはすべて 32bit float で固定されているが、デバイスはそうとは限らない。 | |
297 | + { | |
298 | + case BASSWASAPIFormat.BASS_WASAPI_FORMAT_8BIT: n1サンプルのバイト数 = 1 * wasapiInfo.chans; break; | |
299 | + case BASSWASAPIFormat.BASS_WASAPI_FORMAT_16BIT: n1サンプルのバイト数 = 2 * wasapiInfo.chans; break; | |
300 | + case BASSWASAPIFormat.BASS_WASAPI_FORMAT_24BIT: n1サンプルのバイト数 = 3 * wasapiInfo.chans; break; | |
301 | + case BASSWASAPIFormat.BASS_WASAPI_FORMAT_32BIT: n1サンプルのバイト数 = 4 * wasapiInfo.chans; break; | |
302 | + case BASSWASAPIFormat.BASS_WASAPI_FORMAT_FLOAT: n1サンプルのバイト数 = 4 * wasapiInfo.chans; break; | |
303 | + } | |
304 | + int n1秒のバイト数 = n1サンプルのバイト数 * wasapiInfo.freq; | |
305 | + this.n実バッファサイズms = (long)(wasapiInfo.buflen * 1000.0f / n1秒のバイト数); | |
306 | + Trace.TraceInformation("使用デバイス: #" + nDevNo + " : " + deviceInfo.name + ", flags=" + deviceInfo.flags); | |
307 | + Trace.TraceInformation("BASS を初期化しました。(WASAPI共有モード, {0}Hz, {1}ch, フォーマット:{2}, バッファ{3}bytes [{4}ms(希望{5}ms)], 更新間隔{6}ms, イベント動作={7})", | |
308 | + wasapiInfo.freq, | |
309 | + wasapiInfo.chans, | |
310 | + wasapiInfo.format.ToString(), | |
311 | + wasapiInfo.buflen, | |
312 | + n実バッファサイズms.ToString(), | |
313 | + n希望バッファサイズms.ToString(), | |
314 | + n更新間隔ms.ToString(), | |
315 | + wasapiInfo.IsEventDriven.ToString()); | |
293 | 316 | this.bIsBASSFree = false; |
294 | 317 | //----------------- |
295 | 318 | #endregion |
296 | 319 | } |
297 | 320 | } |
298 | - #region [ #31737 WASAPI排他モードのみ利用可能とし、WASAPI共有モードは使用できないようにするために、WASAPI共有モードでの初期化フローを削除する。 ] | |
321 | + //#region [ #31737 WASAPI排他モードのみ利用可能とし、WASAPI共有モードは使用できないようにするために、WASAPI共有モードでの初期化フローを削除する。 ] | |
299 | 322 | else if (mode == Eデバイスモード.排他) |
300 | 323 | { |
301 | - Trace.TraceInformation("Failed to initialize setting BASS (WASAPI) mode [{0}]", Bass.BASS_ErrorGetCode().ToString()); | |
324 | + Trace.TraceInformation("Failed to initialize setting BASS (WASAPI Exclusive) mode [{0}]", Bass.BASS_ErrorGetCode().ToString()); | |
302 | 325 | #region [ 排他モードに失敗したのなら共有モードでリトライ。] |
303 | 326 | //----------------- |
304 | 327 | mode = Eデバイスモード.共有; |
@@ -306,7 +329,7 @@ namespace FDK | ||
306 | 329 | //----------------- |
307 | 330 | #endregion |
308 | 331 | } |
309 | - #endregion | |
332 | + //#endregion | |
310 | 333 | else |
311 | 334 | { |
312 | 335 | #region [ それでも失敗したら例外発生。] |
@@ -314,7 +337,7 @@ namespace FDK | ||
314 | 337 | BASSError errcode = Bass.BASS_ErrorGetCode(); |
315 | 338 | Bass.BASS_Free(); |
316 | 339 | this.bIsBASSFree = true; |
317 | - throw new Exception( string.Format( "BASS (WASAPI) の初期化に失敗しました。(BASS_WASAPI_Init)[{0}]", errcode ) ); | |
340 | + throw new Exception( string.Format( "BASS (WASAPI Exclusive, Shared) の初期化に失敗しました。(BASS_WASAPI_Init)[{0}]", errcode ) ); | |
318 | 341 | //----------------- |
319 | 342 | #endregion |
320 | 343 | } |