2 using System.Collections.Generic;
\r
4 using System.Diagnostics;
\r
5 using System.Threading;
\r
7 //using Un4seen.BassAsio;
\r
8 //using Un4seen.BassWasapi;
\r
9 //using Un4seen.Bass.AddOn.Mix;
\r
10 using Un4seen.Bass.AddOn.Fx;
\r
14 public class CBeatDetect : IDisposable
\r
16 public struct stBeatPos
\r
18 public float fBeatTime;
\r
21 public int n小節内Grid;
\r
22 public bool b無効; //
\r
23 public bool bレーン表示する; // 未使用
\r
25 public stBeatPos( float _fBeatTime, int _n小節番号, int _nGrid, int _n小節内Grid, bool _b無効, bool _bレーン表示する )
\r
27 fBeatTime = _fBeatTime;
\r
30 n小節内Grid = _n小節内Grid;
\r
32 bレーン表示する= _bレーン表示する;
\r
37 public CBeatDetect()
\r
41 public CBeatDetect( string _filename )
\r
43 this.filename = _filename;
\r
47 #region [ 初期化(コンストラクタから呼び出される) ]
\r
48 private void Initialize()
\r
50 if ( this.listBeatPositions == null )
\r
52 this.listBeatPositions = new List<stBeatPos>();
\r
55 #region [ BASS registration ]
\r
56 // BASS.NET ユーザ登録(BASSスプラッシュが非表示になる)。
\r
58 BassNet.Registration( "dtx2013@gmail.com", "2X9181017152222" );
\r
60 #region [ BASS Version Check ]
\r
62 int nBASSVersion = Utils.HighWord( Bass.BASS_GetVersion() );
\r
63 if ( nBASSVersion != Bass.BASSVERSION )
\r
64 throw new DllNotFoundException( string.Format( "bass.dll のバージョンが異なります({0})。このプログラムはバージョン{1}で動作します。", nBASSVersion, Bass.BASSVERSION ) );
\r
66 int nBASSFXVersion = Utils.HighWord( BassFx.BASS_FX_GetVersion() );
\r
67 if ( nBASSFXVersion != BassFx.BASSFXVERSION )
\r
68 throw new DllNotFoundException( string.Format( "bass_fx.dll のバージョンが異なります({0})。このプログラムはバージョン{1}で動作します。", nBASSFXVersion, BassFx.BASSFXVERSION ) );
\r
71 #region [ BASS の設定。]
\r
72 //this.bIsBASSFree = true;
\r
73 //Debug.Assert( Bass.BASS_SetConfig( BASSConfig.BASS_CONFIG_UPDATEPERIOD, 0 ), // 0:BASSストリームの自動更新を行わない。(サウンド出力しないため)
\r
74 // string.Format( "BASS_SetConfig() に失敗しました。[{0}", Bass.BASS_ErrorGetCode() ) );
\r
76 #region [ BASS の初期化。]
\r
77 int nデバイス = 0; // 0:"no sound" … BASS からはデバイスへアクセスさせない。
\r
78 int n周波数 = 44100; // 仮決め。lデバイス(≠ドライバ)がネイティブに対応している周波数であれば何でもいい?ようだ。いずれにしろBASSMXで自動的にリサンプリングされる。
\r
79 if ( !Bass.BASS_Init( nデバイス, n周波数, BASSInit.BASS_DEVICE_DEFAULT, IntPtr.Zero ) )
\r
80 throw new Exception( string.Format( "BASS の初期化に失敗しました。(BASS_Init)[{0}]", Bass.BASS_ErrorGetCode().ToString() ) );
\r
83 #region [ 指定されたサウンドファイルをBASSでオープンし、必要最小限の情報を取得する。]
\r
84 //this.hBassStream = Bass.BASS_StreamCreateFile( this.filename, 0, 0, BASSFlag.BASS_STREAM_PRESCAN | BASSFlag.BASS_STREAM_DECODE );
\r
85 this.hBassStream = Bass.BASS_StreamCreateFile( this.filename, 0, 0, BASSFlag.BASS_STREAM_DECODE );
\r
86 if ( this.hBassStream == 0 )
\r
87 throw new Exception( string.Format( "{0}: サウンドストリームの生成に失敗しました。(BASS_StreamCreateFile)[{1}]", filename, Bass.BASS_ErrorGetCode().ToString() ) );
\r
89 this.nTotalBytes = Bass.BASS_ChannelGetLength( this.hBassStream );
\r
91 this.nTotalSeconds = Bass.BASS_ChannelBytes2Seconds( this.hBassStream, nTotalBytes );
\r
92 if ( !Bass.BASS_ChannelGetAttribute( this.hBassStream, BASSAttribute.BASS_ATTRIB_FREQ, ref fFreq ) )
\r
94 string errmes = string.Format( "サウンドストリームの周波数取得に失敗しました。(BASS_ChannelGetAttribute)[{0}]", Bass.BASS_ErrorGetCode().ToString() );
\r
96 throw new Exception( errmes );
\r
105 /// <returns>テンポ値</returns>
\r
106 /// <remarks>テンポ値の範囲は70-300</remarks>
\r
107 public float GetTempo()
\r
109 fTempo = BassFx.BASS_FX_BPM_DecodeGet(
\r
113 ( 300 << 16 ) + 70, // MAX BPM=320, MIN BPM=70
\r
115 BASSFXBpm.BASS_FX_BPM_DEFAULT, //BASSFXBpm.BASS_FX_BPM_MULT2,
\r
123 /// <param name="startSec">開始位置</param>
\r
124 /// <param name="endSec">終了位置</param>
\r
125 /// <returns>テンポ値</returns>
\r
126 /// <remarks>テンポ値の範囲は70-300</remarks>
\r
127 public float GetTempo( double startSec, double endSec )
\r
129 fTempo = BassFx.BASS_FX_BPM_DecodeGet(
\r
133 ( 300 << 16 ) + 70, // MAX BPM=320, MIN BPM=70
\r
135 BASSFXBpm.BASS_FX_BPM_DEFAULT, //BASSFXBpm.BASS_FX_BPM_MULT2,
\r
143 /// Beatの検出位置をListで返す
\r
145 /// <returns>Beat検出位置群</returns>
\r
146 public List<stBeatPos> GetBeatPositions()
\r
148 #region [ BeatPosition格納リストの初期化 ]
\r
149 if ( this.listBeatPositions != null )
\r
151 this.listBeatPositions.Clear();
\r
155 this.listBeatPositions = new List<stBeatPos>();
\r
159 BPMBEATPROC _beatProc = new BPMBEATPROC( GetBeat_ProgressCallback );
\r
161 bool ret = BassFx.BASS_FX_BPM_BeatDecodeGet(
\r
166 BASSFXBpm.BASS_FX_BPM_DEFAULT, //BASSFXBpm.BASS_FX_BPM_MULT2,
\r
170 return this.listBeatPositions;
\r
173 private void GetBeat_ProgressCallback( int channel, double beatpos, IntPtr user )
\r
175 stBeatPos sbp = new stBeatPos(
\r
185 listBeatPositions.Add( sbp );
\r
186 // Debug.WriteLine( "Beat at: " + beatpos.ToString() );
\r
192 public void Dispose() // 使い終わったら必ずDispose()すること。BASSのリソースを握りっぱなしにすると、他の再生に不都合が生じるため。
\r
194 BassFx.BASS_FX_BPM_Free( this.hBassStream );
\r
195 Bass.BASS_StreamFree( this.hBassStream );
\r
196 this.hBassStream = -1;
\r
201 private string filename = "";
\r
202 private int hBassStream = -1;
\r
203 private long nTotalBytes = 0;
\r
204 private double nTotalSeconds = 0.0f;
\r
205 private float fFreq = 0.0f;
\r
206 private float fTempo;
\r
207 private List<stBeatPos> listBeatPositions = null;
\r