Junichi Itou / LogibotLib

Dependents:   Logibot_Temp Motor_Temp

Files at this revision

API Documentation at this revision

Comitter:
Jrobo
Date:
Fri Mar 03 20:36:06 2017 +0000
Commit message:
publish

Changed in this revision

beep_sound.cpp Show annotated file Show diff for this revision Revisions of this file
beep_sound.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/beep_sound.cpp	Fri Mar 03 20:36:06 2017 +0000
@@ -0,0 +1,196 @@
+#include "beep_sound.h"
+#include "math.h"
+#include <queue>
+
+
+beep_sound::beep_sound(PinName pwm)
+{
+    frequency = 0;
+    playing = false;
+    teishi = false;
+    m_pwm = new PwmOut(pwm);
+    m_pwm->write(0.0f);
+}
+
+beep_sound::~beep_sound()
+{
+    delete m_pwm;
+}
+
+void beep_sound::stop(){
+    m_pwm->write(0.0f);
+    // キューが空でなければ次の音へ 
+    if(otoQue.empty() == true){
+        playing = false;
+    }else if(otoQue.front().time_s != -1){
+        playing = true;
+        beep_sound::playContinue();
+    }else if(otoQue.front().time_s == -1){
+        otoQue.pop();
+        playing = false;
+    }else{
+        playing = false;
+    }
+}
+
+// 音の再生
+void beep_sound::NoteOn(int octave, int note)
+{
+    playing = true;
+    frequency = frequencyTable[note] << octave;
+    m_pwm->period(1.0f/(float)frequency);
+    m_pwm->write(0.5f);
+}
+
+// 1音ずつ音符情報をキューに追加
+void beep_sound::setGakuhu(int argOc, int argNo, float argTi)
+{
+    bufG.octave = argOc;
+    bufG.note = argNo;
+    bufG.time_s = argTi;
+    otoQue.push(bufG);
+}
+
+// 休符をキューに追加
+void beep_sound::setKyuhu(float argTi)
+{
+    bufG.octave = 10;
+    bufG.note = 0;
+    bufG.time_s = argTi;
+    otoQue.push(bufG);
+}
+
+// 楽譜キューを再生、音停止の割り込み予約
+// Timeoutの日本語リファレンスには書いていないが、
+// thisを引数にしないとコンパイルエラーになるので注意
+void beep_sound::playGakuhu()
+{
+    if(playing == true){
+        while(otoQue.front().time_s != -1) {otoQue.pop();}
+        otoQue.pop(); //最後のフラグを削除
+            // 最後のフラグを挿入
+            bufG.time_s = -1;
+            otoQue.push(bufG);
+        beep_sound::stop();
+    }else{
+            // 最後のフラグを挿入
+            bufG.time_s = -1;
+            otoQue.push(bufG);
+        playing = true;
+        beep_sound::NoteOn(otoQue.front().octave, otoQue.front().note);
+        interruptStop.attach(this, &beep_sound::stop, otoQue.front().time_s);
+        otoQue.pop();
+    }
+}
+void beep_sound::playContinue()
+{
+    beep_sound::NoteOn(otoQue.front().octave, otoQue.front().note);
+    interruptStop.attach(this, &beep_sound::stop, otoQue.front().time_s);
+    otoQue.pop();
+}
+
+void beep_sound::SetFrequency(int octave, int note, bool on_off)
+{
+    static int preFrequency = 0;
+    if(on_off == true){
+        int frequency = frequencyTable[note] << octave;
+        if(frequency != preFrequency){
+            m_pwm->period(1.0f/(float)frequency);
+            m_pwm->write(0.5f);
+        }
+        preFrequency = frequency;
+    }else{
+        m_pwm->write(0.0f);
+        preFrequency = 0;
+    }
+}
+void beep_sound::onpu(int octave, int note, float time_s)
+{
+    playing = true;
+    beep_sound::NoteOn(octave, note);
+    interruptStop.attach(this, &beep_sound::stop, time_s);
+}
+void beep_sound::onpu_stop(int octave, int note, float time_s)
+{
+    playing = true;
+    beep_sound::NoteOn(octave, note);
+    wait(time_s);
+    m_pwm->write(0.0f);
+}
+void beep_sound::sinwave(float center,int speed,int width)
+{
+    for(float i=0.0f;i<6.28f;i+=0.01*speed)
+    {
+    m_pwm->period(1.0f/(center+width*(float)sin(i)));
+    m_pwm->write(0.5f);
+    wait_ms(2);
+    }
+}
+void beep_sound::setwave(float frequency,float duty,float wait)
+{
+    m_pwm->period(1.0f/(frequency));
+    m_pwm->write(duty);
+    wait_ms(wait);
+}
+
+
+//以下サンプル音集
+//引数の回数だけ鳴らす
+void beep_sound::boot()
+{
+    beep_sound::setGakuhu(4,8,0.03);
+    beep_sound::setGakuhu(0,8,0.03);
+    beep_sound::setGakuhu(1,8,0.03);
+    beep_sound::setKyuhu(0.14);
+    beep_sound::setGakuhu(2,8,0.08);
+    beep_sound::setGakuhu(3,1,0.16);
+    beep_sound::playGakuhu();
+}
+
+void beep_sound::beep_right(int nTimes)
+{
+    for(int i=0; i<nTimes; i++){
+        beep_sound::setGakuhu(3,11,0.1);
+        beep_sound::setGakuhu(3,7,0.35);
+        beep_sound::setKyuhu(0.1);
+    }
+    beep_sound::playGakuhu();
+}
+void beep_sound::beep_wrong(int nTimes)
+{
+    for (int i = 0; i < nTimes; i++) {
+        beep_sound::setGakuhu(0, 12, 0.1);
+        beep_sound::setKyuhu(0.1);
+        beep_sound::setGakuhu(0, 12, 0.35);
+        beep_sound::setKyuhu(0.1);
+    }
+    beep_sound::playGakuhu();
+}
+void beep_sound::beep_readyGo(int nTimes)
+{
+    //for (int i = 0; i < nTimes; i++) {
+        beep_sound::onpu_stop(1,0,0.5);
+        wait(0.5);
+        beep_sound::onpu_stop(1,0,0.5);
+        wait(0.5);
+        beep_sound::onpu_stop(1,0,0.5);
+        wait(0.5);
+        beep_sound::onpu(2,0,1);
+    //}
+}
+void beep_sound::beep_notif1(int nTimes){
+    for (int i = 0; i < nTimes; i++) {
+        beep_sound::setGakuhu(3,5,0.1);
+        beep_sound::setGakuhu(3,10,0.1);
+        beep_sound::setGakuhu(4,2,0.1);
+    }
+    beep_sound::playGakuhu();
+}
+void beep_sound::beep_notif2(int nTimes){
+    for (int i = 0; i < nTimes; i++) {
+        beep_sound::setGakuhu(1,2,0.1);
+        beep_sound::setGakuhu(1,9,0.1);
+        beep_sound::setGakuhu(2,2,0.2);
+    }
+    beep_sound::playGakuhu();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/beep_sound.h	Fri Mar 03 20:36:06 2017 +0000
@@ -0,0 +1,57 @@
+#ifndef BEEP_SOUND_H
+#define BEEP_SOUND_H
+#include "mbed.h"
+#include <queue>
+struct gakuhu{
+    int octave;
+    int note;
+    float time_s; // 長さが-1:通常ノート -2:終了フラグ
+};
+/*
+struct beep{
+    float userPeriod;
+    float userWrite;
+    float time_s;
+}
+*/
+const int frequencyTable[] = {261, 277, 294, 311, 330, 349,
+                                370, 392, 415, 440, 466, 494, 100};
+
+
+class beep_sound
+{
+    public:
+        beep_sound(PinName pwm);
+        ~beep_sound();
+        void SetFrequency(int octave, int note, bool on_off);
+        void onpu(int octave, int note, float time_s);
+        void onpu_stop(int octave, int note, float time_s);
+        void sinwave(float center,int speed,int width);
+        void setwave(float frequency,float duty,float wait);
+        // 以下サンプル音集
+        void boot();
+        void beep_right(int nTimes);
+        void beep_wrong(int nTimes);
+        void beep_notif1(int nTimes);
+        void beep_notif2(int nTimes);
+        void beep_readyGo(int nTimes);
+        // 以下並列で鳴らすための関数
+        void stop();
+        void setGakuhu(int argOc, int argNo, float argTi);
+        void setKyuhu(float argTi);
+        void playGakuhu();
+        void playContinue();
+        void NoteOn(int octave, int note);
+    private:
+        PwmOut* m_pwm;
+        int frequency;
+        // 以下並列で鳴らすための宣言
+        queue<gakuhu> otoQue;
+        gakuhu bufG;
+        Timeout interruptStop;
+        // 再生中にキューにsetGakuhuをさせないためのフラグ
+        bool playing; // false:停止中 true:再生中
+        bool teishi; // true:再生を強制停止. ノート再生時に必ずチェック.
+};
+
+#endif