FC2ブログ

名張市つつじが丘おもちゃ病院

三重県名張市つつじが丘でおもちゃの病院を開院しています。年中無休で修理は無料、部品代のみ実費です。おもちゃの修理依頼は tutuji@cb4.so-net.ne.jp へメールにてご連絡下さい。なお、宅配便での受け付けは行っておりません。このブログにはおもちゃ等の修理事例やツール製作などを載せていきます。故障診断や修理方法の改善等、ご意見をお寄せ下さい。

STM32電子オルゴールVer1_2(ピアノ音源)

【前振り】
STM32電子オルゴールの開発の目的の1つにキーボードおもちゃへの応用があり、キーボードでいろんな楽器音を出したい。そのトライアルとして、ピアノ音の音源データを作ってみた。


【設計】
①音の出始めの波形とその時間的な変化が楽器音を特徴付けると言われているので、以下の波形生成方法とする。

・音の出始めから波形が変化している期間の音を音源サンプルデータに取り込む。

・音源サンプルデータを先頭から最後まで1回再生する。

・その後は、音源サンプルデータの最後の1サイクル分を繰り返し再生する。

②実際のピアノ音を観察してみる。

・生ピアノの中央ド(C4=261.63Hz)の音を波形観測した。中心的な音程として中央ドを選んだ。

SoundEngineで波形を表示させた。

全体の波形
STM32電子オルゴールVer1_2(ピアノ音源)C4波形1

時間軸を拡大
STM32電子オルゴールVer1_2(ピアノ音源)C4波形2
STM32電子オルゴールVer1_2(ピアノ音源)C4波形3
STM32電子オルゴールVer1_2(ピアノ音源)C4波形4


・出始めから100msくらいまでは波形が細かく変化している。

・その後は250msくらいまでは変化を続ける。

・500ms以降は殆ど変化しなくなる。

③必要なメモリ量を試算した。

・500ms間のサイクル数は131であり、1サイクル当たりのサンプル数を100とすると13.1kサンプル(=13.1kバイト)になる。100サンプル以上を確保しないと 音程がズレる

・廉価な1チップマイコンのフラッシュメモリは高々32kバイト程度であり、これに対して音源サンプルデータのメモリ消費が大きく、複数種類の音源を持つことが難しくなる。

・音源サンプルデータをSPIフラッシュメモリに置く方法が考えられるが、ランダムアクセスが必要になるので読み込みのオーバヘッドが大きくなり、音声再生と同時実行ではアンダーランが発生するだろう。

・プログラムフラッシュの容量から考えると200ms(=約5kサンプル=約5kバイト)程度が限度だ。

④音源のサンプリングレートを考えると、

・261.63Hzの1サイクルを100サンプルとするには 261.63Hz×100サンプル=26ksps となる。

・一般的な音声加工ツールを利用するため、サンプリングレートは32kspsとする。

・1サイクルのサンプル数を逆算すると 32ksps/261.63Hz=122サンプル となる。

・200ms間のサンプル数は 32ksps*200ms=6.4kサンプル

⑤サンプルデータの長さによる音色の違いを比べるため、実際に音源サンプルデータを作って演奏させてみた。

・サンプル数を300、1k、10kで聴き比べた結果、予想に反して300サンプルが最もピアノ音らしく聴こえた。

・出始めの波形が細かい部分を繰り返した方が良いようだ。

・ピアノは打楽器の一種でアタックタイムが無いと考えるのが妥当ではないか、と思う。

⑥当初の「音の出始めの波形とその時間的な変化が楽器音を特徴付ける」と言う考えは、ピアノ音源では排除することにして、従来の1サイクル分の波形を繰り返し再生するやり方に戻す。

・全体のサンプル数を多くするより1サンプル当たりのサンプル数を多くした方が聴感として良い結果が得られたので、元々の音源の44.1kspsのまま、音源サンプルデータに加工することにした。

⑦44.1kspsのサンプルデータをExcelに喰わせて、1サイクル当たりのサンプル数を計算した。(ダウンロードファイル「orgel1_2\wave_PIANO\C4.xls」のシート「44kspsサイクル数」)

・261.63Hzに対する44.1kspsでのサンプル数は、計算上は168.56サンプルになる。

・半周期に当たる84サンプルでの平均値を求める。これで偶数時高調波が取り除かれるハズで、波形は以下になった。
STM32電子オルゴールVer1_2(ピアノ音源)C4平均値波形

・サンプル値が1つ前のサンプルより小さくなったサンプルを数える。これがサイクル数になる。

・計測期間のサンプル数は 49985-92=49893

・計測期間のサイクル数は 301

・1サイクルのサンプル数は 49893/301=165.21 となり、計算値とズレている。

・オリジナルのピアノ音源が442Hzチューニングだったとしても、計算値は167.80となり、乖離は大きい。どこかに誤差があるのだろうが、実測値の方を採り、1サイクル分のサンプル数は 165.21 とする。

⑧音源サンプルデータを作る。

・44.1kspsの音源波形(ダウンロードファイル「orgel1_2\wave_PIANO\C4.xls」のシート「44ksps16bit」の269行~436行の167サンプル)を音源サンプルデータ「wave_PIANO_C4.s」に取り込んだ。

・ピアノ音源の製作に関わる資材は「orgel1_2\wave_PIANO」に納められている。


【評価】
①演奏音を聴くと、いい出来だと思う。
STM32電子オルゴールVer1_2(ピアノ音源)

②ピアノ音では単純に1サイクル分の波形を繰り返し再生する方法で、おもちゃとしては行けそうだ。


【ダウンロード】
設計資料とプロジェクト一式は ここから ダウンロードできる。

プロジェクトディレクトリは「orgel1_2」

プロジェクトは「piano_STM32F030F4P6.uvproj」

根のソースファイルは「piano.c」

データファイルのアセンブラソースファイルは「piano.s」

その他のソースファイルは上記の2つのソースファイルから#includeされる。
スポンサーサイト



  1. 2021/07/18(日) 15:24:47|
  2. 電子オルゴール+音声再生
  3. | コメント:0

PIC電子オルゴールVer6_3(キーボードおもちゃへの応用の検討)

【前振り】
PIC電子オルゴールの懸案事項であった「キーボードおもちゃへの応用」については、PICよりも先に STM32で実現可能性が確認 できた。今回は、PICでの実現可能性を確認した。


【設計】
STM32でのやり方をPIC電子オルゴールにも適用する。

①電子オルゴールで音符を演奏する処理方式はそのまま継承して、キーボード操作で音符を作って、それをオルゴールエンジンへ渡す制御のルートを作る。

・自動演奏の仕掛けとしては、シーケンサーと音源を組み合わせることが一般的な考えなのだが、元々のPIC電子オルゴールではシーケンサーと音源を1つのマイコン内に同居させるほどのCPU性能が無い。

・シーケンサーと音源を分離すると、構成の自由度は高められるが処理の分割損が多くなるのとインタフェースの標準化が嵩張るのでよりCPUが必要になる。オルゴール演奏だけでもアセンブラで書かないとアンダーランが発生する状況なので、できるだけCPUを喰わないやり方を採らないといけない。

・複数種類のシーケンサーや音源を開発する気は無いので自由な組み合わせの要求度は殆ど無い。

②現行の電子オルゴールのエンジン部では音符データテーブルから音符データを取り出して演奏しているが、キーボード演奏では固有処理部から音符データを受け取る。そのためのバッファをエンジン部に設ける。

・固有部ではキースキャンを行って、キーボード操作に対応する音符データを1個作ってバッファへ置く。

・エンジン部では、バッファから1個の音符データを取り出して演奏する。

③音源波形データ、エンベロープ波形データ等へのリンクはソングデータで押えていることと、音符データでベロシティ設定やエンベロープ設定を行っているので、それらの仕組みもそのまま継承する。その上で、キーボード演奏モード(音符データをバッファ経由で受け取る)への移行を音符データで指示する。

・ソングデータからリンクされる音符データテーブルでは、ベロシティ設定やエンベロープ設定の後に、キーボード演奏モード移行設定を記述する。

・キーボード演奏モード移行設定の後は、エンジン部は音符データテーブルから音符データの取り出しをやめて、バッファへ音符データが入れられるのを待つ。

・キーボード演奏モード移行設定のデータは、新規のコード「0x000d」を割り当てた。

④音価に相当する発声時間はキーボード操作に因るので、発声開始時には決まらない。

・キーが押されっ放しのときは、音価残を最大値に更新し続けることで発声動作を続けさせる。

・キーが離されたら、音価残をクリアして発声動作を止める。

・これらの制御は固有部で行う。

⑤キーボード演奏は1つのパートで実行するので、他のパートでは通常のオルゴール演奏が実行できる。

・手本の曲や伴奏をオルゴール演奏しながら、キーボード操作での演奏も同時に行える。このような利用シーンは有りそうに思う。


【コード例】
固有部のコード
PIC電子オルゴールVer6_3(キーボードおもちゃへの応用の検討)固有部のコード

曲番号1のソングデータ(EXP減衰)
PIC電子オルゴールVer6_3(キーボードおもちゃへの応用の検討)曲番号1のソングデータ(EXP減衰)

曲番号2のソングデータ(減衰無し)
PIC電子オルゴールVer6_3(キーボードおもちゃへの応用の検討)曲番号2のソングデータ(減衰無し)

【ダウンロード】
設計資料とプロジェクト一式は ここから ダウンロードできる。

プロジェクトは「orgel_1705_KB.X」

根のソースファイルは「orgel_1705_KB.asm」

その他のソースファイルは上記の2つのソースファイルから#includeされる。
  1. 2021/07/07(水) 19:19:39|
  2. 電子オルゴール+音声再生
  3. | コメント:0

STM32電子オルゴールVer1_2(キーボードおもちゃへの応用の検討)

【前振り】
最近のおもちゃは歌ったり喋ったりするものが多い。それらのICが壊れたときの代替部品として、STM32(やPIC)で電子オルゴールを開発している。

大概のおもちゃは電子オルゴールの演奏機能と音声再生機能で換装することができるのだが、キーボードおもちゃの再現は難しい。嘗て、PIC電子オルゴールでキーボードおもちゃのCOBを換装した ことがあるが、そのやり方は「無理矢理」な方法だったので、今回は、キーボードおもちゃの換装をよりスマートに行うべく、STM32電子オルゴールの機能改善を検討している。

その実現方式が固まってきたので公開する。


【設計】
①電子オルゴールで音符を演奏する処理方式はそのまま継承して、キーボード操作で音符を作って、それをオルゴールエンジンへ渡す制御のルートを作る。

・自動演奏の仕掛けとしては、シーケンサーと音源を組み合わせることが一般的な考えなのだが、元々のPIC電子オルゴールではシーケンサーと音源を1つのマイコン内に同居させるほどのCPU性能が無い。そのため、音符データでオルゴール音を直接発声させる構成にしている。しかも、Cではアンダーランが発生するのでアセンブラで書いている。

・STM32電子オルゴールでもシーケンサーと音源の分離を考えたが、構成の自由度は高められるが処理の分割損が多くなるのとインタフェースの標準化が嵩張るので敬遠した。複数種類のシーケンサーや音源を開発する気は無いので自由な組み合わせの要求度は殆ど無い。

②現行の電子オルゴールのエンジン部では音符データテーブルから音符データを取り出して演奏しているが、キーボード演奏では固有処理部から音符データを受け取る。そのためのバッファをエンジン部に設ける。

・固有部ではキースキャンを行って、キーボード操作に対応する音符データを1個作ってバッファへ置く。

・エンジン部では、バッファから1個の音符データを取り出して演奏する。

③音源波形データ、エンベロープ波形データ等へのリンクはソングデータで押えていることと、音符データでベロシティ設定やエンベロープ設定を行っているので、それらの仕組みもそのまま継承する。その上で、キーボード演奏モード(音符データをバッファ経由で受け取る)への移行を音符データで指示する。

・ソングデータからリンクされる音符データテーブルでは、ベロシティ設定やエンベロープ設定の後に、キーボード演奏モード移行設定を記述する。

・キーボード演奏モード移行設定の後は、エンジン部は音符データテーブルから音符データの取り出しをやめて、バッファへ音符データが入れられるのを待つ。

・キーボード演奏モード移行設定のデータは従来の音符データと被らないデータ値「0x7fff」とする。

④音価に相当する発声時間はキーボード操作に因るので、発声開始時には決まらない。

・キーが押されっ放しのときは、音価残を最大値に更新し続けることで発声動作を続けさせる。

・キーが離されたら、音価残をクリアして発声動作を止める。

・これらの制御は固有部で行う。

⑤キーボード演奏は1つのパートで実行するので、他のパートでは通常のオルゴール演奏が実行できる。

・手本の曲や伴奏をオルゴール演奏しながら、キーボード操作での演奏も同時に行える。このような利用シーンは有りそうに思う。


【コード例】
固有部のコード
STM32電子オルゴール音符コードのフィールド定義(キーボード演奏の検討)固有部コード

曲番号1のソングデータ(EXP減衰)
STM32電子オルゴール音符コードのフィールド定義(キーボード演奏の検討)ソングデータ(EXP減衰)

曲番号2のソングデータ(減衰無し)
STM32電子オルゴール音符コードのフィールド定義(キーボード演奏の検討)ソングデータ(減衰無し)


【ダウンロード】
設計資料とプロジェクト一式は ここから ダウンロードできる。

プロジェクトディレクトリは「orgel1_2」

プロジェクトは「kb_STM32F030F4P6.uvproj」

根のソースファイルは「kb.c」

データファイルのアセンブラソースファイルは「kb.s」

その他のソースファイルは上記の2つのソースファイルから#includeされる。
  1. 2021/06/30(水) 20:34:29|
  2. 電子オルゴール+音声再生
  3. | コメント:0

STM32電子オルゴールVer1_2(ポルタメント演奏のサポート)

【前振り】
先般、STM32電子オルゴールでピッチベンド機能をサポート したが、そのときの検討課題であった「ポルタメント演奏機能」をサポートした。


【設計】
①ピッチベンドはその変化の仕方をピッチベンド波形で定義するので、時間軸でピッチの変化を自由に表すことができる。ポルタメントは音符間で音高を連続して滑らかに変化させるので、ピッチベンドのような変化の自由度は無いが、演奏コードに「ポルタメント」のフラグを付けるだけで演奏効果が得られる。

②前の音符のサンプル飛び数を現音符の開始時のサンプル飛び数として、正規のサンプル飛び数に到達するまで一定値を増加または減少させていく。

③ポルタメント演奏の可変パラメータは、ピッチの変化スピードだけだ。それは下記の2つのパラメータで指定する。

・ポルタメント処理実行の周期

音符データで、1msを単位とした数値を指定する。内部処理では、波形生成処理の実行周期に対するプリスケール値に替えてポルタメント処理を制御する。

・ポルタメント処理実行周期毎のサンプル飛び数の変化率

音符データで、増減値シフト計算のビット数(=「変化率指定」)を指定する。

増減値=(現音符のサンプル飛び数-前の音符のサンプル飛び数)/(1<<「変化率指定」)

増減値は現音符の開始時に計算し、現音符が終了するまで変化しない。

④現音符のサンプル飛び数に到達したら、サンプル飛び数の増減を終了する。

⑤音符データのフィールド定義は下記に替えた。
STM32電子オルゴール音符コードのフィールド定義(ポルタメントサポート)1
STM32電子オルゴール音符コードのフィールド定義(ポルタメントサポート)2

⑥既存の演奏技法との同時効果も可能とする。

・タイ・スラーは、音符の開始時に音源波形サンプルオフセットとエンベロープ波形サンプルオフセットを前の音符から継続する処理で、ポルタメント処理と競合しない。

・スタッカートは、音符の音価を正規の1/4に短くする処理で、ポルタメント処理と競合しない。

・実際の効果は【実演】で紹介。

⑦演奏技法のコード定義をヘッダファイルに追加した。
STM32電子オルゴール演奏コーディング定義
例えば、タイ・スラーとポルタメントを同時に演奏するときは音符データの演奏コードに TIE+POR と記述する。


【実演】
STM32電子オルゴールポルタメント演奏
下記の順に演奏している。
・通常演奏
・スタッカート演奏
・ポルタメント演奏
・スタッカート演奏+ポルタメント演奏
・タイ・スラー演奏
・タイ・スラー演奏+ポルタメント演奏

このソングデータ(音符データ込み)は以下の通り。
STM32電子オルゴールポルタメント演奏ソースコード1
STM32電子オルゴールポルタメント演奏ソースコード2

【ダウンロード】
設計資料とプロジェクト一式は ここから ダウンロードできる。

プロジェクトディレクトリは「orgel1_2」

プロジェクトは「demo_STM32F030F4P6.uvproj」

根のソースファイルは「demo.c」

データファイルのアセンブラソースファイルは「demo.s」

その他のソースファイルは上記の2つのソースファイルから#includeされる。
  1. 2021/06/27(日) 09:53:43|
  2. 電子オルゴール+音声再生
  3. | コメント:0

STM32電子オルゴールVer1_2(ピッチベンド機能のサポート)

【前振り】
先般、STM32電子オルゴールの残課題をサポート したが、そのときの積み残しであった「ピッチベンド機能」もサポートした。


【設計】
ピッチの変化はベロシティの変化に比べて敏感に聴こえる。そのため、よりきめ細かく制御しないと粗が目立ってしまう。例えると、なだらかな坂道が階段に聴こえてしまう。

①ピッチベンドの変化範囲は2オクターブ下~2オクターブ上とする。

・ピッチベンド波形サンプル値を音源サンプル飛び数に乗じることでピッチベンド効果を得る。

・ピッチベンドサンプル値が64でそのままのキー、16で2オクターブ下、256で2オクターブ上に対応させる。

②変化の周期は数10ms以下から設定可能とする。

・ピッチベンドの効果時間を数秒とするとピッチベンド波形サンプルは数100サンプル以上が必要になる。

・サンプル数を少なくするするため、サンプル間を直線近似で按分計算することで見掛けのサンプル数を増大させる。実際には最大7ビット分(128分割)の按分を行っている。

③変化のステップは5セント以下とする。

・ステップを5セント以下とするには9ビットの精度が必要になる。

 1600/5=320

・ピッチベンド波形サンプル値の最小値は16であり、4ビットである。これに、更に9ビットを加えてサンプル値は13ビットが必要になる。

・サンプルの量子化ビット数はメモリ量を削減するため8ビットととするが、内部処理では13ビット以上で扱い、必要な精度を担保する。サンプルの按分処理で分解能が最大7ビット分向上するので15ビット精度で処理できる。16ビット以下であればビット数を節約しても得しないので、実際は16ビット精度で処理している。

・最大の精度が得られるように、ピッチベンドの処理周期とプリスケ周期を設定する必要がある。


音符データのフィールド定義は下記に替えた。
STM32電子オルゴール音符コードのフィールド定義(ピッチベンドサポート)

エンベロープ処理も、ピッチベンドに合わせた設定と処理に替えた。と一言なのだが、要はエンベロープ波形についても、サンプル間を最大7ビット分(128分割)の按分計算をして見掛けのサンプル数を増大させる改善を行ったと言うことだ。


【実演】
PIC電子オルゴールでも楽曲の演奏でピッチベンドを使った実績は無く、パトカーサイレンをオルゴール演奏で鳴らすことしかやっていない。

STM32でパトカーサイレンを鳴らしてみた。STM32電子オルゴールパトカー

このソングデータ(音符データ込み)は以下の通り。
STM32電子オルゴールPATCARソースコ-ド1
STM32電子オルゴールPATCARソースコ-ド2

【ダウンロード】
設計資料とプロジェクト一式は ここから ダウンロードできる。

プロジェクトディレクトリは「orgel1_2」

プロジェクトは「demo_STM32F030F4P6.uvproj」

根のソースファイルは「demo.c」

データファイルのアセンブラソースファイルは「demo.s」

その他のソースファイルは上記の2つのソースファイルから#includeされる。


【後記】
ピッチベンドはフツウの楽曲では使われていない。それよりもポルタメントの方が一般的だと思うので、今後はポルタメントのサポートを考える。

今回の改善で、PIC版のorgel6_3の機能はすべてサポートした。

PIC16ではCPU不足でC言語はもとより、アセンブラでもスマートに組めなかった。それが8ビットコアから32ビットコアにワープして理想的な形で組むことができた。ビット数もさることながら、それよりも乗算命令が有ることがCPU負荷の低減に寄与している。エンベロープ処理もピッチベンド処理も乗算を積極的に使っている。

それでいてデバイスのコストは同等で、でも、、昔はSTM32は高かったのでPIC16の選択は仕方がなかったと思う。
  1. 2021/06/18(金) 09:05:35|
  2. 電子オルゴール+音声再生
  3. | コメント:0

STM32電子オルゴールVer1_2(設計情報「GPIO割り込み」)

【前振り】
先般、STM32電子オルゴール をリリースしたが、その設計内容を著していきたい。今回は「GPIO割り込み」について。


【GPIO割り込み】
GPIOに繋いだSWの操作で曲の演奏開始/中止、音声再生の開始/中止を制御する。

演奏または再生を実行していないときはSTOPモードでSleepしている。

SWはGPIOポートとGND間に設置してあり、SWを閉じるとGPIOは立ち下りエッジを検知して、EXTI割り込みにてWakeupする。

STM32電子オルゴールでは、EXTI割り込みはWakeupするためだけに利用していて、SW操作の識別はWakeup後のアプリ処理で行っている。


【EXTIの解説】
データシートの解説はネット上に指南記事が多くあるのと、素人の僕が解説するのは烏滸がましいので、僕は今まで指南記事は書いて来なかった。しかし、STM32のEXTI割り込みの設定は僕自身が判り難かったのと、僕が使っているSTM32F030F4P6とSTM32F030K6T6での事例がネット上に見当たらなかったので、ここに記しておくことにした。

ここの STM32F303K8の解説記事 は大変解り易い。

これをベースにSTM32F030F4P6とSTM32F030K6T6に特化したのが、僕のこの記事だ。特化したと言っても、上記のブログ記事にも書かれているように、同じSTM32のファミリなので大きな違いはない。


【STM32F030xxのEXTI】
データシート等からEXTIに関する記述を拾い上げた。

STM32電子オルゴールEXTI_GPIO


STM32電子オルゴールEXTICRx
EXTICR1、EXTICR2、EXTICR3、EXTICR4がある。


STM32電子オルゴールEXTI_IMR


STM32電子オルゴールISER_ICER


STM32電子オルゴール割込みメンバー

STM32電子オルゴールPRIMASK1
STM32電子オルゴールPRIMASK2
STM32電子オルゴールPRIMASK3

これらの情報を下記の表にまとめた。ポートの割り付けを替えるときにはこの表に従ってコードを変更すればよい。

変更の必要が生じたときにデータシートを見て考えればいいのだが、そのときには恐らくSTM32のお作法をまるっきり忘れていて、最初から解読することになってしまうだろう。そのときのためにアンチョコを作っておこうと言うことだ。
STM32電子オルゴール外部割り込み設定表


【外部割り込みラインの割り付け】
外部割り込みラインはEXTI0~EXTI15の16本あり、それぞれの番号と同じGPIOピンが割り付く。

・例えば、EXTI1に割り付け可能なのはPA1、PB1、PF1のどれか1本である。つまり、PA1とPB1、PF1は同時に外部割り込みラインとして使えないと言うことだ。

・例えば、EXTI1にPB1を割り付ける場合は、SYSCFG->EXTICR1のEXTI1[3:0]を0001に設定する。


【割り込み設定】
割り込み許可/禁止の設定

・割込み許可は、ISERレジスタの該当するビットに1を書き込む。

・割込み禁止は、ICERレジスタの該当するビットに1を書き込む。


グローバル割込み
・POR後には、グローバル割り込みは許可(PRIMASKの初期値は0)されているので、それを弄る必要はない。

ソースコード
STM32電子オルゴールEXTI割り込み設定ソースコード


【割り込み処理ルーチン】
該当する割り込み処理ルーチンを関数定義する。

・割り込み処理ルーチンでは、EXTI割り込みペンディングフラグをクリアすること。

・すべてのペンディングフラグを纏めてクリアするには、「EXTI->PR=0xffffffff」を実行すればよい。

・どのEXTIラインからの割り込み要因なのかの識別は、STM32電子オルゴールでは不要なのでやっていない。

ソースコード
STM32電子オルゴールEXTI割り込み処理ルーチンソースコード
  1. 2021/06/01(火) 20:26:06|
  2. 電子オルゴール+音声再生
  3. | コメント:0

STM32電子オルゴールVer1_2(STM32F030K6T6のサポート)

【前振り】
先般、STM32F030F4P6の電子オルゴール を公開したが、STM32F030K6T6もサポートした。

【設計】
STM32F030K6T6はSTM32F030F4P6の上位互換があるので、ポートの割り当ても変更不要でファームウェアのコードはそのまま使える。なので、プロジェクトのターゲットデバイスをSTM32F030K6T6に替えるだけだ。

出来上がったHEXファイルを比較すると、全く同じだった。それじゃ初めから分ける必要は無かったか。でも、ポートの数やプログラムメモリ量は違うので、プロジェクトはターゲットデバイス別に作っておいた方が良い。

回路図(STM32F030K6T6はDIP32変換基板へ実装したイメージで表示している)
テストベンチ
STM32電子オルゴール回路図K6T6テストベンチ

外部メモリ無し
STM32電子オルゴール回路図K6T6外部メモリ無し

SPIフラッシュメモリ(2線SPI接続)使用
STM32電子オルゴール回路図K6T6SPIメモリ

I2Cフラッシュメモリ使用
STM32電子オルゴール回路図K6T6I2Cメモリ

【ダウンロード】
設計資料とプロジェクト一式は ここから ダウンロードできる。

プロジェクトディレクトリは「orgel1_2」

プロジェクトは「demo_STM32F030K6T6.uvproj」

根のソースファイルは「demo.c」

データファイルのアセンブラソースファイルは「demo.s」

その他のソースファイルは上記の2つのソースファイルから#includeされる。


【残課題】
ピッチベンド演奏機能は未サポートである。
  1. 2021/05/29(土) 17:28:29|
  2. 電子オルゴール+音声再生
  3. | コメント:0

STM32電子オルゴールVer1_2(残課題のサポート)

【前振り】
先般、STM32電子オルゴール をリリースしたが、そのときの残課題の「動的なキーの変更」、「SW操作、Sleepなどの操作系機能」、「コンプリ出力時のデッドタイム」をサポートした。


【動的なキーの変更】
①音源波形のサンプル飛び数に音符データの「キートランスポーズ」で指定された変更指数を乗じることで、キーを動的に変更する。

②変更指数は、1024でソングデータのキーのまま、256は2オクターブ高く、4096は2オクターブ低くする。

③動的なキーの変更は、次に変更されるか、曲の演奏が終了するまで継続して有効となる。


【SW操作、Sleepなどの操作系機能】
①オルゴールエンジン側の機能ではないが、固有処理でSW操作の検知により曲演奏や音声再生の開始と中止をする機能をサンプルとして提示した。詳細はダウンロードファイル中のソースコ-ド「orgel_STM32F030F4P6.c」を参照のこと。

②非稼働時は「Stop mode」でSleepしておき、SW操作をEXTIライン割り込みで検知してWakeupする。

③Sleep中の消費電流は実測5uAだった。


【コンプリ出力時のデッドタイム】
①STM32電子オルゴールの設計に掛かる前にPWM出力の実験を行ったが、そのときは、TIM1ではデッドタイムの設定以前の問題でPWM自体が出て来なくて挫折していた。取り敢えずTIM3を使っていたのだが、その後、ネットにある先達の事例を参考にさせていただいて、TIM1でも動作させることができた。多謝。

②足りなかったのは下記の設定だった。

 TIM1->BDTR|=TIM_BDTR_AOE; //自動出力可

・TIM1のような高機能制御タイマでは「BDTR」レジスタがあり、その「MOE」ビットをセットしないとPWM信号が出力されて来ない。「AOE」ビットをセットしておくと、次の更新契機に「MOE」ビットが自動的にセットされる。このことを学習した後で改めてデータシートを読むと以下の記述があった。
STM32電子オルゴールデータシート出力ステージ図
上図の右下部分に、出力制御にMOEビットが介在することが示されている。

CCERレジスタのCC1Eビットの説明にもMOEビットが介在することが書かれていた。
STM32電子オルゴールデータシートTIM1ー>CCERのCC1Eビット

比較として、TIM2のCCERレジスタのCC1Eビットの説明は下記となっている。
STM32電子オルゴールデータシートTIM2ー>CCERのCC1Eビット

・やはり、データシートは熟読しないといけない。

③STM32F030F4P6で使えるPWM出力チャネルは以下の通り。
STM32電子オルゴールPWMポート

・デッドタイム有りのコンプリ出力ができるのはTIM1のCH3とCH3Nのみであり、選択の余地はない。

・余談だが、TIM1_CH1Nは存在するが、TIM1_CH1は無い。ヘンな感じ。

④気持ちの問題で、ブリッジ出力とブレーキ出力もコンプリ出力に合わせてTIM1にした。そうすると、TIM1_CH3とTIM1_CH2を使うことになり、TIM1_CH2はデバグ情報出力ポートに使っているUSART1_TX(PA9)と被ってしまう。

・USART1_TXとの被りを避けるため、デバグ情報出力のUARTをソフト実装にして、今回はPA7に割り当てた。

⑤デッドタイムはBDTRレジスタのDTGビットの8ビットで設定する。データシートでの記述は以下の通り。
STM32電子オルゴールデータシートBDTRのDTSビット

・上記の設定方法は判り難いので、ファームウェアではPWMステップ数で指定できるように以下のマクロを定義した。
STM32電子オルゴールDTG設定マクロ

・デッドタイムを30[PWMステップ]に指定したときのPWM信号波形を示す。
STM32電子オルゴールコンプリ出力時のデッドタイム観測波形

 TIM1の入力クロックは48MHzであり、プリスケ無しのため

 デッドタイム=(1/48MHz)*30=0.625[us]

 となり、実測波形は計算値と合致する。

⑥PWM出力ポートの割り当てを変えたので、変更後の回路図を掲げておく。

テストベンチ
STM32電子オルゴール回路図テストベンチ新

外部メモリ無し
STM32電子オルゴール回路図外部メモリ無し新

SPIフラッシュメモリ(2線SPI接続)使用
STM32電子オルゴール回路図SPIメモリ新

I2Cフラッシュメモリ使用
STM32電子オルゴール回路図I2Cメモリ新


【ダウンロード】
設計資料とプロジェクト一式は ここから ダウンロードできる。

プロジェクトディレクトリは「orgel1_2」

プロジェクトは「demo_STM32F030F4P6.uvproj」

根のソースファイルは「demo.c」

データファイルのアセンブラソースファイルは「demo.s」

その他のソースファイルは上記の2つのソースファイルから#includeされる。


【残課題】
残課題は「ピッチベンド演奏」のみになったが、機能要件の検討から始めていて時間が掛かりそうだ。
  1. 2021/05/28(金) 18:21:57|
  2. 電子オルゴール+音声再生
  3. | コメント:0

STM32電子オルゴールVer1_2(設計情報「データの記述と制御表の連携」)

【前振り】
先般、STM32電子オルゴール をリリースしたが、その設計内容を著していきたい。今回は「データの記述と制御表の連携」について。


【データの記述言語】
今までの設計情報の記事で、データの記述がアセンブラであることにお気付きと思う。STM32への移植で、PICアセンブラからCへの書き替えがメリットだと言っておきながらアセンブラで書いているのは公約違反ではないかと言われ兼ねない。

当初は音声データも音符データもCで書いていたのだが、どうしても解決できない問題が生じて、仕方なくデータはアセンブラで記述せざるを得無くなった。それは、音符データ中の分岐先の記述である。音符データの配列の中でのオフセット(配列要素の番号)を解決するコーディング方法が見い出せなかった。もし、このブログの読者様でアイデアをお持ちなら是非ご教示いただきたい。

音符データを自動生成するようなアプリを作って、音符データ配列中のオフセットを解決すればよいのだが、そこまでの元気はない。音符データをアセンブラ記述するのであれば、音符データ以外のデータも横並びでアセンブラ記述にした。

分岐の記述例(アセンブラ)
STM32電子オル音符データ分岐記述


【制御表連携図】
STM32電子オルゴール制御表連携図


【ソースファイル連携図】
STM32電子オルゴールソースファイル連携図
  1. 2021/05/24(月) 18:37:16|
  2. 電子オルゴール+音声再生
  3. | コメント:0

STM32電子オルゴールVer1_2(設計情報「音声データ」)

【前振り】
先般、STM32電子オルゴール をリリースしたが、その設計内容を著していきたい。今回は「音声データ」について。


【音声インデックス】
音声再生に必要なデータの内容は、オルゴール演奏に比べて非常に簡単で、音声データ実体へのポインタとサンプリングレートなどを規定するのみだ。そのため、ソングデータのような属性情報を集約する枠組みは作らず、音声インデックスにそれらの情報を置いている。

音声インデックスの1エントリが1つの音声に対応する。プログラム上では音声インデックスのエントリ番号で音声を識別する。

プログラムフラッシュ、I2Cフラッシュ、SDカード、SPIフラッシュの音声データの所在によって、音声インデックスの枠組みが異なる。
STM32電子オルゴール音声Nインデックス
STM32電子オルゴール音声Iインデックス
STM32電子オルゴール音声Cインデックス
STM32電子オルゴール音声Sインデックス


【音声データ】
音声データは8ビットPCMデータで表す。

0x80がレベル0、0x00が負の最大値、0xffが正の最大値を示す。

長さの上限は下記のとおりである。

・プログラムフラッシュ 0x100000000[バイト]
・I2Cフラッシュ 0x10000[バイト]
・SPIフラッシュ 0x1000000[バイト]
・SDカード 0x100000000[ページ]

PWM周期が31.25usなので、サンプリングレートは32ksps以下で、その整数分の1であること。但し、PWM周期はカスタマイズにより5.33usまで短くできるので、そうすればサンプリングレートは最大187kspsまで高められる。
  1. 2021/05/24(月) 10:34:01|
  2. 電子オルゴール+音声再生
  3. | コメント:0

STM32電子オルゴールVer1_2(設計情報「ソングデータ」)

【前振り】
先般、STM32電子オルゴール をリリースしたが、その設計内容を著していきたい。今回は「ソングデータ」について。


【ソングデータ】
ソングデータは、曲に関する情報の根っことなる情報で、以下の内容を保有する。

パート共通情報
・キートランスポーズ関連情報
・テンポ関連情報

パート個別情報
・音符データ実体へのポインタ
・音源波形関連情報と波形データ実体へのポインタ
・エンベロープ波形関連情報と波形データ実体へのポインタ
・ピッチベンド波形関連情報と波形データ実体へのポインタ

STM32電子オルゴールソングデータの枠組み

ソングデータについてのヘッダ情報なので、「曲ヘッダ」と言っている。

音符データや各種波形データなど他の曲と共用する情報の実体に対しては、ポインタを持つことでデータ実体を重複保持しないようにしている。音符データの共用とは、例えば、同じ音符データを違った音源波形で演奏する場合は、それぞれのソングデータを作って、別の曲として扱う。ソングデータのメモリ量は

 8+20*パート数[バイト]

であり、違ったアレンジで複数の曲を作ってもあまり嵩張らない。

ソングデータの例(aoimeno)
STM32電子オルゴールソングデータ例aoimeno

【曲インデックス】
ソングデータへのポインタ配列で、1エントリが1つの曲に対応する。プログラム上では曲インデックスのエントリ番号で曲を識別する。
曲インデックス


【音源波形データ】
音源波形データは8ビットPCM形式で、音源波形の1サイクル分を用意する。

0x80がレベル0、0x00が負の最大値、0xffが正の最大値を示す。

サンプル数は256~1024の範囲であること。


【エンベロープ波形データ】
音源波形データは8ビットPCM形式で用意する。

0xffで最大音、0x00で消音となる。

サンプル数は65535まで。


【ピッチベンド波形データ】
ピッチベンド波形データは8ビットPCM形式で用意する。

0xffでピッチベンド最大変異、0x00で変異無しとなる。

サンプル数は65535まで。
  1. 2021/05/24(月) 07:51:04|
  2. 電子オルゴール+音声再生
  3. | コメント:0

STM32電子オルゴールVer1_2(設計情報「音符データ」)

【前振り】
先般、STM32電子オルゴール をリリースしたが、その設計内容を著していきたい。今回は「音符データ」について。


【音符データ】
音符データは曲毎に音符の数だけ定義するのでプログラムメモリが嵩張る。音符データの主要な情報は音価と音高であるが、これらはコード化して、必要な情報ビット数を少なくする。

音符コードのフィールド定義を以下に示す。
STM32電子オルゴール音符コードのフィールド定義

音符データのフィールド定義のExcelシートは、ダウンロードファイル「STM32電子オルゴールVer1\orgel1_2\ドキュメント\設計情報.xls」のシート「音符コード」にある。


【音高コード】

音高に対応する 再生周波数/サンプリングレート の値を音高テーブルに定義する。

再生周波数の値はオクターブ差により、2のべき乗で変化するので、音高テーブルは下記の12種類の音名について定義すればよく、オクターブ違いの音名の 再生周波数/サンプリングレート はシフト演算で算出することができる。
STM32電子オルゴール音高テーブル定義部分

音符データには、オクターブコードと音名コードをセットにして指定する。

例えば、音名「A4」は
STM32電子オルゴール音高テーブルA4

  オクターブコード=4
  音名コード=9

になる。

音名コードを数値で音符データに書くと人には判り難いので、実際のコーディングでは上記表の”コーディング”に示す記号、例えば「La」と書く。そのために、音名コードとコーディングの対応付けを下記の通りに定義しておく。

STM32電子オルゴール音名コーディング定義

音符に♯記号が付けば、音名コードは+1した値になる。コーディングでは「+1」を付加する。例えば、「La+1」と書く。

音符に♭記号が付けば、音名コードは-1した値になる。コーディングでは「-1」を付加する。例えば、「Laー1」と書く。

Siの♯ と Doの♭ は使ってはいけない。


【音価コード】

音価に対応する発音時間の値を音価テーブルに定義する。発音時間は4分音符を48とする相対値で表す。これは音価の分類の細かさと、その数値を8ビットに納めることの妥協点で決めた。
STM32電子オルゴール音価テーブル


音価コードを数値で音符データに書くと人には判り難いので、実際のコーディングでは記号、例えば「K4」と書く。そのために、音価コードと記号の対応付けを下記の通りに定義しておく。

STM32電子オルゴール音価コーディング定義


【リピート制御】
先にリピート回数を設定しておき、リピート分岐で曲の進行を制御する。

リピート分岐は、リピート回数をデクリして0にならなかったら指定位置へ分岐する。
0になったら分岐せず、次の音符へ進む。
リピート回数とリピート分岐は3種類まで設定でき、入れ子になっても構わない。

無条件分岐も可能とする。


【その他の演奏表現】
下記の制御値を演奏中に動的に変更可能とする。

・ベロシティ
・エンベロープ処理の変化速度
・テンポ
・ピッチベンド処理の変化速度
・キートランスポーズ

これらは、ソングデータで設定された値を音符データで指定された比率で増減することで、波形生成処理に作用させる。


【音符データの設定用マクロ】

音符データの設定例として「aoimeno」の先頭部分を以下に示す。

align 4
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;青い目の人形(作曲:本居 長世)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;パート0の音符データテーブル
;
AOIMENO0_onpu_tbl
vel_mac 171 ;ベロシティ設定
env_mac 0,25 ;エンベロープタイム設定

rp1_mac 2 ;リピート1 回数設定

AOIMENO0_onpu_tbl_0_1
;0-1 ドド
onp_mac 0,K2,6,Do
onp_mac 0,K2,6,Do


上記のように音符データの設定は、設定用のマクロを使って記述する。人に判り易いことと、今後の仕様変更に対する対応をし易くするためだ。

下記のマクロを定義している。

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;修飾コードの定義
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
TIE equ 4 ;タイ演奏


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;音符データ生成マクロ
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;++++++++++++++++++++++++++++++++++++++++++++++++
;SONGヘッダのキートランスポーズ値変換マクロ
; パラメータ:キートランスポーズ比率(256~4096)[1024基準]
;  (1024のとき既定の再生周波数、256のとき2オクターブ上、4096のとき2オクターブ下、となる)
; 設定値:パラメータの値をそのまま設定する
;++++++++++++++++++++++++++++++++++++++++++++++++
macro
kts_mac $aaa
dcw $aaa
mend

;++++++++++++++++++++++++++++++++++++++++++++++++
;SONGヘッダのテンポ値変換マクロ
; パラメータ:テンポ100に対する比率[1/100](つまり楽譜のテンポの値そのもの)
; 設定値:音価処理プリスケール値
;  音価処理プリスケール値は、音価の基本単位にしている4分音符の1/48の時間を
;   演奏処理周期をベースに作るためのプリスケール値
;  =60*1000000us/(テンポ)/48/((PWM_PR/100)*SONG_PS)
;++++++++++++++++++++++++++++++++++++++++++++++++
macro
ops_mac $aaa
dcw (600000000/$aaa*100/48/PWM_PR/SONG_PS+5)/10
mend

;++++++++++++++++++++++++++++++++++++++++++++++++
;リピート0回数設定マクロ
; パラメータ:リピート0回数
;++++++++++++++++++++++++++++++++++++++++++++++++
macro
rp0_mac $aaa
dcw 0x8c00+$aaa
mend

;++++++++++++++++++++++++++++++++++++++++++++++++
;リピート0分岐マクロ
; パラメータ:リピート0分岐先の音符データテーブルオフセット値
;++++++++++++++++++++++++++++++++++++++++++++++++
macro
jp0_mac $aaa
dcw 0x9000+($aaa)/2
mend

;++++++++++++++++++++++++++++++++++++++++++++++++
;リピート1回数設定マクロ
; パラメータ:リピート1回数
;++++++++++++++++++++++++++++++++++++++++++++++++
macro
rp1_mac $aaa
dcw 0x8d00+$aaa
mend

;++++++++++++++++++++++++++++++++++++++++++++++++
;リピート1分岐マクロ
; パラメータ:リピート1分岐先の音符データテーブルオフセット値
;++++++++++++++++++++++++++++++++++++++++++++++++
macro
jp1_mac $aaa
dcw 0x9400+($aaa)/2
mend

;++++++++++++++++++++++++++++++++++++++++++++++++
;リピート2回数設定マクロ
; パラメータ:リピート2回数
;++++++++++++++++++++++++++++++++++++++++++++++++
macro
rp2_mac $aaa
dcw 0x8e00+$aaa
mend

;++++++++++++++++++++++++++++++++++++++++++++++++
;リピート2分岐マクロ
; パラメータ:リピート2分岐先の音符データテーブルオフセット値
;++++++++++++++++++++++++++++++++++++++++++++++++
macro
jp2_mac $aaa
dcw 0x9800+($aaa)/2
mend

;++++++++++++++++++++++++++++++++++++++++++++++++
;無条件分岐マクロ
; パラメータ:分岐先の音符データテーブルオフセット値
;++++++++++++++++++++++++++++++++++++++++++++++++
macro
jmp_mac $aaa
dcw 0x9c00+($aaa)/2
mend

;++++++++++++++++++++++++++++++++++++++++++++++++
;ベロシティ配分値設定マクロ
; パラメータ:ベロシティ配分値[1/256](最大値は256で、全パートの合計が256以下になること)
;++++++++++++++++++++++++++++++++++++++++++++++++
macro
vel_mac $aaa
dcw 0xa000+$aaa
mend

;++++++++++++++++++++++++++++++++++++++++++++++++
;エンベロープ設定マクロ
; パラメータ:エンベロープ処理プリスケール値変更指数
;++++++++++++++++++++++++++++++++++++++++++++++++
macro
env_mac $aaa,$bbb
dcw 0xb000+$aaa*512+$bbb
mend

;++++++++++++++++++++++++++++++++++++++++++++++++
;テンポ設定マクロ
; パラメータ:音価残評価処理プリスケール値変更指数
;++++++++++++++++++++++++++++++++++++++++++++++++
macro
tmp_mac $aaa
dcw 0xc000+$aaa-1
mend

;++++++++++++++++++++++++++++++++++++++++++++++++
;ピッチベンド設定マクロ
; パラメータ:ピッチベンド処理プリスケール値変更指数
;++++++++++++++++++++++++++++++++++++++++++++++++
macro
pit_mac $aaa,$bbb
dcw 0xd000+$aaa*512+$bbb
mend

;++++++++++++++++++++++++++++++++++++++++++++++++
;キートランスポーズ設定マクロ
; パラメータ:キートランスポーズ変更指数
;++++++++++++++++++++++++++++++++++++++++++++++++
macro
key_mac $aaa
dcw 0xd000+$aaa-1
mend

;++++++++++++++++++++++++++++++++++++++++++++++++
;通常音符設定マクロ
; パラメータ:修飾コード、音価コード、オクターブコード、音名コード
;++++++++++++++++++++++++++++++++++++++++++++++++
macro
onp_mac $aaa,$bbb,$ccc,$ddd
dcw $aaa*0x1000+$bbb*0x80+$ccc*0x10+$ddd
mend

;++++++++++++++++++++++++++++++++++++++++++++++++
;音符終了設定マクロ
;++++++++++++++++++++++++++++++++++++++++++++++++
macro
onp_end
dcw 0
mend
end
  1. 2021/05/22(土) 20:07:00|
  2. 電子オルゴール+音声再生
  3. | コメント:0

STM32電子オルゴールVer1_2(設計情報「音高と音価」)

【前振り】
先般、STM32電子オルゴール をリリースしたが、その設計内容を著していきたい。先ずは「音高と音価」について。


【音高】
音高は再生周波数に対応し、その範囲は110~3960Hzとする。110Hz以下は小型スピーカでの再生限界であるのと、3960Hzは8kspsでの再現上限であるから。

但し、標本化定理では8kspsの場合は4kHz以上の周波数成分を含まないことが前提条件なので、高調波を含む音源では基本波の上限周波数はずっと低くなる。

例えば、矩形波は奇数次高調波を多く含むが、5次高調波までを含まないと矩形波に近付いて来ない。そうすると、矩形波の場合は、その基本波の周波数の上限値は800Hzになってしまう。これでは再生できる音域が狭くなってしまうので、実際には折り返しノイズが発生して音質が悪化することを容認して、再生周波数を高くするしかない。

音高と再生周波数の対応は下記のとおり。
STM32電子オルゴール音高テーブル
上表で、黄色部分は国際的な規定で、ピンク部分は僕の設計都合で決めた値。

再生周波数の表記上の分解能は0.05Hzで良いことが判る。

上図のExcel表は、ダウンロードファイル「STM32電子オルゴールVer1\orgel1_2\ドキュメント\設計情報.xls」のシート名「音高コード」にある。


【音源波形サンプル数】
音源波形は基本周期1サイクル分の波形データとする。正弦波であれば1/4サイクル分で十分だが、自然音を含む様々な音源を使用可能とするため、丸1周期分用意する。

110Hzの音源1サイクル分のサンプル数は8kspsで

  8ksps/110Hz=72.7サンプル

欲張って16kspsにすると

  16ksps/110Hz=145.5サンプル

となる。これはサンプルデータの精度を落とさないために最低限必要なサンプル数である。

しかし、生ピアノのような自然音源を使う場合は低調波が含まれるため、設計上のサンプル数上限は多めにして1kサンプルとする。

波形合成で作った音源ではサンプル数を整数にできるが、自然音源を使う場合は採取した音源の周波数とサンプリングレートは整数比に合わせられないので、サンプル数は整数未満の端数が生じる。そのため、サンプル数は端数を表現できる必要がある。

サンプル数の誤差は再生周波数の誤差になるので、許容誤差を0.2セントとすると誤差率は

  誤差率=(1/16)*(0.2/100)=1/8000

となり、必要な精度は13ビットとなる。サンプル数の最小値を128とすると、整数部7ビット+端数部6ビットとなる。サンプル数は最大1kとするので、整数部10ビット+端数部6ビットとなる。

この試算は、必要ビット数を切りの良い16にするという意図も働いて、許容誤差を0.2セントとしている。なお、一般人の聴感では5セントの誤差で違和感を感じるそうだ。

この精度はサンプル飛び数とサンプルオフセットにも適用される。


【サンプル飛び数】
サンプル飛び数は以下の式で求められる。

  サンプル飛び数=サンプル数*(再生周波数/サンプリングレート

ここで、サンプル数は音源データにより異なるので、音源毎=演奏曲毎に変わる。曲に対して音源は固定なので、演奏中はサンプル数は固定値である。

再生周波数は音符データの音高の指定値で決まる。

サンプリングレートは波形生成処理の実行レートで8kspsを標準とし、コンパイル時に確定し、定数である。

従って、音高コードに対応する 再生周波数/サンプリングレート の値を音高テーブルに定数として持ち、これに波形生成処理実行時にサンプル数を乗じてサンプル飛び数を求める。音高テーブルは全曲で共通となる。

再生周波数/サンプリングレート の値は、標本化定理により0.5未満でなければならない。

サンプル飛び数の計算結果が32ビットに収まるためには、サンプル数が16ビットであるため、 再生周波数/サンプリングレート は16ビットを充てられる。MSBの重みは0.25である。

音高テーブルは最高オクターブの12音名(再生周波数が2112~3960)について定義し、それより低い再生周波数については音高テーブルの同じ音名の値をオクターブ数だけ左シフトして求める。

キートランスポーズやピッチベンド演奏は、上式で得られたサンプル飛び数を音符データで指定された比率で動的に増減することで実現する。

具体的な設定値は、例えば

  再生周波数=3960Hz
  PWM周期=31.25us
  処理実行プリスケール値=4

のとき

  再生周波数値*PWM周期*処理実行プリスケール値

   =3960[Hz]*31.25[us]*4

   =0.495

テーブルへの設定値は、0.495*(2^17)=0xfd71となる。


【音価】
音価は再生音の発声時間に対応する。その発声時間は8ビットで表すこととし、3連符の表現を可能とするため3*(2のべき乗)での最大値は192となる。これを全音符とすると最小値は2=3連32分音符、3=64分音符となる。

音高に対する発声時間を音価テーブルに持ち、全曲に共通の定義となる。
STM32電子オルゴール音価テーブル

Excelシートは、ダウンロードファイル「STM32電子オルゴールVer1\orgel1_2\ドキュメント\設計情報.xls」のシート「音価コード」にある。

テンポは曲ごとに異なるので、発声時間の単位値とテンポとの対応は音価カウントのプリスケール値を曲毎に定義する。

発声時間の評価周期は曲演奏処理周期(=波形生成のサンプリング周期)をプリスケールして作る。

  波形生成のサンプリング周期=PWM周期*処理実行プリスケール値

  PWM周期値は PWM_PR[1/100us] 範囲100~3200(1~32us)
  処理実行プリスケール値は SONG_PS 範囲1~4

テンポ値は60秒間の4分音符の数であることから

  テンポ値=TEMPO とすると

  音価単位値の時間=60[s]/TEMPO/48

  プリスケール値=音価単位値の時間/サンプリング周期

   =60[s]/TEMPO/48/(PWM周期値/100/(10^6)*処理実行プリスケール値)

   =60*(10^8)/48/TEMPO/PWM周期値/処理実行プリスケール値

例えば、TEMPO=100、波形生成のサンプリング周期=125usとすると

  プリスケール値=6000000000/48/3125/4=100

となる。TEMPの可変範囲を0.5~2とし、処理実行プリスケール値の可変範囲を0.5~2とすると、プリスケール値は16ビット必要である。

テンポの動的変更は、上式で得られたプリスケール値を音符データで指定された比率で動的に増減することで実現する。


【PWM周期】
PWM周期は、演奏処理のベールタイマーとなり、下記式で決まる。

 PWM周期=PWMステップ数/TMRクロック

現行の設定値は、PWMステップ数=1500、TMRクロック=48MHzとなっているため

 PWM周期=1500/48MHz=31.25us

となっている。

オルゴール演奏のみ実行の場合はカスタマイズにより、PWMステップ数を256まで小さくしても量子化ノイズへの影響は無いので、そうするとPWM周期は5.33usまで短くでき、波形生成処理のサンプリングレートを187kspsまで高められる。
  1. 2021/05/21(金) 08:06:27|
  2. 電子オルゴール+音声再生
  3. | コメント:2

STM32電子オルゴールVer1_2(オルゴール演奏機能のサポート)

【前振り】結果
STM32の電子オルゴールとして、先般は 音声再生機能のみのバージョン(Ver1_1) を公開した。オルゴール演奏機能が無い電子オルゴールってヘンな話だったのだが、漸く、オルゴール演奏の機能がサポートできたので、Ver1_2としてリリースする。


【演奏音】
サンプル曲は糸魚川の渡辺Dr.がアレンジされた「青い目の人形」で、電子オルゴールの表現力を最大限引き出してくれている素晴らしい作品だ。多謝。
STM32電子オルゴールaoimeno


【設計方針】
PIC電子オルゴールの処理方式を踏襲してCへ書き替えるが、STM32の能力を十分に活かす。

①乗算処理

・PICではソフト乗算のためビット数を絞った処理を行っていたが、STM32には32ビットの乗算命令があるので、音源波形のサンプリングやエンベロープ処理で制御データのビット数を多くとり、精度を高める。

・例えば、音源波形データのオフセットが16ビットの精度であると、再現周波数は最良時で約0.025セントの確度となる。再現周波数の範囲が5オクターブであると、最悪でも0.64セントとなり、一般人の聴感覚で差異が感じられるとされる5セントに対して十分な確度が得られる。

・PICでは3パートまでの演奏が実用範囲であったが、STM32では更に拡張することができる。

②PWMステップ数

・PICではPWMのタイマークロックが32MHzであるが、STM32では48MHzであり、同じPWM周期でもステップ数を1.5倍確保できる。

・PWM周期を31.25us、ステップ数1500とする。各chのステップ数の合計が1500に拡大できる。

③ワードサイズ

・PICではプログラムメモリが14ビット/ワードであり、音符データは14ビット、波形データは7ビットで表現していたが、STM32では16ビット/ワードであり、音符コードは16ビット、波形データは8ビットで表現する。

演奏データはPIC電子オルゴールで保有しているものから移植するが、取り敢えず、「ANNI」と「AOIMENO」の2曲を評価用に作成する。

④配列処理

・STM32はレジスタが比較的多いので、PICでは苦手な配列やポインタの処理が効率的に実行できる。そのため、パート処理や音声再生処理のchを配列構造にして、ソースコードをスマートにする。これは極フツウのことなのだが、PICでは配列・ポインタ処理が非常に嵩張り、メモリ不足とCPU不足を起こして実用にならなかった。

⑤プログラムフラッシュのアクセス

・STM32ではプログラムフラッシュに置いたデータに用意にアクセスできる。これも極フツウのことなのだが、PICでは特別なCPU機能を使わないとアクセスできず、CPU負荷となっていた。

具体的な設計内容については、今後、別記事を書いていく予定だ。


【設計】
ファームウェアの具体的な設計内容は下記を参照。

音高と音価

音符データ

ソングデータ

音声データ

データの記述と制御表の連携

残課題「動的なキーの変更」、「SW操作、Sleepなどの操作系機能」、「コンプリ出力時のデッドタイム」のサポート

STM32F030K6T6のサポート

GPIO割り込み

ピッチベンドのサポート

【動作環境】
①テストベンチ

・既存のPIC電子オルゴールのテストベンチを共用する。
STM32電子オルゴールテストベンチ表

STM32電子オルゴールテストベンチ裏

バス切り替えジャンパー設定
STM32電子オルゴールテストベンチ配線ジャンパー設定

・PIC電子オルゴールのテストベンチと接続するために、8ピンPICのピン接に変換するためのヘッダを装備する。

注)その後、コンプリ出力のサポート時にポートの割り当てを変更した ので、下記の回路図は最新のファームウェアと整合しなくなった。
STM32電子オルゴール回路図テストベンチ
STM32電子オルゴール基板表
STM32電子オルゴール基板裏

合体した様子
STM32電子オルゴール基板合体

②回路図

注)その後、コンプリ出力のサポート時にポートの割り当てを変更した ので、下記の回路図は最新のファームウェアと整合しなくなった。

外部メモリ無し
STM32電子オルゴール回路図外部メモリ無し

SPIフラッシュメモリ(2線SPI接続)使用
STM32電子オルゴール回路図SPIメモリ

I2Cフラッシュメモリ使用
STM32電子オルゴール回路図I2Cメモリ


【ソフト開発】
①uVision V5.31.0.0を使っている。
STM32電子オルゴールuVision情報

②設計資料とプロジェクト一式は ここから ダウンロードできる。

プロジェクトディレクトリは「orgel1_2」

プロジェクトは「demo_STM32F030F4P6.uvproj」

根のソースファイルは「demo.c」

データファイルのアセンブラソースファイルは「demo.s」

その他のソースファイルは上記の2つのソースファイルから#includeされる。


【残課題】
以下の機能は未サポートである。

・ピッチベンド演奏
・動的なキーの変更
・SW操作、Sleepなどの操作系機能
・コンプリ出力時のデッドバンド

最も大きな問題点は、STM32F030の価格が高騰していること。STM32を触り始めた去年の秋はAliExpressでの入手価格が@50円以下(配送無料)だったので、おもちゃ修理に使えると思った。しかし、現在では、配送料込みで200円超えにもなっていて、おもちゃ修理には使えなくなってしまった。しかし、処理をCに書き替えたので、今後廉価なCPUが出てくれば移植は比較的容易と思う。現時点では秋月のSTM32L010F4P6(@95円)が次善の選択と思う。
  1. 2021/05/20(木) 08:36:21|
  2. 電子オルゴール+音声再生
  3. | コメント:0

STM32電子オルゴールVer1_1(途上版のリリース)

【前振り】
STM32の初プロジェクトとして 音声再生を公開 したが、STM32を弄り始めたのはPIC電子オルゴールに代わる高性能な電子オルゴールの製作だった。その目標はまだ途上なのだが、音声再生機能ができたので公開する。現時点ではオルゴール機能の無い電子オルゴールだが、オルゴール機能は鋭意開発中だ。

【設計】
PIC電子オルゴールはCPUが遅いため音声再生とコンカレントに動作すると

・演奏のパート数が2(PART_N=2)までしか実用にならない。

・音声再生のサンプリングレートが8ksps(SONG_PS=4)までに制限される。

STM32のCPUクロックは48MHzであり、PIC16に比べて6倍にもなる。また、乗算命令があり、演奏処理でのPCM値計算が高速に実行できる。この高速性を活かして

・演奏のパート数を4に上げる。

・演奏の産プリンレートを16kspsに上げる。

・音声再生のサンプリングレートを16kspsに上げる。

・PWM分解能を1500ステップに拡大して、演奏と音声再生の波形合成で量子化ノイズの発生を抑える。

次の機能はPIC電子オルゴールと同等以上にサポートする。

・BTL(シングル・コンプリ・ブリッジ・ブレーキ)出力。但し、現時点ではデッドバンドは未サポート。

・音声データはプログラムフラッシュ・I2Cフラッシュ・SPIフラッシュ・SDカードに格納。

・音源(演奏・音声再生)のチャネル毎の音量の設定。

・2線でのSPI通信。

・演奏と音声再生の開始・中断、終了時のコールバック等のAPI機能。

【ダウンロード】

STM32電子オルゴールの設計資料と開発プロジェクトは ここから ダウンロードできる。uVISIONのプロジェクトディレクトリは orgel1_1。

【躓いていること】
PWMのコンプリ出力でのデッドバンドのサポートはTIM1でできるそうだが、TIM3と同じようにやってもPWM信号が出て来ない。有識者からの指南をいただければ有難い。実験中のプロジェクトはダウンロードファイル中の orgel_PWM。
  1. 2021/01/27(水) 21:47:37|
  2. 電子オルゴール+音声再生
  3. | コメント:0

PIC電子オルゴールVer6_3のバグ改修(IOC設定関連)

【前振り】
PIC電子オルゴールのサンプルプロジェクトの多くは非稼働時はIOC割り込みを仕掛けてSleepさせているのだが、その処理にとんでもないバグがあった。

【バグの内容】
改修前のコード
PIC電子オルゴールVer6_3のバグ改修(IOC設定関連)改修前

先ずは、IOC設定の前に行っている「ポートの空読み」だが、これは不要だ。僕の遠い記憶では、「IOCは直近の読み込み値との比較」であるので事前にポートを空読みしておく必要があると思っていた。改めてデータシートを確認したら、そのような記述は見当たらなかった。しかし、僕は何故ずっとそう思っていたのだろうと他のデータシートを見たら、12F629には「IOCは直近の読み込み値との比較」としっかりと書かれていた。また、「GPIOを読み直すことでIOCフラグがクリアされる」とのことだ。
PIC電子オルゴールVer6_3のバグ改修(IOC設定関連)12F629IOC
レガシーなデバイスではそうだったのだ。僕はIOCを理解していなかった。。。

PIC電子オルゴールでサポートしているデバイスは16F18xx以降なので「ポートの空読み」は必要無かった。

致命的なバグは、PIC電子オルゴールでは割り込みが許可された状態(GIEがセット)で動作しているにも関わらず、いきなり「IOC割込みを許可」していること。「IOC検出表示をクリア」してからsleep命令が実行されるまでの2命令サイクルの時間内に実際にIOCが発生すると割込み処理へ分岐してしまう。ところがIOC割り込み処理を用意していないのでIOC割り込みフラグがクリアされることなく、割り込み処理が無限に繰り返されることになる。

もう一つのバグは、SWがオンの状態でSleep処理に入ってくるとWakeupしないことだ。SWがオフであったからこそSleep処理へ飛んできたのだが、メインループでSWのオフを判定してからSleep処理へ飛んでくる間にオンになった場合に発生する。SWのチャタリングの発生具合によっては発生し得る。これは、蚊蜻蛉さん に指摘されて気が付いた。多謝。

改修後のコード
PIC電子オルゴールVer6_3のバグ改修(IOC設定関連)改修後

上記のように、Sleepへ移行する前には、「割込みを禁止(GIEをクリア)」してから「IOC割込みを許可」するようにした。Wakeup後には、「IOC割込みを禁止」してから「割込み許可(GIEをセット)」する。

「ポートの空読み」をやめて、SWがオン状態であった場合はSleepしないで戻るようにした。上記のコードでSWのオフを確認してからsleep命令が実行されるまでの間にオンになった場合はIOCフラグがセットされるのでsleep命令からすぐに戻ってくる。

【ダウンロード】
バグ修正は完了していて、公開ファイルは修正後のものに入れ替え済みである。
orgel6_3は ここから ダウンロードできる。

【余談】
改修前のコードで、sleep命令で休止中は割り込みが許可されているので、IOCが発生すると割り込み処理へ分岐するように見えるが、実際には分岐しない。

例えば、12F1822のデータシートでは
PIC電子オルゴールVer6_3のバグ改修(IOC設定関連)SLEEP中の割り込み
「sleep命令の直後の命令はISRへ分岐する前に必ず実行される」となっている。修正前のコードではsleep命令の直後の命令は「IOC割込みを禁止する」命令であり、それが実行されるので割り込み処理へは分岐しないことになる。

試しに、下記のようにsleep命令の後にnop命令を入れると、割り込み処理がループしてダンマリになる。
PIC電子オルゴールVer6_3のバグ改修(IOC設定関連)割り込みダンマリ実験
  1. 2021/01/15(金) 23:32:40|
  2. 電子オルゴール+音声再生
  3. | コメント:1

PIC電子オルゴールVer6_3のリリース(2線SPIのサポート完了)

【前振り】
先般は、「2線SPI」を PIC電子オルゴールに適用 した。但し、極一部のプロジェクトだけだった。その後、適用範囲を広げていき、全プロジェクトへの横展開が終わった。

【設計】
対応済みプロジェクトでのやり方を他のプロジェクトへコピペすればよいので大半が単なる力仕事だ。しかし、RFIDを使ったプロジェクトでは RFID-RC522 もSPIで繋いでいるので、これにも2線SPIを適用する。これが今回の課題だ。

MFRC522のデータシートでは
PIC電子オルゴールVer6_3のリリース(2線SPIのサポート)MFRC522のSPI-1
PIC電子オルゴールVer6_3のリリース(2線SPIのサポート)MFRC522のSPI-2

となっていて、W25QやSDCと同じようにMOSIとMISOをPICの同じポートで制御する前提で、それぞれの信号のやり取りができる。

下記の回路と処理手順で 「2線SPI」 での送受信の同時進行が可能である。

回路図
PIC電子オルゴールVer6_3のリリース(2線SPIのサポート)回路図RC522

処理手順
①PICのポートにMOSIを出力し、セットアップ時間後にSCKを立ち上げる。

②PICのポートを入力モードに切り替えてMISOを取り込む。

③SCKを立ち下げる。

ソースコード
PIC電子オルゴールVer6_3のリリース(2線SPIのサポート)ソースコードRC522
PIC電子オルゴールVer6_3のリリース(2線SPIのサポート)ソースコードRC522-2

【評価】
RFID-RC522とのSPI信号を観測して、送受信の同時進行を確認した。
PIC電子オルゴールVer6_3のリリース(2線SPIのサポート)RC522波形1
PIC電子オルゴールVer6_3のリリース(2線SPIのサポート)RC522波形2

【ダウンロード】
orgel6_3は ここから ダウンロードできる。

プロジェクト名にデバイス名が盛り込まれている。例えば、orgel_1572 のターゲットデバイスは 12F1572 である。

TOUCHが付くものは タッチSWで操作するもの
MTOUCHが付くものは タッチSWで操作するもので、マルチタッチを識別するもの
RFIDが付くものは RFID-RC522を接続して非接触ICタグで操作するもの
CdSが付くものは CdSで操作するもの

下記の宣言で「RFID-RC522との2線SPI」が実装される。なお、RFID-RC522とのSPIはソフト実装であることが前提となっている。
PIC電子オルゴールVer6_3のリリース(2線SPIのサポート)RC522のSPI2宣言
  1. 2021/01/05(火) 18:45:03|
  2. 電子オルゴール+音声再生
  3. | コメント:0

PIC電子オルゴールVer6_3のリリース(2線SPIのサポート)

【前振り】
先般は、「2本でSPI」を 「PICで音声再生」 と 「2.4GHzラジコン用ファームウェア」 に適用した。そうすると次は 「PIC電子オルゴール」 となるのが自然だ。エンジン部のSPI処理を変更することになるので、「2線SPI」サポート版はバージョンをVer6_3に進めた。

【設計】
「PICで音声再生」と「2.4GHzラジコン用ファームウェア」では共にSPI通信を送信と受信に分けて別々に実行している。2.4GHzトランシーバとSPIフラッシュメモリではそれでよいのだが、「PIC電子オルゴール」ではSDメモリカード(以下SD)をサポートしていて、SDではデータ要求のときには送受信を同時に実行するインタフェースが必要である。データ要求のときにSDへ送るダミーデータは0xffでないといけないと言うことだ。

SPIフラッシュメモリのSPIインタフェース
PIC電子オルゴールVer6_3W25QのSPI

SDのSPIインタフェース
SD Card Associationの「Physical Layer Simplified Specification」を見てもSPI信号のタイミングは判明しなかった。
そのため、ルネサスの「ADJ-603-002B(O)マルチメディアカード ユーザーズマニュアル」から下記の情報を得た。
PIC電子オルゴールVer6_3のリリース(2線SPIのサポート)SDのSPI

MOSIとMISOをPICの同じポートで制御する前提で、SCKのH期間とL期間で送信と受信のフェーズを分けてそれぞれの信号のやり取りができる。

下記の回路と処理手順で「2線SPI」での送受信の同時進行が可能である。

回路図
PIC電子オルゴールVer6_3のリリース(2線SPIのサポート)回路図W25Q
PIC電子オルゴールVer6_3のリリース(2線SPIのサポート)回路図SD

処理手順
①PICのポートにMOSIを出力し、セットアップ時間後にSCKを立ち上げる。

②PICのポートを入力モードに切り替えてMISOを取り込む。

③SCKを立ち下げる。

ソースコード
PIC電子オルゴールVer6_3のリリース(2線SPIのサポート)ソースコード

【評価】
SDへデータ要求するときのSPI信号を観測して、送受信の同時進行を確認した。

4線SPI(12F1572)
PIC電子オルゴールVer6_3のリリース(2線SPIのサポート)波形4線SPI(1572)
MOSIで送信するダミーデータは0xff、MISOにはSDから音声PCMデータが返ってきている。

2線SPI(12F1572)
PIC電子オルゴールVer6_3のリリース(2線SPIのサポート)波形2線SPI(1572)
SCKの立ち上がり時点でMOSIで送信するダミーデータが確定していて、0xffとなっている。
MISOにはSDから音声PCMデータが返ってきている。
SSはLに張り付いている。

内蔵MSSPモジュール(16F1705)
PIC電子オルゴールVer6_3のリリース(2線SPIのサポート)波形内蔵MSSPモジュール(1705)

SPIフラッシュメモリからの2線SPIでの音声再生も動作確認した。

【ダウンロード】
orgel6_3は ここから ダウンロードできる。

プロジェクト名にデバイス名が盛り込まれている。例えば、orgel_1572 のターゲットデバイスは 12F1572 である。

現在は、下記のプロジェクトのみが「2線SPI対応」となっている。他のプロジェクトへの横展開はボチボチ進めて行く。当ブログの読者からご要望があれば優先して対応を検討する。

orgel_1572.X
orgel_1705.X

下記の宣言で「2線SPI」が実装される。なお、「2線SPI」は内蔵MSSPモジュールを使用する場合は実装できない。
PIC電子オルゴールVer6_3のリリース(2線SPIのサポート)SPI2宣言
  1. 2020/12/14(月) 12:09:58|
  2. 電子オルゴール+音声再生
  3. | コメント:0

STMで音声再生の改善(STOPモードで待機)

【前振り】
この頃はSTM32を弄っていて、先日は STMで音声再生 を公開した。
STM32で低電力モード設定のやり方が解ったので、STMで音声再生 に適用した。


【設計】
STM32の低電力モードは「STOPモード」と「STANBYモード」がある。

①「STANBYモード」は待機電流が実測2uAと省電力だが、Wakeupの手段が限られていて、SRAMとレジスタの内容は失われる。つまり、リセットと同等の結果になる。また、リセットでしか動作を再開できない。

②「STOPモード」は実測18uAの待機電流が流れるが、外部割り込み(ピン変化割り込み)でWakeupし、STOPモードに入る前の状態で処理を再開できる。但し、システムクロックは初期化される。

③「STOPモード」で、更に「レギュレータ低電力モード」に設定すると実測8uAとなった。

音声再生での応用では、音声を選択するボタンの操作によってWakeupしなければならないので、上記③の「STOPモード」+「レギュレータ低電力モード」を採用する。

この開発の過程で、待機時の消費電流を極小化するための方策が見えて来た。

・「STOPモード」への移行によりシステムクロックが停止するので、事前に周辺機能へのクロックを断つ操作は不要である。

・GPIOポートは入力モードでプルアップまたはプルダウンするか、アナログ設定すると待機時電流が激減する。(常識)

・Wakeup後は、PLLが無効になりシステムクロックがHSI8MHzに変わる。クロック設定を元に戻すためにSystemInit()を呼び出す必要がある。

処理の流れは以下とした。

・音声選択ボタンがオンなら、該当する音声を再生する。

・音声選択ボタンがオフなら「STOPモード」に入る。

・「STOPモード」中に音声選択ボタンがオンされたら、外部割り込みでWakeupし、システムクロックを再設定する。


【実装】
STOPモード設定
STMで音声再生の改善(STOPモードで待機)STOPモード設定

STOPモードへの移行
STMで音声再生の改善(STOPモードで待機)STOPモードへの移行

外部(ピン変化)割り込み設定
STMで音声再生の改善(STOPモードで待機)外部割り込み設定

外部(ピン変化)割り込みハンドラ
STMで音声再生の改善(STOPモードで待機)外部割り込みハンドラ

稼働中の消費電流は14mA、STOPモード中は8uAになった。

STOPモード中はピン変化にてWakeupし、音声再生を実行することを確認した。

【ダウンロード】
設計資料と開発プロジェクトは ここから ダウンロードできる。
  1. 2020/11/05(木) 21:09:45|
  2. 電子オルゴール+音声再生
  3. | コメント:0

STMで音声再生

【前振り】
STM32を使った初のファームウェアとして、音声再生を作った。

STM32F030K6T6の32kBのフラッシュメモリを活かして、フラッシュメモリに置いたPCMデータをPWMで出力する。ただそれだけなので32ビットコアを活かしたものではないが、50円で4秒間の音声が再生できる。


【設計】
①ターゲットはSTM32F030K6T6。システムクロックはHSI48MHzとする。

②PCMデータは8ビット8kspsとする。

③TIM3クロック入力は、PCLK(48MHz)を6分周して8MHzとする。

④PWMステップ数を255とし、PWM周期は255/8MHz=31.875usとなる。

⑤TIM3更新割込みをソフトで1/4に間引きして、デューティ更新周期は127.5usとする。8ksps(125us)と若干誤差が発生するが無視する。

⑥フラッシュメモリは32kBしかないので、音声データもプロジェクト内に置いて、コードとデータを合わせて32kB以内とする。

⑦コードは高々2kBなので、音声データは30kB分格納できる。orgel6_2のミラーナ音声から30kB分を流用する。

・結果として、「キラキラおめめかわいいでしょう」と「えがおがステキ」の2言を収容した。

・PA4とPA5のL検出により、それぞれの音声を再生開始する。


【PWM波形】
STMで音声再生PWM波形1
設計通りのタイミングで出力されている。

STMで音声再生PWM波形2
PWMの4周期毎にデューティが更新されている。


【再生音】
8ビット8kspsでのPWM出力を録音したもの。
再生音


【ダウンロード】
設計資料と開発プロジェクトは ここから ダウンロードできる。
  1. 2020/11/01(日) 20:13:14|
  2. 電子オルゴール+音声再生
  3. | コメント:0
次のページ

プロフィール

大泉茂幸

Author:大泉茂幸
名張市つつじが丘おもちゃ病院
名張市つつじが丘南3番町129
mailto:tutuji@cb4.so-net.ne.jp

子どもの頃から趣味は電子工作一筋でやってきました。理科離れが進む中で科学技術に興味を持つ子どもが少しでも増えて行くことを願って、子ども達に電子工作の活動の場を提供しています。

1981年からおもちゃ病院の活動を始め、2014年に三重県名張市への移住を機に「つつじが丘おもちゃ病院」を開院しました。自分でおもちゃを設計し製作する【おもちゃ工房】と、マイコンを応用した電子工作を楽しむ【マイコンクラブ】も併設しています。新規参加メンバーを募集しています。

当ブログで公開している技術情報や成果物の複製、改変および再配布はフリーです。読者様のおもちゃ病院活動のお役に立てば幸いです。ご利用いただいた結果や感想等を記事へのコメントやメールでフィードバックしていただけると有難いです。なお、公開ファイルは最新版を載せているので、古い記事の内容から変わっている場合があります。

カテゴリ

おもちゃ修理技術 (221)
¦ ・電子オルゴール+音声再生 (83)
¦ ・音声再生・録音再生 (31)
¦ ・2.4GHzラジコン (80)
¦ ・レガシーラジコン (16)
¦ ・赤外線リモコン (4)
¦ ・タッチセンス (4)
¦ ・RFID (3)
ツール製作 (39)
¦ ・プログラマー (29)
¦ ・USB-シリアル変換 (6)
¦ ・その他のツール (4)
修理事例 (188)
¦ ・マイコン換装 (94)
¦ ・電子・電気修理 (70)
¦ ・メカ修理 (24)
製作記事 (17)
PIC開発 (6)
AVR開発 (3)
STM開発 (2)
おもちゃ病院 (10)
ドクター研修会 (4)
未分類 (0)

最新記事

最新コメント

月別アーカイブ

訪問者数

検索フォーム

RSSリンクの表示

リンク

このブログをリンクに追加する

QRコード

QR