Realtime sound spectrogram using FFT or linear prediction. Spectrogram is displayed on the display of PC. リアルタイム・スペクトログラム.解析の手法:FFT,線形予測法.スペクトログラムは PC のディスプレー装置に表示される.PC 側のプログラム:F446_Spectrogram.

Dependencies:   Array_Matrix mbed SerialTxRxIntr F446_AD_DA UIT_FFT_Real

Files at this revision

API Documentation at this revision

Comitter:
MikamiUitOpen
Date:
Mon Jul 23 05:53:29 2018 +0000
Parent:
3:74a50c14d3fd
Child:
5:fcc1b0b4737e
Commit message:
5

Changed in this revision

SerialTxRxIntr.lib Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
myFunction.hpp Show annotated file Show diff for this revision Revisions of this file
myFunctions.cpp Show diff for this revision Revisions of this file
myFunctions.hpp Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SerialTxRxIntr.lib	Mon Jul 23 05:53:29 2018 +0000
@@ -0,0 +1,1 @@
+http://os.mbed.com/users/MikamiUitOpen/code/SerialTxRxIntr/#f6e15c19dd75
--- a/main.cpp	Wed Mar 08 09:57:41 2017 +0000
+++ b/main.cpp	Mon Jul 23 05:53:29 2018 +0000
@@ -10,12 +10,16 @@
 //      ● ボーレート: 460800 baud
 //      ● 受信データの文字列の終了マーク: "\r"
 //
-//  2017/03/08, 三上 直樹
+//      ● 入力  A0: 左チャンネル,A1 右チャンネル
+//      ● 出力  A2: 左チャンネル,D13 右チャンネル
+//             入力をそのまま出力する
+//
+//  2018/07/23, Copyright (c) 2018 MIKAMI, Naoki
 //---------------------------------------------------------------------
 
 #include "mbed.h"
 #include <string>
-#include "myFunctions.hpp"
+#include "myFunction.hpp"
 #include "Array.hpp"
 #include "F446_ADC_Interrupt.hpp"
 #include "FFT_Analyzer.hpp"
@@ -43,7 +47,7 @@
 
 const int FS_ = 16000;      // 標本化周波数: 16 kHz
 AdcDual_Intr myAdc_(FS_);   // "F446_ADC_Interrupt.hpp" で定義
-DacDual myDac_;             // "F446_DAC" で定義
+DacDual myDac_;             // "F446_DAC.cpp/hpp" で定義
 
 // FFT によるスペクトル解析オブジェクトの生成
 FftAnalyzer *fftAnlz_ = new FftAnalyzer(N_DATA_, N_FFT_);
@@ -51,18 +55,10 @@
 LpcAnalyzer *lpcAnlz_ = new LpcAnalyzer(N_DATA_, N_FFT_, 20);
 AnalyzerBase *analyzer_ = fftAnlz_;     // 最初は FFT を使う
 
-Serial pc_(USBTX, USBRX);   // PC との通信で使うオブジェクト
-DigitalOut myLed_(D10, 1);  // LED1 が使えないので D10 を使う
+SerialRxTxIntr rxTx_(32, 115200*4);     // PC との通信用
 
-const int DATA_SIZE_ = N_FFT_/2 + 1;
-Array<uint16_t> txData_(DATA_SIZE_);    // 送信用データ
-string rxBuffer_;           // 受信バッファ
-
-float levelShift_ = 20;     // dB 計算の際のシフト量の初期値
 float empha_ = 1.0f;        // 高域強調器の係数
 
-__IO bool eol_;             // "\r" を受信した場合に true
-
 // 入力チャンネルを選択する関数とそれを割り当てる関数ポインタ
 float InputL(float x1, float x2) { return x1; }
 float InputR(float x1, float x2) { return x2; }
@@ -93,37 +89,34 @@
 
 int main()
 {
+    const int DATA_SIZE = N_FFT_/2 + 1;
+    Array<uint16_t> txData(DATA_SIZE);     // 送信用データ
     float sn[N_DATA_];      // スペクトル解析の対象となるデータ
     float db[N_FRAME_];     // 解析結果である対数スペクトル [dB]
     for (int n=0; n<N_DATA_; n++) sn[n] = 0;
     for (int n=0; n<N_FRAME_; n++) xPong_[n] = 2048;    // uint16_t 型の 0 に対応
 
-    rxBuffer_ = "";     // 受信バッファのクリア
-    eol_ = false;
+    NVIC_SetPriority(ADC_IRQn, 0);      // AD変換終了割り込みの優先度が最高
+    NVIC_SetPriority(USART2_IRQn, 1);
 
-    pc_.baud(115200*4); // ボーレートの設定
-    pc_.format();       // default: 8 bits, nonparity, 1 stop bit
-
-    NVIC_SetPriority(ADC_IRQn, 1);      // AD変換終了割り込みの優先度が最高
-    NVIC_SetPriority(USART2_IRQn, 2);
-
-    pc_.attach(&Rx);            // 受信割り込みの割り当て
+    float levelShift = 20;  // dB 計算の際のシフト量の初期値
 
     full_ = false;
-    myAdc_.SetIntrVec(&AdcIsr); // AD変換終了割り込みの割り当て
-
     __IO bool ready = false;    // スペクトルの計算終了で true
     __IO bool okGo = false;     // "GO" を受信したら true
+
+    myAdc_.SetIntrVec(&AdcIsr); // AD変換終了割り込みの割り当て
     while (true)
     {
         // PC からのコマンドの解析
-        if (eol_)
+        if (rxTx_.IsEol())      // 受信バッファのデータが有効になった場合の処理
         {
-            if (rxBuffer_.find("ENQ") != string::npos)
-                pc_.printf("ACK\n");    // "ACK" を PC へ転送
-            else if (rxBuffer_.find("GO") != string::npos)
+            string str = rxTx_.GetBuffer();
+            if (str.substr(0, 3) == "ENQ")
+                rxTx_.Tx("ACK");
+            else if (str.substr(0, 2) == "GO")
             {
-                // rxBuffer_ の内容
+                // str の内容
                 // [0]  'G'
                 // [1]  'O'
                 // [2]  入力チャンネルの選択:'L', 'R', or '+'
@@ -131,7 +124,7 @@
                 // [4]  高域強調器の有無:'Y', 'N'
                 // [5]  解析方法  F: FFT,L: 線形予測法
 
-                switch (rxBuffer_[2])   // 'L', 'R', or '+'
+                switch (str[2])
                 {
                     case 'L': InputNew = InputL;  break;
                     case 'R': InputNew = InputR;  break;
@@ -139,20 +132,16 @@
                     default : InputNew = InputLR; break;
                 }
 
-                levelShift_ = (float)(rxBuffer_[3] - ' ');  // dB 計算の際のシフト量
+                levelShift = (float)(str[3] - ' ');     // dB 計算の際のシフト量
 
-                if (rxBuffer_[4] == 'Y') empha_ = 1.0f;     // 高域強調器は有
-                else                     empha_ = 0;        // 高域強調器は無
+                if (str[4] == 'Y') empha_ = 1.0f;       // 高域強調器は有
+                else               empha_ = 0;          // 高域強調器は無
 
-                if (rxBuffer_[5] == 'F') analyzer_ = fftAnlz_;  // FFT
-                else                     analyzer_ = lpcAnlz_;  // 線形予測法
+                if (str[5] == 'F') analyzer_ = fftAnlz_;    // FFT
+                else               analyzer_ = lpcAnlz_;    // 線形予測法
  
                 okGo = true;            // データの転送要求あり
             }
-
-            eol_ = false;
-            rxBuffer_ = "";     // 受信バッファのクリア
-            wait_ms(1);
         }
 
         if (full_)  // 入力データが満杯かどうか調べる
@@ -170,13 +159,13 @@
             analyzer_->Execute(sn, db); // スペクトル解析の実行
 
             const float FACTOR = 10000.0f/80.0f;     // 表示範囲: 0 ~ 80 dB
-            for (int n=0; n<DATA_SIZE_; n++)
+            for (int n=0; n<DATA_SIZE; n++)
             {
-                float xDb = FACTOR*(db[n] + 30.0f + levelShift_);
+                float xDb = FACTOR*(db[n] + 30.0f + levelShift);
                 if (xDb > 10000.0f) xDb = 10000.0f;
                 if (xDb < 0.0f) xDb = 0.0f;
                 uint16_t spc = (uint16_t)xDb;
-                txData_[n] = spc;
+                txData[n] = spc;
             }
             ready = true;       // スペクトル解析終了
         }
@@ -184,9 +173,10 @@
         // 転送要求がありスペクトル解析が終了している場合にデータを PC へ転送する
         if (okGo && ready)
         {
-            Xfer(txData_);      // データを PC へ転送
+            Xfer(txData);       // データを PC へ転送
             ready = false;
             okGo = false;
         }
     }
 }
+
--- a/mbed.bld	Wed Mar 08 09:57:41 2017 +0000
+++ b/mbed.bld	Mon Jul 23 05:53:29 2018 +0000
@@ -1,1 +1,1 @@
-http://mbed.org/users/mbed_official/code/mbed/builds/e1686b8d5b90
\ No newline at end of file
+http://mbed.org/users/mbed_official/code/mbed/builds/a7c7b631e539
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/myFunction.hpp	Mon Jul 23 05:53:29 2018 +0000
@@ -0,0 +1,31 @@
+//---------------------------------------------------------------------
+//  データを PC へ転送
+//
+//  2018/07/23, Copyright (c) 2018 MIKAMI, Naoki
+//---------------------------------------------------------------------
+
+#include <string>
+#include "Array.hpp"
+#include "SerialRxTxIntr.hpp"
+using namespace Mikami;
+
+#ifndef MY_FUNCTION_XFER_HPP
+#define MY_FUNCTION_XFER_HPP
+
+extern SerialRxTxIntr rxTx_;
+
+// データを PC へ転送(0 ~ 10,000 の範囲の値を 2 文字で表すコード化を利用)
+void Xfer(Array<uint16_t> &xn)
+{
+    string str = "";
+    for (int n=0; n<xn.Length(); n++)
+    {
+        div_t a = div(xn[n], 100);
+        str += a.quot + 0x10;
+        str += a.rem + 0x10;
+    }
+    rxTx_.Tx(str);
+    rxTx_.Tx("EOT");
+}
+
+#endif  // MY_FUNCTION_XFER_HPP
--- a/myFunctions.cpp	Wed Mar 08 09:57:41 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-#include "myFunctions.hpp"
-
-// シリアル・ポートの受信割り込み
-void Rx()
-{
-    unsigned char chr = pc_.getc();
-    // '\r' を受信した場合はメッセージの終了とする
-    // '\r' は,rxBuffer_ には追加されない
-    if (chr == '\r') eol_ = true;
-    else             rxBuffer_ += chr;  // '\r' が来るまで文字が追加される
-
-    // 受信するメッセージの文字数のチェック
-    if (rxBuffer_.size() > RX_MAX_)
-        while (true)    // 文字数がオーバーの場合 LED が点滅する
-        {
-            myLed_ = !myLed_;
-            wait(0.1f);
-        }
-}
-
-// データを PC へ転送(0 ~ 10,000 の範囲の値を 2 文字で表すコード化を利用)
-void Xfer(Array<uint16_t> &xn)
-{
-    for (int n=0; n<xn.Length(); n++)
-    {
-        div_t a = div(xn[n], 100);
-        pc_.putc(a.quot + 0x10);
-        pc_.putc(a.rem + 0x10);
-    }
-    pc_.printf("\n");       // データの最後を通知
-    wait_ms(1);             // これは必須
-    pc_.printf("EOT\n");    // 転送終了であることを送信
-}
--- a/myFunctions.hpp	Wed Mar 08 09:57:41 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,22 +0,0 @@
-#include "mbed.h"
-#include <string>
-#include "Array.hpp"
-using namespace Mikami;
-
-#ifndef MY_FUNCTIONS_HPP
-#define MY_FUNCTIONS_HPP
-
-const int RX_MAX_ = 32;     // 受信バッファの文字数の最大値
-
-extern string rxBuffer_;    // 受信バッファ
-extern __IO bool eol_;      // "\r" を受信した場合に true
-
-extern Serial pc_;
-extern DigitalOut myLed_;
-
-// シリアル・ポートの受信割り込み
-void Rx();
-// データを PC へ転送
-void Xfer(Array<uint16_t> &xn);
-
-#endif  // MY_FUNCTIONS_HPP