HAGIWO 2OSC VCO と SYNC LFO を作る

概要

次のHAGIWO作品を作ることにした。2OSC VCO は前に作った Triple VCO の並びで揃えるため、SYNC LFO はシンセ用ソフト作りの勉強のためだ。

2OSC VCO はMozzi を使っている。自分では単音なら鳴らせても、VCO はとても手が出ない。したがって、フルコピーだ。

SYNC LFO はハード構成がマイコンと入出力のみというシンプルな構成なので、ソフトに注目できることも作りたくなった理由である。

  • No.18 2OSC VCO:Mozziを使ったノコギリ波、方形波、三角波、サイン波、ノイズ 2オシレータ。
  • No.12 Clock SYNC LFO:Fast PWMを使って疑似的にDA変換によってLFO波形を作る。

マイコンには素のAtmega328Pを使う。Nano に比べてアナログポートが2つ少なく6ポートだが、上記2作例では、それぞれ5ポートと4ポート使いなので問題ない。素のAtmega328P に16MHz のクリスタル発振器を外付けすれば、Arduino Uno と同等になる。

2OSC VCO と SYNC LFO

本文

モジュラーシンセを自作するにあたって、どんな機能が必要で、その仕様をどうすべきかということが全く分からない。まして、音楽面の知識も経験もないので、電気信号と音の関係は皆無である。

そういったことから、ハードもソフトもHAGIWOサイト情報の丸写しなので、ここで特記することはない。基板に組む前にブレッドボードに組んでソフトを走らせて、波形を見たり音を聴いたりするくらいのことしかやっていない。場合によっては、そのときプラスαを盛り込むこともあるが、今回はそういったこともない。

パネルサイズを4HPで作ったことしかオリジナルなものはない。
いつも通りFusion360でパネルや部品/基板レイアウト設計を行った。

2OSC VCO

3D of 2OSC VCO と SYNC LFO

スケッチから読み取れる2OSC VCOの内容


このコードは、Mozziライブラリを使用して、さまざまな波形を生成するArduinoプログラムです。複数のオシレーターを使用し、外部入力とアナログ読み取りに基づいて音声出力を生成します。以下に、このコードのインターフェースと動作を説明します。

インターフェース

  • ピン定義

    • デジタルピン:
      • 2, 3: OCTスイッチ入力用ピン
    • アナログピン:
      • A0: OSC1の基本周波数設定
      • A1: OSC2の基本周波数設定
      • A3: 波形選択用ノブ
      • A4: 出力ゲイン設定用ノブ
      • A5: V/OCT入力
  • オシレーター

    • 鋸波(SAW)、矩形波(SQUARE)、三角波(TRIANGLE)、正弦波(SIN)、ホワイトノイズ(NOISE)の各オシレーターを定義
  • 変数

    • freq1, freq2: OSC1およびOSC2の基本周波数
    • voct: 外部V/OCT入力値
    • freqv1, freqv2: V/OCT適用後のOSC1およびOSC2の周波数
    • octsw: オクターブスイッチの状態(-1オクターブ、0オクターブ、+1オクターブ)
    • wave_knob: 波形選択用ノブのアナログ値
    • wave: 波形モード(0: SAW, 1: SQUARE, 2: TRIANGLE, 3: SIN, 4: NOISE)
    • gain: 出力ゲイン
    • voctpow: V/OCTの指数テーブル
    • gain_table: ゲインテーブル

動作

  1. セットアップ

    • ピンモードを設定し、Mozziの初期化を行う
  2. コントロール更新 (updateControl)

    • 波形選択ノブの値に基づいて波形モードを設定
    • 出力ゲイン設定ノブの値に基づいてゲインを設定
    • OCTスイッチの状態に基づいてオクターブスイッチを設定
    • OSC1およびOSC2の基本周波数を設定
    • V/OCT入力を読み取り、適用
    • 選択された波形モードに基づいてOSC1およびOSC2の周波数を設定
  3. オーディオ更新 (updateAudio)

    • 現在の波形モードに基づいて、OSC1およびOSC2の音声出力を合成し、ゲインテーブルを適用して出力
  4. メインループ (loop)

    • Mozziのオーディオフックを呼び出してオーディオを更新

各関数の説明

  • setup()

    • Arduinoの初期設定を行い、Mozziのオーディオ出力を開始する
  • updateControl()

    • 波形選択、ゲイン設定、オクターブスイッチの状態、OSCの周波数設定、V/OCTの適用を行う
  • updateAudio()

    • 選択された波形モードに基づいてOSC1およびOSC2の音声出力を合成し、ゲインテーブルを適用して出力する
  • loop()

    • Mozziのオーディオフックを呼び出してオーディオを更新する

このコードは、Mozziライブラリを使用して、OSC1およびOSC2の周波数と波形を制御し、指定された設定に基づいてオーディオ出力を生成します。ユーザーはアナログ入力を使用して、波形モード、ゲイン、オクターブスイッチ、および周波数を調整できます。

ハード構成

HAGIWOモデルからの変更
  • マイコン :Atmega328p + 16MHz セラロック
  • オペアンプ:LMC6482(CMOS レール ツー レール フルスイング , 16V)Aliexpress品

kicad of 2OSC VCO と SYNC LFO


side view of 2OSC VCO と SYNC LFO


SYNC LFO

top wiew of SYNC LFO


このコードは、FlexiTimer2ライブラリを使用してPWM信号を生成し、外部クロック入力を監視しながら様々な波形を出力します。

インターフェース

  • ピン定義

    • PWMPin (10): PWM出力ピン
    • CheckPin (13, PIN_CHECKが1の場合): デバッグ用の出力ピン
    • アナログ入力ピン
      • A0: 振幅設定用
      • A1: 内部クロック/フェーズ設定用
      • A3: 波形モード設定用
      • A5: モジュレーション設定用
  • 変数

    • duty: PWMのデューティ比(0.0~1.0)
    • count: 波形テーブルのカウント
    • wave: 波形モード選択
    • set_freq: 周波数設定
    • freq_max: 最大周波数
    • amp: 振幅
    • amp_rate: 振幅比率
    • phase: 位相
    • mod: モジュレーションモード
    • ext_injudge: 外部クロック使用判定
    • ext_pulse: 外部クロック入力
    • old_ext_pulse: 前回の外部クロック入力
    • ext_count, ext_count_result, old_ext_count_result: 外部クロックカウント
    • ext_period: 外部クロック周期
    • reset_count: リセットカウント

動作

  1. セットアップ

    • PWM出力ピンと入力ピンのモードを設定
    • タイマー2を50µsごとに割り込みをかけるように設定
    • PWMの10ビット高速モードを設定
  2. メインループ

    • 外部クロック入力を監視し、前回の状態と比較
    • 各種設定関数を呼び出して波形、フェーズ、モジュレーション、振幅、外部入力の判定、クロック設定を行う
    • PWMの設定を更新
  3. 割り込み処理

    • 50µsごとに呼び出される
    • 外部クロックカウントをインクリメント
    • 周波数設定カウントをインクリメント
    • チェックピンのトグル(PIN_CHECKが1の場合)
    • 周波数設定カウントが最大周波数を超えた場合、カウントをリセットし、波形テーブルからデューティ比を取得してPWMを更新

各関数の説明

  • selectWaveMode()

    • A3ピンのアナログ値に基づいて波形モードを選択
  • setPhaseAndClock()

    • 内部クロック使用時と外部クロック使用時でフェーズと最大周波数を設定
  • selectModulation()

    • A5ピンのアナログ値に基づいてモジュレーションモードを選択し、対応する波形テーブルを使用してフェーズを更新
  • setAmplitude()

    • A0ピンのアナログ値に基づいて振幅を設定
  • judgeExternalInput()

    • 外部クロック信号が8秒間無い場合は内部クロックを使用するように設定
  • setClock()

    • 外部クロック信号が変化した場合、クロックカウントをリセットし、周期を計算して最大周波数を設定
  • timer_count()

    • 50µsごとに呼び出され、外部クロックカウントと周波数設定カウントをインクリメント
    • 周波数設定カウントが最大周波数を超えた場合、カウントをリセットし、波形テーブルからデューティ比を取得してPWMを更新

PWMが8bitで出力しているようなので、10bit出力に変更してみた。


  // PWM設定
OCR1A = 1023; // 10-bit max value
OCR1B = (unsigned int)(1023 * duty * amp_rate);

ハード構成

HAGIWOモデルからの変更
  • マイコン :Atmega328p + 16MHz セラロック

kicad of SYNC LFO



finished OF SYNC LFO 1

finished OF SYNC LFO 2


実験波形

サイン波形とRamdam波形を出してみた事例。

oscillo wave OSC oscillo wave LFO


まとめ 

今回、HAGIWO作品を作ることで信号を音楽的に扱う経験ができた。
Mozziについては、プログラミングの手順は理解したが、自分で波形を作るまでは習得できていない。
以前、Fast PWMを使ったことがあるが、DA変換をすることを今回経験した。
Next Post Previous Post
Gemini