LoginSignup
5
6

More than 5 years have passed since last update.

Siv3D で音楽プレイヤーを作る

Last updated at Posted at 2013-12-06

概要

完成形はこれです。Open でダイアログから音楽ファイルを選び、Play で再生、Pause で一時停止、シークバーを動かして再生位置を変更します。
https://lh6.googleusercontent.com/-cqhFHZ5kNx0/VHkWYj5aNsI/AAAAAAAADiI/SSH4EIZYhbo/s800/soundplayer.gif

実装 [1/4]

SoundPlayer クラスを作ります。
GUI をデフォルトの GUIStyle で初期化します。

# include <Siv3D.hpp>

class SoundPlayer
{
private:

    GUI m_gui;

public:

    SoundPlayer()
        : m_gui(GUIStyle::Default)
    {

    }

    void update()
    {

    }
};

void Main()
{
    SoundPlayer soundPlayer;

    while (System::Update())
    {
        soundPlayer.update();
    }
}

実装 [2/4]

GUI に以下のアイテムを追加します。

  • Play ボタン
  • Pause ボタン
  • Open ボタン
  • [0.0, 1.0] を調節する幅 500px のスライダー

そのあと、GUI を画面下の中央に移動させます。

# include <Siv3D.hpp>

class SoundPlayer
{
private:

    GUI m_gui;

public:

    SoundPlayer()
        : m_gui(GUIStyle::Default)
    {
        m_gui.add(L"PlayButton", GUIButton::Create(L"Play"));

        m_gui.add(L"PauseButton", GUIButton::Create(L"Pause"));

        m_gui.addln(L"OpenButton", GUIButton::Create(L"Open"));

        m_gui.add(L"Slider", GUISlider::Create(0.0, 1.0, 0.0, 500));

        m_gui.setPos((Window::Width() - m_gui.getRect().w) / 2, 360);
    }

    void update()
    {

    }
};

void Main()
{
    SoundPlayer soundPlayer;

    while (System::Update())
    {
        soundPlayer.update();
    }
}

実装 [3/4]

GUI::button(name).pushed で、指定したボタンが押されたかを取得できます。
それぞれのボタンを押したときの処理を加えます。

# include <Siv3D.hpp>

class SoundPlayer
{
private:

    GUI m_gui;

    Sound m_sound;

public:

    SoundPlayer()
        : m_gui(GUIStyle::Default)
    {
        m_gui.add(L"PlayButton", GUIButton::Create(L"Play"));

        m_gui.add(L"PauseButton", GUIButton::Create(L"Pause"));

        m_gui.addln(L"OpenButton", GUIButton::Create(L"Open"));

        m_gui.add(L"Slider", GUISlider::Create(0.0, 1.0, 0.0, 500));

        m_gui.setPos((Window::Width() - m_gui.getRect().w) / 2, 360);
    }

    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).enabled プロパティを変更すると、ボタンのアクティブ / 非アクティブを切り替えられます。
サウンドがロードされていないか再生中である時には Play ボタンを非アクティブに、
サウンドが再生されていないときは Pause ボタンを非アクティブにします。

スライダーがユーザによって操作されたとき GUI::slider(name).hasChanged が true を返します。
スライダーの位置に応じてサウンドの再生位置を変更します。

また、サウンドの再生位置に応じてスライダーを GUI::slider(name).setValue() で動かします。

# include <Siv3D.hpp>

class SoundPlayer
{
private:

    GUI m_gui;

    Sound m_sound;

public:

    SoundPlayer()
        : m_gui(GUIStyle::Default)
    {
        m_gui.add(L"PlayButton", GUIButton::Create(L"Play"));

        m_gui.add(L"PauseButton", GUIButton::Create(L"Pause"));

        m_gui.addln(L"OpenButton", GUIButton::Create(L"Open"));

        m_gui.add(L"Slider", GUISlider::Create(0.0, 1.0, 0.0, 500));

        m_gui.setPos((Window::Width() - m_gui.getRect().w) / 2, 360);
    }

    void update()
    {
        m_gui.button(L"PlayButton").enabled = (m_sound && !m_sound.isPlaying());

        m_gui.button(L"PauseButton").enabled = 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.streamPosSec() / m_sound.lengthSec());
    }
};

void Main()
{
    SoundPlayer soundPlayer;

    while (System::Update())
    {
        soundPlayer.update();
    }
}

完成

リファレンスの サンプル | オーディオスペクトラム を参考に簡単なオーディオビジュアライザを加えました。これで完成です!

このソースコードはパブリックドメインです。

// Siv3D March 2016
# include <Siv3D.hpp>

class SoundPlayer
{
private:

    GUI m_gui;

    Sound m_sound;

public:

    SoundPlayer()
        : m_gui(GUIStyle::Default)
    {
        m_gui.add(L"PlayButton", GUIButton::Create(L"Play"));

        m_gui.add(L"PauseButton", GUIButton::Create(L"Pause"));

        m_gui.addln(L"OpenButton", GUIButton::Create(L"Open"));

        m_gui.add(L"Slider", GUISlider::Create(0.0, 1.0, 0.0, 500));

        m_gui.setPos((Window::Width() - m_gui.getRect().w) / 2, 360);
    }

    void update()
    {
        m_gui.button(L"PlayButton").enabled = (m_sound && !m_sound.isPlaying());

        m_gui.button(L"PauseButton").enabled = 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.streamPosSec() / m_sound.lengthSec());
    }

    void drawVisualizer() const
    {
        if (!m_sound.isPlaying())
        {
            return;
        }

        const auto fft = FFT::Analyze(m_sound);

        for (int i = 0; i < 640; ++i)
        {
            const double size = Pow(fft.buffer[i], 0.6f) * 500;

            RectF(i, 200 + size, 1, -size * 2).draw(HSV(240 - i));
        }
    }
};

void Main()
{
    Graphics::SetBackground(Color(70, 80, 170));

    SoundPlayer soundPlayer;

    while (System::Update())
    {
        soundPlayer.update();

        soundPlayer.drawVisualizer();
    }
}

拡張

このプログラムを拡張するヒントです。

オーディオビジュアライザー

オリジナルのエフェクトのオーディオビジュアライザーを作ってみましょう

ループ再生

GUIToggleSwitch と Sound::setLoop(loop) を使ってループの有無を切り替えます

サウンドの情報

Dialog::GetOpenSound() でファイルパスを取得したあとに Audio::GetProperty(path) で音楽ファイルのメタデータ(タイトル、ビットレート等)を取得できます

再生時間の表示

公式リファレンスの「サウンドの再生」チュートリアルが参考になります

Siv3D について

Siv3D は C++ で楽しく簡単にゲームやメディアアートを作れるライブラリです。Kinect や Leap Motion, カメラやマイクといった多くのデバイスに対応し、複雑なインタラクションを短いコードで書くことができます。2008 年から開発を始め、2012 年に α 版を公開、2013 年 9 月には IPA 未踏事業に採択 、2014 年 9 月に CEDEC に出展、2016 年 8 月に最新版 Siv3D August 2016 をリリースしました。

Siv3D 公式ページ http://play-siv3d.hateblo.jp/

5
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
6