Help us understand the problem. What is going on with this article?

音階が見えるビジュアライザー

More than 5 years have passed since last update.

音階が見えるビジュアライザーです

Main.cpp
//はむくん ビジュアライザー 試作
# include <Siv3D.hpp>

class SoundPlayer
{
private:

    GUI m_gui;

    Sound m_sound;

    const Font m_font;

    const Vec2 m_centerPos;

    static const double m_freq[];

    static const bool m_isWhite[];

    static const String m_name[];

    bool m_isRecording;
public:

    SoundPlayer()
        : m_gui{ GUISkin::Default({ 0, 0, 0 }) }, m_font(10), m_centerPos(320, 190), m_isRecording(false)
    {
        m_gui.addButton(L"PlayButton", { L"Play" });

        m_gui.addButton(L"PauseButton", { L"Pause" });

        m_gui.addButton(L"OpenButton", { L"Open" });

        m_gui.addButton(L"UseMic", { L"Mic" });

        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);

        m_gui.button(L"UseMic").setEnabled(!m_isRecording );

        m_gui.slider(L"Slider").setEnabled(!m_isRecording);

        if (m_gui.button(L"PlayButton").pushed)
        {
            m_sound.play();

            m_isRecording = false;

            Recorder::Stop();
        }
        else if (m_gui.button(L"PauseButton").pushed)
        {
            m_sound.pause();

            m_isRecording = false;

            Recorder::Stop();
        }
        else if (m_gui.button(L"OpenButton").pushed)
        {
            m_sound.pause();

            m_isRecording = false;

            Recorder::Stop();

            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);

        if (m_gui.button(L"UseMic").pushed)
        {
            if (!Recorder::Start()){

            }
            else
            {
                m_isRecording = true;

                m_sound.pause();
            }
        }

    }

    void drawVisualizer() 
    {

        if (m_isRecording)
        {
            Waving::FFT(Recorder::GetWave(), Recorder::GetPos());
        }
        else
        {
            if (m_sound.isPlaying)Waving::FFT(m_sound);
        }


        const float* p = Waving::FFTBuffer();

        for (int i = 0; i < 12; ++i)
        {
            const double startRad = getRad((m_freq[i] + m_freq[i + 1]) / 2.0) + 0.01;

            const double angle = getRad((m_freq[i + 1] + m_freq[i + 2]) / 2.0) - startRad;

            const Vec2 pos = getPosFromRad( getRad(m_freq[i])) * (160.0) + m_centerPos;

            if (m_isWhite[i])
            { 
                Circle(m_centerPos, 180).drawPie(startRad, angle, Color(50));
            }
            else
            {
                Circle(m_centerPos, 180).drawPie(startRad, angle, Color(20));
            }

            m_font.drawCenter(m_name[i], pos,Color(70));
        }

        for (int i = 0; i<1760; ++i)
        {
            const double di = i;

            const double radian = getRad(di);

            const double radius = 0.0;

            const double radiusOuter = 180.0;

            const double width = Min(radiusOuter * ((radian)- getRad(di-1)), 50.0);

            const double size = Pow(p[i], 0.6f) * 800 * Log(di)/Log(10.0);

            const double strength = Pow(size , 2.0) * Log( di ) / 1000000.0;

            const Vec2 pos = getPosFromRad(radian) * (radius + size / 2.0) + m_centerPos;

            RectF(width, size).setCenter(pos).rotate(radian).draw(HSV(240 - Log( di ) * 100,1.0,strength));
        }



        if (m_isRecording && Recorder::IsEnd()) // 録音が終了
        {
            Recorder::Restart();
        }


    }

    double getRad(double freq) 
    {
        return 2 * Pi * Log(freq) / Log(2.0) + 2.42;
    }

    Vec2 getPosFromRad(double rad)
    {
        return Vec2(Sin(rad), -Cos(rad));
    }
};

const double SoundPlayer::m_freq[] = {
    440.000000,
    466.163762,
    493.883301,
    523.251131,
    554.365262,
    587.329536,
    622.253967,
    659.255114,
    698.456463,
    739.988845,
    783.990872,
    830.609395,
    880.000000,
    932.328
};

const bool SoundPlayer::m_isWhite[] = {
    false, true, true, false, true, false, true, false, true, true, false, true
};

const String SoundPlayer::m_name[] = {
    L"D", L"D#", L"E", L"F", L"F#", L"G", L"G#", L"A", L"A#", L"B", L"C", L"C#"
};

void Main()
{
    SoundPlayer soundPlayer;

    Graphics::Set2DBlendState(BlendState::Additive());

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

        soundPlayer.drawVisualizer();       
    }
}
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away