1. Reputeless
Changes in body
Source | HTML | Preview
@@ -1,358 +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;
+ const double size = Pow(p[i], 0.6) * 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/