圏9研究所 工作室

圏9研究所の開発情報資料など

STM32F411 BlackPill CMSIS-DSPによる楽器用チューナー(6)定数、変数、処理

1.定数一覧
1)FFT

シンボル

設定値

単位

内容

FS1

16000 = FSREAD / NK1

Hz

FFT1次サンプリング周波数

 マイク:160000 USB48000/3

FT

4 (250msec)

Hz

1/サンプリング時間

NS1

4000 = FS1 / FT

 

読込サンプル数

NFFT

4096

 

FFTサンプル数

NPOWER

2048 = NFFT / 2

 

FFT Power サンプル数

FRESO1

FS1 / NFFT

Hz

FFT1次周波数ピッチ

FKMIN

55.0

Hz

計測下限周波数

FKMAX

880.0

Hz

計測上限周波数

PKMIN

1000000 * NK1

 

計測下限Power(無音レベル)

PKK

2

 

ピーク前後除去係数(Power平均値に掛ける値)

 

2)スプライン

シンボル

設定値

単位

内容

NSPS

12

 

サンプル数 FFTピーク±6相当

NSPH

100

 

補間数

PSPH

50 = NSPS / 2

 

補間倍率 = 1/補間ピッチ = NSPH / 2

 

2.変数一覧
1)FFT

変数名

G/L

内容

uint16_t data_sample[4096 * 2]

G

読込サンプルデータ 4000 / 250msec

arm_rfft_fast_instance_f32 fft;

L

RFFT計算

float32_t fft_input[NFFT];

L

float32_t fft_output[NFFT];

L

float32_t fft_power[NFFT / 2];

L

uint8_t ifftFlag = 0;

L

float32_t maxValue;

L

arm_max_f32 引数

uint32_t maxIndex;

L

 

2)スプライン

変数名

G/L

内容

arm_spline_instance_f32 S;

L

スプライン係数

arm_spline_type type = ARM_SPLINE_NATURAL;

L

float32_t x[NSPS];

L

float32_t y[NSPS];

L

uint32_t n = NSPS;

L

float32_t coeffs[3 * (NSPS - 1)];

L

float32_t tempBuffer[2 * (NSPS - 1)];

L

float32_t xq[NSPH];

L

スプライン補間

float32_t pDst[NSPH];

L

uint32_t blockSize = NSPH;

L

float32_t maxValue_s;

L

arm_max_f32 引数

uint32_t maxIndex_S;

L

 

3)計測計算

処理

変数名

G/L

内容

FFT1次計算

float32_t avg_power

L

FFT power平均値

float32_t fm1_01, fm1_02

L

FFT1powerピーク01, 02

uint32_t fm1Index_01, fm1Index_02

L

fm1_01, fm1_02 fft_powerインデックス

float32_t fm1

L

FFT1次計測周波数 fm1=基音*fm1_multi

uint32_t fm1Index

L

fm1 fft_powerインデックス

uint32_t fm1_multi

L

fm1基音の倍数

FFT2次準備

float32_t xn

L

サンプリング変換係数

float32_t fs2

L

FFT2次サンプリング周波数

float32_t freso2

L

FFT2次周波数ピッチ

uint32_t nk2

L

fs1 / fs2 サンプリング周波数比

FFT2次計算

float32_t fm2

L

FFT2次計測周波数

スプライン

float32_t fmspl

L

スプライン補間計測周波数

fmspl=スプライン補間値 / fm1_multi

セント値計算

int16_t oct_cent

L

オクターブセント値 1[oct] = 1200[cent]

int16_t cent1200

L

セント値:0 - 1199

int16_t note

L

音階値:0 - 11

int16_t cent

L

表示セント値:±50

 

3.計測手順
1)FFT 1次

処理

手順

サンプルデータコピー

fft_input[0-3999] = sample_data[0-3999]

不足分ゼロ埋め

fft_input[4000-4095] = {0}

FFT計算

arm_rfft_fast_init_f32(&fft, NFFT);

arm_rfft_fast_f32(&fft, fft_input, fft_output, ifftFlag);

arm_cmplx_mag_f32(fft_output, fft_power, NFFT / 2);

0Hz値をゼロに

fft_power[0] = 0

fft_power 平均値算出

arm_mean_f32

ゼロ埋め

・計測範囲外 55Hz(55 / FRESO1)<, >880Hz(880 / FRESO1)

fft_power < 平均値 * 2(PKK)

fft_power < 無音レベル(PKMIN)

ピーク検出 1回目

 fm1_01

 fm1Index_01

arm_max_f32

ピーク前後 fft_power==0 までゼロ埋め

ピークIndex 2.5倍以上ゼロ埋め

ピーク検出 2回目

 fm1_02

 fm1Index_02

arm_max_f32

ピーク値1,2ソート

Index小さい順

計測周波数決定

 fm1

 fm1Index

fm1_multi

if power[fm1Index_01]==0   エラー

fm1_multi = 1

if power[fm1Index_02]==0   fm1Index=fm1Index_01

else

 if fm1Index_01 * 2 == fm1Index_02±1  fm1Index=fm1Index_01

 else 

  fm1Index = fm1Index_01

  fm1_multi = fm1Index_01 / (fm1Index_02 - fm1Index_01)

fm1 =  (float32_t)fm1Index * FRESO1

 

2)FFT 2次

処理

手順

2次サンプリング周波数

と周波数比計算

 fs2, nk2, freso2

xn = (log(fm1 * 16) – log125)/log2

fs2 = 125 * 2 ^ xn

nk2 = fs1 / fs2

freso2 = fs2 / NFFT4096;

サンプルデータコピー

 fft_input

nk2 個サンプル加算して1サンプル値とする

 データ数:fs2 / 4FT

 残りゼロ埋め

FFT計算

FFT 1次と同じ

ピーク検出

 fm2

 fm2Index

fm1Index±2 相当の間のピーク fm2Index を探す

 (fm1Index – 2)*nk2 < 検索 < (fm1Index + 2)*nk2

 fm2 = (float32_t)fm2Index * freso2 / fm1_multi;

 

3)スプライン補間

処理

手順

スプライン係数計算データ

 x

 y

インデックス範囲:maxIndex ±6

データ数:12 = NSPS

スプライン補間 x

 xq[]

補間区間 = 100NSPH

 fm2Index±/2区間を補間倍率 50PSPH = 100NSPH/2で補間値算出

スプライン計算

arm_spline_init_f32(&S, type, x, y, n, coeffs, tempBuffer);

arm_spline_f32(&S, xq, pDst, blockSize);

ピーク検出

 fmspl

arm_max 補間値yピーク値抽出

・計測周波数算出

 fmspl = xq[maxIndex_s] * freso2 / fm1_multi

 

4.表示計算
1)オクターブ値、セント値計算
(1)基本計算式
 基準周波数 = 27.5[Hz] A0
 オクターブセント:oct_cent = 1200 * log(fmspl / 27.5) / log(2)
 セント値        :cent1200 = oct_cent % 1200
 音階値        :note = cent1200 / 100
 表示セント値     :cent = cent1200 % 100

(2)表示用計算式
 表示セント値範囲を±50 符号付にする

 基準周波数 = 27.5[Hz] A0
 オクターブセント:oct_cent = (int16_t)(1200 * log(fmspl / 27.5) / log(2) + 50.5)
 セント値        :cent1200 = oct_cent % 1200
 音階値        :note = cent1200 / 100
 表示セント値     :cent = cent1200 % 100 - 50

5.補足:マイクアンプとFFT計算
1)マイクアンプ
(1)仕様
・購入先        秋月
・品名        高感度マイクアンプキット
・販売コード     105757
・種別        コンデンサーマイク
・電源電圧        2.5V〜5V
・周波数        50Hz〜6kHz
・出力        0V〜VCC
・DCオフセット    約VCC/2

(2)電源ノイズ対策
 VCC/2を仮想グランドとしていることもあり電源ノイズの影響が大きく未対策では計測レンジを小さくしなければならない
 マイクアンプの電源にはマイクロインダクター47mHを使ったパイ型フィルターを付けた

2)FFT計算データ処理
(1)DCオフセット対策
 DCオフセット相当量は0HzポイントのFFTパワー値に加算される
 対策
 ・AD変換値は加工せずFFT計算し0Hzポイントのパワー値を無視する
   今回0Hzポイントは計測範囲外のためこの方法を採用
 ・各AD変換値からDCオフセット相当量を引き算した後FFT計算する
 ・各AD変換値からAD変換値の平均値を引き算した後FFT計算する

(2)サンプリング値不足対策
 サンプリング周波数とFFTサンプル数の不一致対策
 ・不足するFFTサンプル値をゼロで埋める
 ・ゼロで埋めた分は0HzポイントのFFTパワー値に加算されるため0Hzポイントのパワー値を無視する

続く