技術情報」カテゴリーアーカイブ

CEM 3340 タイプの VCO

今汎用の VCO を作ろうかなと考えています。Analog2.0 の VCO も汎用なので今まで実験などに使ってきたのですけれども、調整箇所が多いなど色々と直したい点があるので一から作り直してみようと考えているわけです。

普通に作るなら今まで通りリセット型の発振器にするのが素直ですけれども、CEM3340 のような三角波を発生する VCO もかねてから興味があったので検討してみました。実は CEM 3340、今は入手しようと思えば入手できてしまいます。数を作るならそれを素直に使うのが良いかもしれないのですが、電源が ±15V と指定されています。利便性を考えて ±10V の電源で設計しようと考えているのでこのプロジェクトでは使えません。残念。昇圧するという手もあることはあるのですけれどもね。

続きを読む

MIDI ジッタ

以前に、BOSS の DR-110 を改造して MIDI 信号を受けられるようにするというプロジェクトをじわじわやっていたのですが、

実はもうとっくに音が出るようになっていたのですが、こんな感じ

これは気持ち悪い。なんかリズムが転んでいる気がします。どうもおかしい。というところで、やる気が駄々下がりしてしまいかなり長いこと放置してしまいました。基板もむき出しで放ってあるので壊してしまいかねない。いい加減に収拾をつけないといけません。まずは本当にリズムが転んでいるかチェック。一番気持ち悪い二小節を切り出して、さらに波形を拡大してみると

ああこれは。矢印のところは 16 ビートのハイハットですが、はっきり遅れています。それ以外の部分もどうもガタガタです。ざっと目測しただけですが本来欲しいタイミングより 40ms から 50ms ぐらい遅れている模様。こんな盛大な遅れが出るのはなぜかというのは謎が深いです。USB MIDI はフレームがあるのでジッタが出るという説もネットをあさっていて見かけました。この改造でも USB MIDI を使っていますが、仮に説が本当としても、USB MIDI のフレームサイズは 1ms なのでこの遅延は説明がつきません。そもそも 1ms ずれたぐらいでは人間にはわからないのではないでしょうか。まあとにかく、このままでは使い物になりません。

どうやって解決の糸口をつかむか思案しています。まずは MIDI 信号のタイミング測定からやってみようかな。

マイクロプロセッサで立ち上がり・減衰時間を減衰率に変換する方法

前回の記事で減衰時間から減衰率を求める計算式を考えましたが、K = e-0.01/T とかなり変な式、グラフを引いてみると、こんな風に極端な形で、この減衰率をマイクロプロセッサで求めるのはこれまた単純にはゆかなさそうです。

上記の式は非線形の関数なので、プロセッサで都度計算するのは時間がかかり、処理が追い付かなくなりそうです。近似値でよいので素早く計算したいです。手っ取り早いのはテーブル参照と補間・補外を使う方法、それなら実用的な速さで計算できそうです。

入力は、1024 ステップの整数値でこれを欲しい減衰時間に線形に対応させます。出力はその減衰時間のための減衰率です。テーブルには主要の入力値にたいする減衰率を覚えさせます。

ただここで一つ問題が。参照テーブルの値の精度をどれぐらい取る必要があるか試行錯誤しましたが、今の僕の技術ではどうしても 32bit 必要です。これを 1024 点全部覚えさせるには、1024 x 4 = 4KB の SRAM が必要です。今プロセッサに AVR の ATmega168 を使っていますが、内部 SRAM が 1KB しかありません。思い切りあふれています。テーブルの点数を 256 点にして補間しましたが変化が急激すぎて時間分解能が足りません。それでもまだメモリがあふれています。テーブルの作りに工夫が必要です。

その前に、まず時間変化の範囲をどれぐらいに取る必要があるか決めました。これは音を出して決めるのが一番、パラメータを変え、音を聞きを繰り返して、多分時定数を 1ms から 5s の範囲で動かせれば十分なようです。いずれもっと長い立ち上がりと減衰が欲しくなるかもしれませんが、まあ将来の改良点ということにしてほっときます。

で、もう一度上のグラフを見ると、カーブが急激に動くのはせいぜい 1 秒ぐらいまでで、あとはほぼ横ばいです。なので、時間の短いところと長いところでテーブルの時間分解能を変えるのはどうでしょうか?目標は 128点。これで 512B のサイズで、メモリには余裕ができます。

これまた試行錯誤して、最初の 64 点 (0.3秒ぐらいまで) は入力値とテーブルを一対一で対応して、残りの 1024 – 64 = 960 点は時間分解能がそれほど必要ないのでテーブルの後半のもう 64 点でカバーしてみると、かなり良い精度で近似できました。後半はテーブル一点で入力値の15点をまかなう計算になります。それだと値がカクカクするから線形に補完します。

テーブルの値の計算をするプログラムはこちら。ちょっと雑なプログラムですけどまあさっと動かしてしまいたかったので。テーブルの値は、Q0.32 の固定小数点数です。減衰率なので値は絶対に 1 未満なのでこれで大丈夫です。

#include <math.h>
#include <stdint.h>
#include <stdio.h>

uint32_t table[128];

int main(int argc, char *argv[]) {
  for (int i = 0; i < 1024; ++i) {
    if (i >= 64 && (i - 64) % 15 != 0) {
      continue;
    }
    double x = -0.0001 / (0.001 + 5.0 * i / 1024.0);
    uint32_t value = ((uint32_t) (exp(x) * (float) ((uint64_t) 1 << 32)));
    int index = (i < 64) ? i : ((i - 64) / 15 + 64);
    table[index] = value;
    printf("%12u,", table[index]);
    if (index % 4 == 3) {
      printf("\n");
    }
  }
  return 0;
}

このプログラムで作ったテーブルをマイクロプロセッサに埋め込んで減衰率を求める関数を書きました。今のところ良好です。

/*
 * Exponential decay/grow ratio lookup table.
 *
 * The table stores data points to give decay/grow ratio for lookup keys ranging
 * from 0 to 1023 (inclusive). The key 0 receives the ratio for time constant
 * 0.001s (1ms) approximately. The key 1023 receives the ratio for time constant
 * about 5s. The values in th table are Q0.32 unsigned fixed point numbers.
 *
 * In order to save data memory space, the values have different key resolutions
 * depending on the position in the table.
 * Table values with indexes from 0 to 63 has 1-1 key mapping to index,
 * i.e.
 *   ratio = kTransientRatios[key]
 * But for the indexes from 64 to 127, the table keeps only values for every 15 keys,
 * i.e.
 *   ratio = kTransientRatios[(key - 64) / 15 + 64]
 * where (key - 64) % 15 == 0
 *
 * Ratios for keys that are not on these indexes need to be calculated
 * by interpolation or extrapolation. See the method GetRatio().
 */
uint32_t kTransientRatios[128] = {
  3886247118,  4222575580,  4255256816,  4267608186,
  4274098987,  4278100538,  4280814394,  4282775974,
  4284259997,  4285421933,  4286356375,  4287124175,
  4287766262,  4288311174,  4288779419,  4289186113,
  4289542645,  4289857756,  4290138268,  4290389583,
  4290616034,  4290821137,  4291007774,  4291178333,
  4291334804,  4291478865,  4291611934,  4291735225,
  4291849776,  4291956486,  4292056132,  4292149393,
  4292236865,  4292319070,  4292396469,  4292469473,
  4292538445,  4292603710,  4292665560,  4292724255,
  4292780031,  4292833101,  4292883656,  4292931872,
  4292977906,  4293021905,  4293063999,  4293104310,
  4293142949,  4293180018,  4293215611,  4293249813,
  4293282706,  4293314362,  4293344850,  4293374234,
  4293402573,  4293429921,  4293456330,  4293481846,
  4293506515,  4293530379,  4293553475,  4293575840,
  4293597508,  4293856889,  4294033677,  4294161903,
  4294259161,  4294335461,  4294396917,  4294447478,
  4294489805,  4294525758,  4294556676,  4294583547,
  4294607117,  4294627960,  4294646522,  4294663159,
  4294678155,  4294691742,  4294704109,  4294715414,
  4294725787,  4294735340,  4294744166,  4294752345,
  4294759946,  4294767027,  4294773641,  4294779831,
  4294785639,  4294791097,  4294796237,  4294801085,
  4294805667,  4294810002,  4294814111,  4294818011,
  4294821717,  4294825243,  4294828603,  4294831807,
  4294834867,  4294837792,  4294840590,  4294843270,
  4294845839,  4294848303,  4294850670,  4294852944,
  4294855131,  4294857236,  4294859264,  4294861218,
  4294863103,  4294864922,  4294866678,  4294868376,
  4294870017,  4294871604,  4294873141,  4294874628,
  4294876070,  4294877467,  4294878823,  4294880138,
};

uint32_t GetRatio(uint16_t key) {
  const int kTableBoundary = 64;
  if (key < kTableBoundary) {
    return kTransientRatios[key];
  }
  const int kResolution = 15;
  int index = (key - kTableBoundary) / kResolution + kTableBoundary;
  int ramainder = (key - kTableBoundary) % kResolution;
  register uint32_t temp = kTransientRatios[index];
  if (ramainder > 0) {
    register uint32_t temp2;
    if (index == 127) {
      temp2 = temp - kTransientRatios[index - 1];
    } else {
      temp2 = kTransientRatios[index + 1] - temp;
    }
    temp2 *= ramainder;
    temp2 /= kResolution;
    temp += temp2;
  }
  return temp;
}

減衰係数はどうやって計算すれば良いか?

ちょっと間違っているかもしれませんが後で見直すためのメモでもあります。

まず放電とかの減衰曲線の時定数の定義が何だったか忘れました。調べたら行き着くのは当然 Wikipedia、もとの値の約 37% ということで、なんでそんな半端な数なのかも思い出せませんが、とにかく、37% ね。ちなみに時定数を英語で何というかも知りませんでした。普通に time constant なのですね。あっ英語ページには 1 / e ≒ 36.8% て書いてある。と思ってよく見たら日本語ページにも書いてあるじゃないか。

と、与太話はこれぐらいにして、今設計している EG モジュールの PWM は、約10ミリ秒ごとに値を更新するので、T 秒で 1 / e に落とすなら、T / 0.01 回の更新で値が 1 / e にまで減衰すれば良いのだから、

K = (1/e)0.01/T = e-0.01/T

プロットしてみました

なんというか、不安を誘う曲線ですね。精度とか大丈夫だろうか?横軸を対数に取ってみたらどうでしょうか?

うん、これならまだ何とかなるかもしれません。手持ちのボリュームに B カーブのものがなくてDカーブのものを使っているのがとっても気になりますが、もうハードウェアは作ってしまったので仕方がない。でもいずれにせよこの曲線をリアルタイムで計算するのはちょっと厳しそうです。実装にまた工夫がいります。先は長い、かも

マイクロプロセッサでの減衰曲線の実装

前回、参照テーブルを使わずに減衰曲線を生成する方法を考察しましたが、その方法をマイクロプロセッサで試してみました。やはり一筋縄ではいかないようです。

実際のプログラムは記事に載せるには長すぎますが、関係のある部分を抜粋して、こんな感じのプログラムを組みました。一見動きそうだし、これを普通に PC で実行すれば動作するはずですが、AVR ではうまく動作しません。

volatile uint32_t g_value;  // value holder, Q10.22 fixed point number
volatile uint32_t g_decay_factor;  // amount of decay,  Q0.32 fixed point
volatile uint8_t g_update_ready;

ISR(Time1_OVF_vect) {
  OCR1A = g_value >> 22;  // reflect the value to PWM、Q10.22 to integer
  g_update_ready = 1;
}

void UpdateValue() {
  if (!update_ready) {
    return;
  }
  // reduce the value by multiplying the decay factor
  uint64_t temp = g_value;
  temp *= g_decay_factor;
  g_value = temp >> 32;
  g_update_ready = false;
}

int main() {
  g_value = 1023 << 22; // integer to Q10.22
  g_decay_factor = 0.99309249543703590153321021688807 * 0x100000000;
  g_update_ready = 0;

  while (true) {
    UpdateValue();
  }
}

どうも AVR 用のコンパイラ avr-gcc は、C 言語標準に厳密には従っていないようです。どこかにドキュメントがあるかもしれませんが見つけていません。レジスタを細かく制御したいための仕様なのかもしれません。レジスタを意識して、データ領域からレジスタにどんな風にデータをロードしてレジスタ上でどんな演算をするのか意識して書くと動くようです。上記のプログラムは以下のように書き換えれば動くはずです。

volatile uint32_t g_value;  // value holder, Q10.22 fixed point number
volatile uint32_t g_decay_factor;  // amount of decay,  Q0.32 fixed point
volatile uint8_t g_update_ready;

ISR(Time1_OVF_vect) {
  register uint32_t temp = g_value;  // copy the Q10.22 value to a variable
  temp >>= 22;  // Q10.22 to integer
  OCR1A = temp;  // reflect the value to PWM
  g_update_ready = 1;
}

void UpdateValue() {
  if (!update_ready) {
    return;
  }
  register uint64_t temp = g_value;
  // copy the Q10.22 value to a 64-bit int
  temp *= g_decay_factor;
  // multiply by the Q0.32 decay factor
  temp >>= 32;  // shift 32 bit to adjust scale, now it's Q10.22 again
  g_value = temp;
  // copy back to the value holder
  g_update_ready = false;
}

int main() {
  register uint32_t temp = 1023 << 22;   // this is calculated by the compiler
  g_value = temp;
  g_decay_factor = 0.99309249543703590153321021688807 * 0x100000000;
  g_update_ready = 0;

  while (true) {
    UpdateValue();
  }
}

temp は register 変数として宣言しなくても動くようです。コンパイラが良きに計らってくれるようです。

要点は、ビットを伸ばしたり縮めたりする演算をするときには、以下の点を気を付けると動くようです

  • データをどこにロードさせるかはっきりさせる (一時変数を宣言する)
  • 演算がどこで行われるかはっきりさせる
    • 二項演算子 +, -, *, >>, << のかわりに +=, -=, *=, >>=, <<= を使う。
    • 一行一演算、一行に二つの演算を入れない

「ようです」が多いのが恐縮です。このことが書かれているドキュメントを読んだわけではないので、コンパイラの挙動から推測しています。

指数関数曲線を固定小数点演算で求める

エンベロープジェネレータのプログラムですが、現状は指数関数テーブルを参照して出発点の値に時間ごとに減衰する指数関数を掛け合わせて減衰曲線を作っています。

https://github.com/naokiiwakami/vceg

これは精度をあまり気にせずにざっと計算できるので手っ取り早いのですが、プログラムはどうしても煩雑になります。また、値の更新周期は約 10ms なのですが、減衰が遅いと 10ms の間には値が動かず、時間軸を補間しないといけません。これはまだ実装していませんがプログラムはもっと煩雑になります。

ちょっと嫌だなと考え始めたのですが、そもそも指数関数の減衰は

V(i+1) = V(i) * k

where 0 <= k < 1

のような式で簡単に作れそうなものなのですが、実はそう甘くはありません。例えば、1秒で半分に減衰する曲線を、10ms の更新周期で計算しようとすると、k の値は

k = 0.5 ^ (1 / 100) = 0.99309249543703590153321021688807

限りなく 1 に近いけれども 1 にしてしまったら減衰しません。変数として float を使えばいいじゃない?とも思いますが、例えば AVR で float を static 領域に持つとなんだかわからないけれどもデータがばんばん壊れてしまいます(バグかもしれませんが)。それにそもそもふつうのマイクロプロセッサでの浮動小数点演算は遅いです。ということで、固定小数点演算で曲線が求まらないか考えてみました。

ブランクがあまりにも長いのでやり方を忘れてしまいました。ので調べました。以下の解説がとてもわかりやすかったです

https://www.allaboutcircuits.com/technical-articles/multiplication-examples-using-the-fixed-point-representation/

いつか上記リンク先がなくなってしまうかもしれないので解説を書いとくのも良いのですが、何分もう夜分遅いので、書いたプログラムだけだっと貼っちゃいます。

#include <stdio.h>
#include <stdint.h>

int main(int argc, char *argv[]) {
  // fixed point integer 10bit.6bit
  uint16_t value = (1023) << 6;
  // fixed point integer .16bit
  uint16_t decay_factor = 0.99309249543703590153321021688807 * 65536;
  for (uint16_t i = 0; i < 1000; ++i) {
    // multiplication
    uint32_t temp = value * decay_factor;
    value = temp >> 16;
    // retrieve the integer part
    uint16_t output = value >> 6;
    printf("%d %d\n", i, output, 10);
  }
  return 0;
}

結果もさくっと貼っちゃいます

これはいけそうな気がします。

AVRISP mkII を使ってコマンドラインからプログラムする

アトメルの AVR プログラマ AVRISP mkII はもう販売終了していますが、デバイスにさっと書き込むにはやはり大変便利、いまだに愛用しています。でも AtmelStudio 経由で書き込むとウィンドウを開けたり閉じたりしなくてはならず繰り返しプログラミングするときには面倒です。コマンドラインからのプログラミングには Avrdude を使うことが多いですが、このソフトは AVRISP mkII で使われているドライバとうまく通信ができないようで、よっく探すと AVRISP のドライバをハックして無理やり書き込むこともできるようですが、それはちょっと危なっかしい。目的は avrdude を使うことではなくコマンドラインから書き込むことなので、違う方法を探しました。AVRISP mkII はアトメルのものなので Atmel Studio のパッケージの中に何らかのツールがあるはず、と探してみたらありました。atprogram というツールらしいです。以下は使い方のメモです。

PATH 環境変数への登録

C:\Program Files (x86)\Atmel\Studio\7.0\atbackend あたりにあるのでここを環境変数 PATH に登録します。

デバイスへの接続チェック

プログラマを使うときまずするのがデバイスときちんと通信できるかのチェックですが、以下のコマンドを使います

$ atprogram -t avrispmk2 -i isp -d atmega168 info --signature
Firmware check OK
0x001e9406

–signature オプションを省くとフューズなどもっと詳しい情報が出ます。でもフューズをもっと手っ取り早く読むには

$ atprogram -t avrispmk2 -i isp -d atmega168 read --fuses --format hex
Firmware check OK
dfdeff

デバイスへのファームウェア書き込み

以下が例です

$ atprogram -t avrispmk2 -i isp -d atmega168 program -c -fl -f dr-110.elf --format elf --verify
 Firmware check OK
 Programming and verification completed successfully.

ビルドしたイメージのサイズの表示

avr-size コマンドを使います

$ avr-size -C --mcu atmega88 dr-110.elf
AVR Memory Usage
----------------
Device: atmega88

Program:    2468 bytes (30.1% Full)
(.text + .data + .bootloader)

Data:         76 bytes (7.4% Full)
(.data + .bss + .noinit)

Windows 10 の設定

日本から持ってきた ThinkPad 200、10年ぐらい直し直し使っていましたが電源まわりの故障が起きてしまいそろそろ寿命のようで新しい PC を購入しました。Windows 機を新調すると大変な量の設定が必要で毎度辟易しますが、その分できることも多いので我慢のしどころです。

設定事項のひとつひとつは検索をするとたいてい解決しますが数が多いので毎回おのおのを検索するのは時間食いです。過去にやったことを繰り返すにはこのブログにメモを入れておくのが一番効果的とだんだんわかってきました。ということで、この記事には、Windows の設定方法が集めてあります。

JIS 配列キーボードを US 配列キーボードとして使う

106 キーボードを 101 キーマップで使うわけです。以前はレジストリを編集しなくてはならなくてちょっと嫌でしたが、Windows 10 では設定の変更だけでいけます。以下作業メモから

Go to Settings -> Time & Language -> Language -> “Choose an input method to always use as default” -> “Override for default input method”

Then change the selection to “English” from “Use language list”

Inconsolata フォントをインストールする

Inconsolata ページ: https://www.levien.com/type/myfonts/inconsolata.html
フォントの入手先: https://github.com/google/fonts/tree/master/ofl/inconsolata

フォントのインストール方法:

  1. フォント ttf ファイルをダウンロードする
  2. 右クリック→Install
  3. Windows 検索ウィンドウで fonts とタイプすると設定されたフォントが確認できる

参考: https://www.groovypost.com/howto/install-fonts-windows-10/

Sonar をインストールする

Sonar で古いプロジェクトやプラグインを使っているのですがそれらが動くようにするには色々設定が必要です。

32 bit か 64 bit か?

プラグインが 32 bit なので 32 bit 版の Sonar をインストールしたほうが簡単です。 64 bit 版をインストールすると何もしなければプラグインが動きません。

日本語 Sonar を英語 Windows で使う

英語版 Windows で日本語のアプリを使う方法は 鍋CADが英語モードの WINDOWS 10 で文字化けしてしまう に一度書いたのですが、日本語 Sonar はこれだけではまだ十分でなく、

Control Panel > Clock, Language, and Region を呼び出した後、Region > Change location > Administrative タブ > Change system locale… > Current system locale: Japanese > OK

ここまでは一緒ですが、ここからさらに、”Beta: Use Unicode UTF-8 for worldwide language support” チェックボックスにチェックを入れます。それでもまだ多少の文字化けをしますが使える範囲内です。

Proteus VX プラグインのインストール

Proteus VX は Windows XP 向けに開発されていて、32 bit の設定でインストールするだけでは動きません。コンパチブルバージョンを変えないといけません。インストールされた Proteus VX の実行ファイルを探し (私の環境では C:\Program Files (x86)\Creative Professional\Proteus VX\ProteusVX.exe)、右クリック -> Properties -> Compatibility タブ -> Compatibility mode に行き、”Run this program in compatibility mode for” をチェックし、バージョンは “Windows XP (Service Pack 3)” を選びます。今回はこれで動作しました。

こんなに古いプラグインがまだ動くのはありがたいことです。でも誤動作も頻繁に見かけます。E-mu ブランドはついになくなってしまったようで、今後 Proteus が再リリースされる可能性はだいぶん低いのだと思います。残念です。

USB コネクタソケットのシールドはどこにつなぐ?

MIDI USB の実験のために USB コネクタの配線を始めるところですが、まず最初の疑問、「ソケットのシールドはどこにつないだら良い?」 GND に落とすんでしょうか?別のことをするんでしょうか? GND に落とすと色々悪いことが起きそうな予感がします。

Stack Exchange に 参考になるスレッドがありました

たくさん記述がありますが、要するに GND に落としてはいけなくて、どこにもつながないか装置のアースにつなぐのが良いようです。今のプロジェクトでは前者です。

上記のスレッドは長いですが、内容は面白く読む価値はあります。

MC34063 を使った DC-DC 昇圧電源の設計

今改造中の DR-110 は 6V の電池または 9V の ACアダプタを電源にしていますが、USB とつなぐことも検討しているので USB から電源が取れると便利です。 DR-110 の回路図を見ると、電源には最低でも 6V 必要です。 USB からの給電は 5V なので、少しだけ持ち上げる必要があります。今後も USB からアナログ回路への電源が取れるとなにかと便利なので、入手しやすい DC-DC 電源 IC を探して使い方を覚えることにしました。

Jameco が近所にあってそこに在庫があればその日のうちに部品が入手できるので、ここにあるチップしかも DIP パッケージのものが使えれば便利です。調べてみると、MC34063 というチップが安価で在庫豊富です。このチップは、昇圧、減圧、極性反転すべて可能で容量も 1.5A あり応用範囲が広そうです。ほかのサイトを見ても入手しやすいようで、DC-DC コンバータの定番チップであるようです。まずはこの IC の使い方を覚えることにします。

DR-110 の電源として使うには、5V の USB 電源から 7V ぐらいに昇圧すればちょうど良いです。消費電流は 50mA も取れれば良いはず。この仕様なら IC の性能の範囲に楽々収まるのでこの設計をしてみることにします。

最初は資料集めからです。Jameco で扱っている MC34063 は STMicro 製で製品ページはこちらですが、データシートには使い方の要約が書かれているだけで、この回路の知識がないとこれだけでは設計できそうにもありません。ので、ONセミコンダクタTI の製品ページからデータシートとアプリケーションノートを入手しました。アプリケーションノートはどちらの配布も内容は同じなようです。先に見つけたのは TI のページでそちらの資料を使いました。

これが、データシートに載っている昇圧電源の回路図、内臓のオシレータによりQ1/Q2 スイッチを断続して、Lにエネルギーを貯めて昇圧します。5番ピンに入る電圧を監視して、コンパレータによりスイッチングのタイミングを変えることにより出力電圧を安定させます。巧妙にできていますね。

この回路定数をそのままR2だけを変えて 5V → 7V の昇圧になるように設定して実際に回路を組んでみましたが、出力電源に盛大なリップルが入ってそれがノイズとして聞こえてしまい使い物になりませんでした。もっと丁寧に回路定数を計算する必要があるようです。アプリケーションノートには動作原理から回路定数の計算方法まで詳しく書かれているのでそれに従って回路定数を計算してみました。

オシレータの周波数は CT によって決まり、ほかの回路定数の影響はほぼ受けないようです。発振周波数から決めて、あとは、出力電圧からスイッチングのデューティー比を計算、それと出力電流から L の最小値を決めればよいようです。それで決めた回路定数をもとに、シミュレータを使って動作確認をして回路定数を少し変えました。下の図が回路定数を変えてシミュレーションした回路、R4 は負荷です。

スイッチング電源の難しそうなところは、負荷の大きさでスイッチングの挙動が大きく変わること、アナログ回路では消費電流が大きく変わることはあまりなさそうなので、消費電流をあらかじめ調べてから設計を調整したほうが良いような気もします。以下は、負荷抵抗を 100kΩにまで増やした時の挙動、スイッチングのタイミングが大きく変わって、遅いリップルもくっきり見えています。周期が 1 kHz 弱ぐらいまでに落ちているのでこれは音になって聞こえてしまいそうで、このようになったら回路定数をまた変えないといけません。ここまできたら実際に回路を組んで確認したほうがよさそうです。今 10μH のインダクタが手元にないのでまずはここまでです。