1. Reputeless

    Posted

    Reputeless
Changes in title
+Siv3D で音楽プレイヤーを作る
Changes in tags
+Siv3D
December 2013
Changes in body
Source | HTML | Preview
@@ -0,0 +1,358 @@
+# 概要
+Siv3D Advent Calendar 2013, 6 日目の記事 <a href="http://siv3d.hateblo.jp/entry/adventcalendar2013/6" target="_blank">「Siv3D で音楽プレイヤーを作る」</a> のプログラムの解説です。
+
+完成形はこれです。Open でダイアログから音楽ファイルを選び、Play で再生、Pause で一時停止、シークバーを動かして再生位置を変更します。
+![https://lh6.googleusercontent.com/-XlHTmqAlzc8/UqFrI9zheSI/AAAAAAAACzM/cX_npwDSX58/s800/soundplayer.gif](https://lh6.googleusercontent.com/-XlHTmqAlzc8/UqFrI9zheSI/AAAAAAAACzM/cX_npwDSX58/s800/soundplayer.gif)
+
+# 実装 [1/4]
+SoundPlayer クラスを作ります。
+GUI をデフォルトの GUISkin で初期化します。
+
+```cpp
+# include <Siv3D.hpp>
+
+class SoundPlayer
+{
+private:
+
+ GUI m_gui;
+
+public:
+
+ SoundPlayer()
+ : m_gui{ GUISkin::Default() }
+ {
+
+ }
+
+ void update()
+ {
+
+ }
+};
+
+void Main()
+{
+ SoundPlayer soundPlayer;
+
+ while (System::Update())
+ {
+ soundPlayer.update();
+ }
+}
+```
+
+# 実装 [2/4]
+GUI に以下のアイテムを追加します。
+
+* Play ボタン
+* Pause ボタン
+* Open ボタン
+* 改行
+* [0.0, 1.0] を調節する幅 500px のスライダー
+
+そのあと、GUI を画面下の中央に移動させます。
+
+```cpp
+# include <Siv3D.hpp>
+
+class SoundPlayer
+{
+private:
+
+ GUI m_gui;
+
+public:
+
+ SoundPlayer()
+ : m_gui{ GUISkin::Default() }
+ {
+ m_gui.addButton(L"PlayButton", { L"Play" });
+
+ m_gui.addButton(L"PauseButton", { L"Pause" });
+
+ m_gui.addButton(L"OpenButton", { L"Open" });
+
+ m_gui.addNewLine();
+
+ m_gui.addSlider(L"Slider", { 0.0, 1.0, 0.0, 500 });
+
+ m_gui.setPos((Window::Width() - m_gui.rect.w) / 2, 380);
+ }
+
+ void update()
+ {
+
+ }
+};
+
+void Main()
+{
+ SoundPlayer soundPlayer;
+
+ while (System::Update())
+ {
+ soundPlayer.update();
+ }
+}
+```
+
+# 実装 [3/4]
+GUI::button(name).pushed で、指定したボタンが押されたかを取得できます。
+それぞれのボタンを押したときの処理を加えます。
+
+```cpp
+# include <Siv3D.hpp>
+
+class SoundPlayer
+{
+private:
+
+ GUI m_gui;
+
+ Sound m_sound;
+
+public:
+
+ SoundPlayer()
+ : m_gui{ GUISkin::Default() }
+ {
+ m_gui.addButton(L"PlayButton", { L"Play" });
+
+ m_gui.addButton(L"PauseButton", { L"Pause" });
+
+ m_gui.addButton(L"OpenButton", { L"Open" });
+
+ m_gui.addNewLine();
+
+ m_gui.addSlider(L"Slider", { 0.0, 1.0, 0.0, 500 });
+
+ m_gui.setPos((Window::Width() - m_gui.rect.w) / 2, 380);
+ }
+
+ void update()
+ {
+ if (m_gui.button(L"PlayButton").pushed)
+ {
+ m_sound.play();
+ }
+ else if (m_gui.button(L"PauseButton").pushed)
+ {
+ m_sound.pause();
+ }
+ else if (m_gui.button(L"OpenButton").pushed)
+ {
+ m_sound.pause();
+
+ m_sound = Dialog::OpenSound();
+ }
+ }
+};
+
+void Main()
+{
+ SoundPlayer soundPlayer;
+
+ while (System::Update())
+ {
+ soundPlayer.update();
+ }
+}
+```
+
+# 実装 [4/4]
+GUI::button(name).setEnabled(enabled)で、指定したボタンを非アクティブにできます。
+サウンドがロードされていないか再生中である時には Play ボタンを非アクティブに、
+サウンドが再生されていないときは Pause ボタンを非アクティブにします。
+
+スライダーがユーザによって操作されたとき GUI::slider(name).hasChanged が true を返します。
+スライダーの位置に応じてサウンドの再生位置を変更します。
+
+また、サウンドの再生位置に応じてスライダーを GUI::slider(name).setValue() で動かします。
+
+```cpp
+# include <Siv3D.hpp>
+
+class SoundPlayer
+{
+private:
+
+ GUI m_gui;
+
+ Sound m_sound;
+
+public:
+
+ SoundPlayer()
+ : m_gui{ GUISkin::Default() }
+ {
+ m_gui.addButton(L"PlayButton", { L"Play" });
+
+ m_gui.addButton(L"PauseButton", { L"Pause" });
+
+ m_gui.addButton(L"OpenButton", { L"Open" });
+
+ m_gui.addNewLine();
+
+ m_gui.addSlider(L"Slider", { 0.0, 1.0, 0.0, 500 });
+
+ m_gui.setPos((Window::Width() - m_gui.rect.w) / 2, 380);
+ }
+
+ void update()
+ {
+ m_gui.button(L"PlayButton").setEnabled(m_sound && !m_sound.isPlaying);
+
+ m_gui.button(L"PauseButton").setEnabled(m_sound.isPlaying);
+
+ if (m_gui.button(L"PlayButton").pushed)
+ {
+ m_sound.play();
+ }
+ else if (m_gui.button(L"PauseButton").pushed)
+ {
+ m_sound.pause();
+ }
+ else if (m_gui.button(L"OpenButton").pushed)
+ {
+ m_sound.pause();
+
+ m_sound = Dialog::OpenSound();
+ }
+
+ if (m_gui.slider(L"Slider").hasChanged)
+ {
+ m_sound.setPosSec(m_sound.lengthSec*m_gui.slider(L"Slider").value);
+ }
+
+ m_gui.slider(L"Slider").setValue(m_sound.posSec / m_sound.lengthSec);
+ }
+};
+
+void Main()
+{
+ SoundPlayer soundPlayer;
+
+ while (System::Update())
+ {
+ soundPlayer.update();
+ }
+}
+```
+
+# 完成
+Play Siv3D! の <a href="http://play-siv3d.hateblo.jp/entry/example/audiospectrum" target="_blank">サンプル | オーディオスペクトラム</a> を参考に簡単なオーディオビジュアライザを加えました。これで完成です!
+
+このソースコードはパブリックドメインです。
+
+```cpp
+// Siv3D December 2013
+# include <Siv3D.hpp>
+
+class SoundPlayer
+{
+private:
+
+ GUI m_gui;
+
+ Sound m_sound;
+
+public:
+
+ SoundPlayer()
+ : m_gui{ GUISkin::Default() }
+ {
+ m_gui.addButton(L"PlayButton", { L"Play" });
+
+ m_gui.addButton(L"PauseButton", { L"Pause" });
+
+ m_gui.addButton(L"OpenButton", { L"Open" });
+
+ m_gui.addNewLine();
+
+ m_gui.addSlider(L"Slider", { 0.0, 1.0, 0.0, 500 });
+
+ m_gui.setPos((Window::Width() - m_gui.rect.w) / 2, 380);
+ }
+
+ void update()
+ {
+ m_gui.button(L"PlayButton").setEnabled(m_sound && !m_sound.isPlaying);
+
+ m_gui.button(L"PauseButton").setEnabled(m_sound.isPlaying);
+
+ if (m_gui.button(L"PlayButton").pushed)
+ {
+ m_sound.play();
+ }
+ else if (m_gui.button(L"PauseButton").pushed)
+ {
+ m_sound.pause();
+ }
+ else if (m_gui.button(L"OpenButton").pushed)
+ {
+ m_sound.pause();
+
+ m_sound = Dialog::OpenSound();
+ }
+
+ if (m_gui.slider(L"Slider").hasChanged)
+ {
+ m_sound.setPosSec(m_sound.lengthSec*m_gui.slider(L"Slider").value);
+ }
+
+ m_gui.slider(L"Slider").setValue(m_sound.posSec / m_sound.lengthSec);
+ }
+
+ void drawVisualizer() const
+ {
+ Waving::FFT(m_sound);
+
+ const float* p = Waving::FFTBuffer();
+
+ for (int i = 0; i < 640; ++i)
+ {
+ const double size = Pow(p[i], 0.6f) * 500;
+
+ RectF(i, 200 + size, 1, -size * 2).draw(HSV(240 - i));
+ }
+ }
+};
+
+void Main()
+{
+ SoundPlayer soundPlayer;
+
+ while (System::Update())
+ {
+ soundPlayer.update();
+
+ soundPlayer.drawVisualizer();
+ }
+}
+```
+
+# 拡張
+このプログラムを拡張するヒントです。
+
+## オーディオビジュアライザー
+オリジナルのエフェクトのオーディオビジュアライザーを作ってみましょう
+## ループ再生
+GUI の ToggleSwitch と Sound::setLoop(loop) を使ってループの有無を切り替えます
+## サウンドの情報
+Dialog::GetOpenSound() でファイルパスを取得したあとに Audio::GetProperty(path) で音楽ファイルのメタデータ(タイトル、ビットレート等)を取得できます
+## 再生時間の表示
+Play Siv3D! の「サウンドの再生」チュートリアルが参考になります
+
+# Siv3D について
+Siv3D は CG や音楽、様々な入力デバイスを扱うプログラミングを、楽しく簡単にする C++ ライブラリです。2008 年 から開発を始め、現在 2D グラフィックス機能が中心のアルファ版を公開しています。
+
+Siv3D 公式ページ https://sites.google.com/site/siv3dgameengine/
+
+
+
+
+
+
+
+