SDXFrameWork  0.13
SDXFrameWork
 All Classes Namespaces Functions Variables Enumerations Enumerator Pages
Music.h
1 //Copyright © 2014 SDXFramework
2 //[License]GNU Affero General Public License, version 3
3 //[Contact]http://sourceforge.jp/projects/dxframework/
4 #pragma once
5 #include <Multimedia/SDX.h>
6 #include <Multimedia/Sound.h>
7 #include <chrono>
8 #include <string>
9 
10 namespace SDX
11 {
15  class Music
16  {
17  friend class System;
18  private:
19  static Music *active;
20  static Music *next;
21  static bool nextLoop;
22  static bool nextRestart;
23  static int mainVolume;
24 
25  Mix_Music* handle = nullptr;
26  std::string fileName;
27  int volume;
28 
29  int fadeInTime = 0;
30  int fadeOutTime = 0;
31 
32  std::chrono::system_clock::time_point startTime;//再生開始時刻
33  double restartPosition = 0;
34 
37  static void Finished()
38  {
39  //ここでは再生処理等をしてはいけない
40  //途中で終了した場合
41  auto diff = std::chrono::system_clock::now() - active->startTime;
42  active->restartPosition += (double)std::chrono::duration_cast<std::chrono::milliseconds>(diff).count() / 1000;
43  active = nullptr;
44  }
45 
46  public:
47  Music(){};
48 
49  ~Music(){}
50 
52  Music(const char *ファイル名, double 音量 = 1.0)
53  {
54  Music::Load(ファイル名, 音量);
55  }
56 
59  bool Load(const char *ファイル名, double 音量 = 1.0)
60  {
61  if (Loading::isLoading)
62  {
63  Loading::AddLoading([=]{ Load(ファイル名, 音量); });
64  return true;
65  }
66 
67  if (handle != nullptr){ return false; }
68 
69  fileName = ファイル名;
70  handle = Mix_LoadMUS(ファイル名);
71  volume = int(音量 * MIX_MAX_VOLUME);
72 
73  return true;
74  }
75 
77  bool Destroy()
78  {
79  if (handle == nullptr){ return false; }
80 
81  Mix_FreeMusic(handle);
82  return true;
83  }
84 
87  bool Play( bool ループ再生フラグ = true )
88  {
89  next = nullptr;
90  if (handle == nullptr){ return false; }
91 
92  //現在再生中のBGMにfadeOutTimeが設定されている場合
93  if (active && active->fadeOutTime > 0)
94  {
95  next = this;
96  nextLoop = ループ再生フラグ;
97  nextRestart = false;
98  Stop();
99  return true;
100  }
101 
102  int isLoop = ( 1 - ループ再生フラグ * 2);
103 
104  if (fadeInTime <= 0)
105  {
106  Mix_PlayMusic(handle, isLoop );
107  }
108  else
109  {
110  Mix_FadeInMusic(handle, isLoop , fadeInTime);
111  }
112 
113  startTime = std::chrono::system_clock::now();
114  Mix_VolumeMusic(volume * mainVolume / MIX_MAX_VOLUME);
115  active = this;
116 
117  return true;
118  }
119 
122  bool Restart(bool ループ再生フラグ = true)
123  {
124  next = nullptr;
125  if (handle == nullptr){ return false; }
126 
127  //現在再生中のBGMにfadeOutTimeが設定されている場合
128  if (active && active->fadeOutTime > 0)
129  {
130  next = this;
131  nextLoop = ループ再生フラグ;
132  nextRestart = true;
133  Stop();
134  return true;
135  }
136  else if ( active )
137  {
138  //止めてから再生する
139  Stop();
140  }
141 
142  int isLoop = ( 1 - ループ再生フラグ * 2);
143 
144  if (fadeInTime <= 0)
145  {
146  Mix_PlayMusic(handle, isLoop);
147  if (restartPosition > 0)
148  {
149  Mix_SetMusicPosition(restartPosition);
150  }
151  }
152  else
153  {
154  Mix_FadeInMusicPos(handle, isLoop, fadeInTime, restartPosition);
155  }
156 
157  startTime = std::chrono::system_clock::now();
158  Mix_VolumeMusic(volume * mainVolume / MIX_MAX_VOLUME);
159  active = this;
160 
161  return true;
162  }
163 
165  void SetVolume(double 音量)
166  {
167  volume = int(音量 * 255);
168  }
169 
172  void SetFadeInTime(int フェードイン時間)
173  {
174  fadeInTime = std::max(0,フェードイン時間);
175  }
176 
179  void SetFadeOutTime(int フェードアウト時間)
180  {
181  fadeOutTime = std::max(0,フェードアウト時間);
182  }
183 
186  static bool Check()
187  {
188  //何故かこの関数だけ成功時は1
189  return (Mix_PlayingMusic() == 1);
190  }
191 
194  static bool Stop()
195  {
196  if (!Check()){ return false; }
197 
198  if (active->fadeOutTime <= 0)
199  {
200  Mix_HaltMusic();
201  }
202  else
203  {
204  Mix_FadeOutMusic( active->fadeOutTime );
205  }
206 
207  return true;
208  }
209 
212  static void ChangeVolume(double 音量)
213  {
214  Mix_VolumeMusic(int(音量 * mainVolume));
215  }
216 
219  static void SetMainVolume(double 音量)
220  {
221  //元音量を変更
222  mainVolume = int(音量 * MIX_MAX_VOLUME);
223 
224  //再生中なら現在の音量も変化
225  if (Check())
226  {
227  Mix_VolumeMusic(mainVolume * active->volume / MIX_MAX_VOLUME);
228  }
229  }
230 
233  static bool Update()
234  {
235  if (!active && next)
236  {
237  if (nextRestart)
238  {
239  return next->Restart(nextLoop);
240  }
241  else
242  {
243  return next->Play(nextLoop);
244  }
245  }
246  return false;
247  }
248 
249  };
250 }
void SetFadeInTime(int フェードイン時間)
再生時のフェードイン時間を設定[ミリ秒].
Definition: Music.h:172
void SetFadeOutTime(int フェードアウト時間)
停止時のフェードアウト時間を設定[ミリ秒].
Definition: Music.h:179
bool Destroy()
音声ファイルを解放.
Definition: Music.h:77
static void SetMainVolume(double 音量)
全体の音量を0~1.0の範囲で設定.
Definition: Music.h:219
ライブラリの初期化やシステム的な処理を行う関数群.
Definition: System.h:23
bool Play(bool ループ再生フラグ=true)
音声ファイルを先頭から再生.
Definition: Music.h:87
static bool Stop()
再生中のMusicを停止.
Definition: Music.h:194
bool Load(const char *ファイル名, double 音量=1.0)
音声ファイルを登録.
Definition: Music.h:59
static void AddLoading(std::function< void(void)> &&読み込み関数)
非同期読み込み処理に追加.
Definition: Loading.h:96
BGM用音声を表すクラス.
Definition: Music.h:15
static bool Update()
fadeOut付きで終了した後に次Musicを再生するための処理.
Definition: Music.h:233
static void ChangeVolume(double 音量)
再生中の音量を変更.
Definition: Music.h:212
bool Restart(bool ループ再生フラグ=true)
前回停止した位置から再生.
Definition: Music.h:122
void SetVolume(double 音量)
0~1.0で音量を設定.
Definition: Music.h:165
static bool Check()
再生中か確認.
Definition: Music.h:186
Music(const char *ファイル名, double 音量=1.0)
音声ファイルを登録.
Definition: Music.h:52