From: yyagi Date: Wed, 22 Aug 2018 16:15:37 +0000 (+0900) Subject: #37271 サウンドのミキシングをマルチスレッド化するライブラリを使おうとしたが、うまく動かなかった実装を、注釈でなく#ifdefに入れ込んだ。後日じっくり対応し直す。 X-Git-Tag: Release113~7 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=2455bf1ad2c451bdbdc8711e028c8ea2aea2fde1;p=dtxmania%2Fdtxmania.git #37271 サウンドのミキシングをマルチスレッド化するライブラリを使おうとしたが、うまく動かなかった実装を、注釈でなく#ifdefに入れ込んだ。後日じっくり対応し直す。 --- diff --git a/FDK/FDK.csproj b/FDK/FDK.csproj index 12d621dd..d228ac24 100644 --- a/FDK/FDK.csproj +++ b/FDK/FDK.csproj @@ -47,7 +47,7 @@ false 0219 - TRACE;DEBUG;TEST_CancelEnterCodeInAltEnter2 TEST_Direct3D9Ex_ TEST_MulthThreadedMixer_ + TRACE;DEBUG;TEST_CancelEnterCodeInAltEnter2 TEST_Direct3D9Ex_ TEST_MultiThreadedMixer_ false false diff --git a/FDK/コード/03.サウンド/CSound.cs b/FDK/コード/03.サウンド/CSound.cs index a1620f53..387cb02c 100644 --- a/FDK/コード/03.サウンド/CSound.cs +++ b/FDK/コード/03.サウンド/CSound.cs @@ -1769,7 +1769,7 @@ Debug.WriteLine("更に再生に失敗: " + Path.GetFileName(this.strファイ _hTempoStream = 0; if ( CSound管理.bIsTimeStretch ) // TimeStretchのON/OFFに関わりなく、テンポ変更のストリームを生成する。後からON/OFF切り替え可能とするため。 // ... と思ったが、1サウンド辺り1つのテンポ変更ストリームが存在することになり、 - // ミキシング負荷が非常に高くなるため、結局TimeStretch=ONの時のみ店舗変更ストリームを提供することにした。 + // ミキシング負荷が非常に高くなるため、結局TimeStretch=ONの時のみテンポ変更ストリームを提供することにした。 { this._hTempoStream = BassFx.BASS_FX_TempoCreate(this._hBassStream, BASSFlag.BASS_STREAM_DECODE | BASSFlag.BASS_FX_FREESOURCE); if (this._hTempoStream == 0) @@ -1852,9 +1852,12 @@ Debug.WriteLine("更に再生に失敗: " + Path.GetFileName(this.strファイ } public bool tBASSサウンドをミキサーから削除する( int channel ) { -//bool b = BASSThreadedMixerLibraryWrapper.BASS_ThreadedMixer_RemoveSource((IntPtr)this.hMixer, channel ); -//mixingChannel.Remove((IntPtr)this.hMixer); +#if TEST_MultiThreadedMixer + bool b = BASSThreadedMixerLibraryWrapper.BASS_ThreadedMixer_RemoveSource((IntPtr)this.hMixer, channel ); + mixingChannel.Remove((IntPtr)this.hMixer); +#else bool b = BassMix.BASS_Mixer_ChannelRemove(channel); +#endif if ( b ) { Interlocked.Decrement( ref CSound管理.nMixing ); @@ -1865,13 +1868,17 @@ Debug.WriteLine("更に再生に失敗: " + Path.GetFileName(this.strファイ // mixer への追加 - -//private List mixingChannel = new List(); +#if TEST_MultiThreadedMixer + private List mixingChannel = new List(); +#endif public bool tBASSサウンドをミキサーに追加する() { -//if (!mixingChannel.Contains((IntPtr)this.hMixer)) +#if TEST_MultiThreadedMixer + if (!mixingChannel.Contains((IntPtr)this.hMixer)) +#else if ( BassMix.BASS_Mixer_ChannelGetMixer( hBassStream ) == 0 ) +#endif { BASSFlag bf = BASSFlag.BASS_SPEAKER_FRONT | BASSFlag.BASS_MIXER_NORAMPIN | BASSFlag.BASS_MIXER_PAUSE; Interlocked.Increment( ref CSound管理.nMixing ); @@ -1879,9 +1886,12 @@ Debug.WriteLine("更に再生に失敗: " + Path.GetFileName(this.strファイ // preloadされることを期待して、敢えてflagからはBASS_MIXER_PAUSEを外してAddChannelした上で、すぐにPAUSEする // -> ChannelUpdateでprebufferできることが分かったため、BASS_MIXER_PAUSEを使用することにした -//bool b1 = BASSThreadedMixerLibraryWrapper.BASS_ThreadedMixer_AddSource( (IntPtr)this.hMixer, this.hBassStream, IntPtr.Zero ); -//mixingChannel.Add((IntPtr)this.hMixer); +#if TEST_MultiThreadedMixer + bool b1 = BASSThreadedMixerLibraryWrapper.BASS_ThreadedMixer_AddSource( (IntPtr)this.hMixer, this.hBassStream, IntPtr.Zero ); + mixingChannel.Add((IntPtr)this.hMixer); +#else bool b1 = BassMix.BASS_Mixer_StreamAddChannel(this.hMixer, this.hBassStream, bf); +#endif //bool b2 = BassMix.BASS_Mixer_ChannelPause( this.hBassStream ); t再生位置を先頭に戻す(); // StreamAddChannelの後で再生位置を戻さないとダメ。逆だと再生位置が変わらない。 //Trace.TraceInformation( "Add Mixer: " + Path.GetFileName( this.strファイル名 ) + " (" + hBassStream + ")" + " MixedStreams=" + CSound管理.nMixing ); @@ -1891,7 +1901,7 @@ Debug.WriteLine("更に再生に失敗: " + Path.GetFileName(this.strファイ return true; } - #region [ tオンメモリ方式でデコードする() ] +#region [ tオンメモリ方式でデコードする() ] public void tオンメモリ方式でデコードする( string strファイル名, out byte[] buffer, out int nPCMデータの先頭インデックス, out int totalPCMSize, out CWin32.WAVEFORMATEX wfx, bool bIntegrateWaveHeader ) @@ -2004,7 +2014,7 @@ Debug.WriteLine("更に再生に失敗: " + Path.GetFileName(this.strファイ sounddecoder = null; } } - #endregion - #endregion +#endregion +#endregion } } diff --git a/FDK/コード/03.サウンド/CSoundDeviceWASAPI.cs b/FDK/コード/03.サウンド/CSoundDeviceWASAPI.cs index 74028462..3d085613 100644 --- a/FDK/コード/03.サウンド/CSoundDeviceWASAPI.cs +++ b/FDK/コード/03.サウンド/CSoundDeviceWASAPI.cs @@ -435,10 +435,10 @@ Trace.TraceInformation("WASAPI Device #{0}: {1}: IsDefault={2}, defPeriod={3}s, //----------------- #endregion } - -//LoadLibraryに失敗する・・・ -//BASSThreadedMixerLibraryWrapper.InitBASSThreadedMixerLibrary(); - +#if TEST_MultiThreadedMixer + //LoadLibraryに失敗する・・・ + //BASSThreadedMixerLibraryWrapper.InitBASSThreadedMixerLibrary(); +#endif // WASAPI出力と同じフォーマットを持つ BASS ミキサーを作成。 @@ -448,18 +448,20 @@ Trace.TraceInformation("WASAPI Device #{0}: {1}: IsDefault={2}, defPeriod={3}s, // string.Format( "BASS_SetConfig(CONFIG_MIXER_BUFFER) に失敗しました。[{0}", Bass.BASS_ErrorGetCode() ) ); var info = BassWasapi.BASS_WASAPI_GetInfo(); -//this.hMixer = BASSThreadedMixerLibraryWrapper.BASS_ThreadedMixer_Create( -// info.freq, -// info.chans, -// (int)(BASSFlag.BASS_MIXER_NONSTOP | BASSFlag.BASS_SAMPLE_FLOAT | BASSFlag.BASS_STREAM_DECODE | BASSFlag.BASS_MIXER_POSEX), -// out hMixerThreaded -// ); - +#if TEST_MultiThreadedMixer + this.hMixer = BASSThreadedMixerLibraryWrapper.BASS_ThreadedMixer_Create( + info.freq, + info.chans, + (int)(BASSFlag.BASS_MIXER_NONSTOP | BASSFlag.BASS_SAMPLE_FLOAT | BASSFlag.BASS_STREAM_DECODE | BASSFlag.BASS_MIXER_POSEX), + out hMixerThreaded + ); +#else this.hMixer = BassMix.BASS_Mixer_StreamCreate( info.freq, info.chans, BASSFlag.BASS_MIXER_NONSTOP | BASSFlag.BASS_SAMPLE_FLOAT | BASSFlag.BASS_STREAM_DECODE | BASSFlag.BASS_MIXER_POSEX); // デコードのみ=発声しない。WASAPIに出力されるだけ。 - if ( this.hMixer == 0 ) +#endif + if (this.hMixer == 0 ) { BASSError errcode = Bass.BASS_ErrorGetCode(); BassWasapi.BASS_WASAPI_Free(); @@ -471,16 +473,19 @@ Trace.TraceInformation("WASAPI Device #{0}: {1}: IsDefault={2}, defPeriod={3}s, for (int i = 0; i <= (int)CSound.EInstType.Unknown; i++) { -//this.hMixer_Chips[i] = BASSThreadedMixerLibraryWrapper.BASS_ThreadedMixer_Create( -// info.freq, -// info.chans, -// (int)(BASSFlag.BASS_MIXER_NONSTOP | BASSFlag.BASS_SAMPLE_FLOAT | BASSFlag.BASS_STREAM_DECODE | BASSFlag.BASS_MIXER_POSEX), -// out this.hMixerThreaded_Chips[i] -//); // デコードのみ=発声しない。WASAPIに出力されるだけ。 +#if TEST_MultiThreadedMixer + this.hMixer_Chips[i] = BASSThreadedMixerLibraryWrapper.BASS_ThreadedMixer_Create( + info.freq, + info.chans, + (int)(BASSFlag.BASS_MIXER_NONSTOP | BASSFlag.BASS_SAMPLE_FLOAT | BASSFlag.BASS_STREAM_DECODE | BASSFlag.BASS_MIXER_POSEX), + out this.hMixerThreaded_Chips[i] + ); // デコードのみ=発声しない。WASAPIに出力されるだけ。 +#else this.hMixer_Chips[ i ] = BassMix.BASS_Mixer_StreamCreate( info.freq, info.chans, BASSFlag.BASS_MIXER_NONSTOP | BASSFlag.BASS_SAMPLE_FLOAT | BASSFlag.BASS_STREAM_DECODE | BASSFlag.BASS_MIXER_POSEX); // デコードのみ=発声しない。WASAPIに出力されるだけ。 +#endif if (this.hMixer_Chips[ i ] == 0) { BASSError errcode = Bass.BASS_ErrorGetCode(); @@ -494,8 +499,11 @@ Trace.TraceInformation("WASAPI Device #{0}: {1}: IsDefault={2}, defPeriod={3}s, Bass.BASS_ChannelSetAttribute(this.hMixer_Chips[i], BASSAttribute.BASS_ATTRIB_VOL, CSound管理.nMixerVolume[i] / 100.0f); //Trace.TraceInformation("Vol{0}: {1}", i, CSound管理.nMixerVolume[i]); -//bool b1 = BASSThreadedMixerLibraryWrapper.BASS_ThreadedMixer_AddSource(this.hMixerThreaded, this.hMixer_Chips[i], IntPtr.Zero); +#if TEST_MultiThreadedMixer + bool b1 = BASSThreadedMixerLibraryWrapper.BASS_ThreadedMixer_AddSource(this.hMixerThreaded, this.hMixer_Chips[i], IntPtr.Zero); +#else bool b1 = BassMix.BASS_Mixer_StreamAddChannel(this.hMixer, this.hMixer_Chips[i], BASSFlag.BASS_DEFAULT); +#endif if (!b1) { BASSError errcode = Bass.BASS_ErrorGetCode(); @@ -596,20 +604,20 @@ Trace.TraceInformation("WASAPI Device #{0}: {1}: IsDefault={2}, defPeriod={3}s, BassWasapi.BASS_WASAPI_Start(); } - #region [録音開始] +#region [録音開始] public bool tStartRecording() { return encoder.Pause(false); } - #endregion - #region [録音終了] +#endregion +#region [録音終了] public bool tStopRecording() { return encoder.Stop(true); } - #endregion +#endregion - #region [ tサウンドを作成する() ] +#region [ tサウンドを作成する() ] public CSound tサウンドを作成する(string strファイル名) { return tサウンドを作成する( strファイル名, CSound.EInstType.Unknown ); @@ -617,8 +625,11 @@ Trace.TraceInformation("WASAPI Device #{0}: {1}: IsDefault={2}, defPeriod={3}s, public CSound tサウンドを作成する( string strファイル名, CSound.EInstType eInstType ) { var sound = new CSound(); -//int hmixer = (int)hMixerThreaded_Chips[ (int)eInstType ]; +#if TEST_MultiThreadedMixer + int hmixer = (int)hMixerThreaded_Chips[ (int)eInstType ]; +#else int hmixer = hMixer_Chips[(int)eInstType]; +#endif sound.tWASAPIサウンドを作成する( strファイル名, hmixer, this.e出力デバイス, eInstType ); return sound; } @@ -629,26 +640,35 @@ Trace.TraceInformation("WASAPI Device #{0}: {1}: IsDefault={2}, defPeriod={3}s, public CSound tサウンドを作成する( byte[] byArrWAVファイルイメージ, CSound.EInstType eInstType ) { var sound = new CSound(); -//int hmixer = (int)hMixerThreaded_Chips[(int)eInstType]; +#if TEST_MultiThreadedMixer + int hmixer = (int)hMixerThreaded_Chips[(int)eInstType]; +#else int hmixer = hMixer_Chips[(int)eInstType]; +#endif sound.tWASAPIサウンドを作成する( byArrWAVファイルイメージ, hmixer, this.e出力デバイス, eInstType ); return sound; } public void tサウンドを作成する( string strファイル名, ref CSound sound, CSound.EInstType eInstType ) { -//int hmixer = (int)hMixerThreaded_Chips[(int)eInstType]; +#if TEST_MultiThreadedMixer + int hmixer = (int)hMixerThreaded_Chips[(int)eInstType]; +#else int hmixer = hMixer_Chips[(int)eInstType]; +#endif sound.tWASAPIサウンドを作成する( strファイル名, hmixer, this.e出力デバイス, eInstType ); } public void tサウンドを作成する( byte[] byArrWAVファイルイメージ, ref CSound sound, CSound.EInstType eInstType) { -//int hmixer = (int)hMixerThreaded_Chips[(int)eInstType]; +#if TEST_MultiThreadedMixer + int hmixer = (int)hMixerThreaded_Chips[(int)eInstType]; +#else int hmixer = hMixer_Chips[(int)eInstType]; +#endif sound.tWASAPIサウンドを作成する( byArrWAVファイルイメージ, hmixer, this.e出力デバイス, eInstType ); } - #endregion +#endregion - #region [ Dispose-Finallizeパターン実装 ] +#region [ Dispose-Finallizeパターン実装 ] //----------------- public void Dispose() { @@ -697,7 +717,9 @@ Trace.TraceInformation("WASAPI Device #{0}: {1}: IsDefault={2}, defPeriod={3}s, } } } -//BASSThreadedMixerLibraryWrapper.FreeBASSThreadedMixerLibrary(); +#if TEST_MultiThreadedMixer + //BASSThreadedMixerLibraryWrapper.FreeBASSThreadedMixerLibrary(); +#endif if ( !this.bIsBASSFree ) { @@ -715,16 +737,17 @@ Trace.TraceInformation("WASAPI Device #{0}: {1}: IsDefault={2}, defPeriod={3}s, this.Dispose( false ); } //----------------- - #endregion +#endregion protected int hMixer = 0; protected int hMixer_DeviceOut = 0; protected int hMixer_Record = 0; protected int[] hMixer_Chips = new int[(int)CSound.EInstType.Unknown + 1]; //DTX2WAV対応 BGM, SE, Drums...を別々のmixerに入れて、個別に音量変更できるようにする -//protected IntPtr hMixerThreaded = IntPtr.Zero; -//protected IntPtr[] hMixerThreaded_Chips = new IntPtr[(int)CSound.EInstType.Unknown + 1]; - +#if TEST_MultiThreadedMixer + protected IntPtr hMixerThreaded = IntPtr.Zero; + protected IntPtr[] hMixerThreaded_Chips = new IntPtr[(int)CSound.EInstType.Unknown + 1]; +#endif protected BaseEncoder encoder; protected int stream; protected WASAPIPROC tWasapiProc = null;