• R/O
  • HTTP
  • SSH
  • HTTPS

コミット

よく使われているワード(クリックで追加)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

ATMEGA328を搭載した Arduino Duemilanove 互換機で音をPWM D/A変換出力するシンセサイザーライブラリです。


コミットメタ情報

リビジョン3c6fdeedb6f0127f4fa8ced72842e82e8be5716d (tree)
日時2020-04-18 23:56:21
作者Akiyoshi Kamide <kamide@yk.r...>
コミッターAkiyoshi Kamide

ログメッセージ

Doc/keywords update, and macro refactored

変更サマリ

差分

--- a/PWMDAC_Synth.h
+++ b/PWMDAC_Synth.h
@@ -1,5 +1,5 @@
11 //
2-// PWM DAC Synthesizer ver.20200413
2+// PWM DAC Synthesizer ver.20200418
33 // by Akiyoshi Kamide (Twitter: @akiyoshi_kamide)
44 // http://kamide.b.osdn.me/pwmdac_synth_lib/
55 // https://osdn.jp/users/kamide/pf/PWMDAC_Synth/
@@ -16,17 +16,7 @@
1616 #define cbi16(sfr, bit) (_SFR_WORD(sfr) &= ~_BV(bit))
1717 #define sbi16(sfr, bit) (_SFR_WORD(sfr) |= _BV(bit))
1818
19-// Function-to-array generator
20-#define FX2(f,x) f(x), f(x + 1)
21-#define FX4(f,x) FX2(f,x), FX2(f,x + 2)
22-#define FX8(f,x) FX4(f,x), FX4(f,x + 4)
23-#define FX16(f,x) FX8(f,x), FX8(f,x + 8)
24-#define FX32(f,x) FX16(f,x),FX16(f,x + 16)
25-#define FX64(f,x) FX32(f,x),FX32(f,x + 32)
26-#define FX128(f,x) FX64(f,x),FX64(f,x + 64)
27-#define ARRAY128(f) {FX128(f,0)}
28-#define ARRAY256(f) {FX128(f,0),FX128(f,128)}
29-
19+// Default parameter
3020 #ifndef PWMDAC_OUTPUT_PIN
3121 #define PWMDAC_OUTPUT_PIN 3
3222 #endif
@@ -37,7 +27,8 @@
3727 #define PWMDAC_POLYPHONY 6
3828 #endif
3929
40-// Built-in wavetable generator
30+//
31+// Built-in wavetable functions
4132 // x = Phase angle : 0x00...0x80(PI_radian)...0xFF
4233 // f(x) = Wave voltage at the x : 0x00(min)...0x80(center)...0xFF(max)
4334 #define PWMDAC_SQUARE_WAVE(x) (((x) < 0x80 ? 0x00 : 0xFF) / PWMDAC_POLYPHONY)
@@ -46,17 +37,26 @@
4637 #define PWMDAC_MAX_VOLUME_SINE_WAVE(x) ((byte)( 0x80 * (1 + sin(PI * (x) / 0x80)) ))
4738 #define PWMDAC_SINE_WAVE(x) ((byte)( 0x80 * (1 + sin(PI * (x) / 0x80)) / PWMDAC_POLYPHONY ))
4839 #define PWMDAC_SHEPARD_TONE(x) ((byte)( 0x80 * (8 \
49- +sin(PI * (x) / 0x80) \
50- +sin(PI * (x) / 0x40) \
51- +sin(PI * (x) / 0x20) \
52- +sin(PI * (x) / 0x10) \
53- +sin(PI * (x) / 0x08) \
54- +sin(PI * (x) / 0x04) \
55- +sin(PI * (x) / 0x02) \
56- +sin(PI * (x) / 0x01) \
57- ) / (8 * PWMDAC_POLYPHONY) ))
40+ +sin(PI * (x) / 0x80) \
41+ +sin(PI * (x) / 0x40) \
42+ +sin(PI * (x) / 0x20) \
43+ +sin(PI * (x) / 0x10) \
44+ +sin(PI * (x) / 0x08) \
45+ +sin(PI * (x) / 0x04) \
46+ +sin(PI * (x) / 0x02) \
47+ +sin(PI * (x) / 0x01) \
48+ ) / (8 * PWMDAC_POLYPHONY) ))
49+
50+#define FX2(f,x) f(x), f(x + 1)
51+#define FX4(f,x) FX2(f,x), FX2(f,x + 2)
52+#define FX8(f,x) FX4(f,x), FX4(f,x + 4)
53+#define FX16(f,x) FX8(f,x), FX8(f,x + 8)
54+#define FX32(f,x) FX16(f,x), FX16(f,x + 16)
55+#define FX64(f,x) FX32(f,x), FX32(f,x + 32)
56+#define FX128(f,x) FX64(f,x), FX64(f,x + 64)
57+#define FX256(f,x) FX128(f,x), FX128(f,x + 128)
5858
59-#define PWMDAC_CREATE_WAVETABLE(table, function) PROGMEM const byte table[] = ARRAY256(function)
59+#define PWMDAC_CREATE_WAVETABLE(table, func) PROGMEM const byte table[] = { FX256(func,0) }
6060
6161 // [Phase-correct PWM dual-slope]
6262 // TCNTn value changes to:
@@ -277,7 +277,7 @@ class PWMDACSynth {
277277 wavetable = this->channel->wavetable;
278278 envelope = this->channel->envelope;
279279 modulation = &(this->channel->modulation);
280- static PROGMEM const unsigned long phase_speed_table[] = ARRAY128(PHASE_SPEED_OF);
280+ static PROGMEM const unsigned long phase_speed_table[] = { FX128(PHASE_SPEED_OF,0) };
281281 dphase32_original = pgm_read_dword(phase_speed_table + (this->note = note));
282282 dphase32_bended = this->channel->bendedPitchOf(dphase32_original);
283283 dphase32_real = dphase32_bended + dphase32_moffset;
--- a/README.txt
+++ b/README.txt
@@ -1,17 +1,17 @@
11
22 [PWMDAC_Synth - PWM DAC synthesizer library for Arduino]
33
4-ver.20200405
4+ver.20200418
55
66 https://osdn.jp/users/kamide/pf/PWMDAC_Synth/wiki/FrontPage
77
8-Arduinoで動作する簡易シンセサイザライブラリです。
98
109 これは、CAmiDion
1110
1211 http://www.yk.rim.or.jp/~kamide/music/chordhelper/hardware/
1312
14-の2号機以降で実装した音源をライブラリ化したものです。
13+の2号機以降で実装した音源をライブラリとして独立させた、
14+Arduino互換機用のPWMシンセサイザライブラリです。
1515
1616
1717 ●Arduinoで楽器を作ろうとして、こんな問題にぶち当たったことはありませんか?
@@ -52,6 +52,8 @@ Arduino
5252 基本的な使い方を下記に示します。なお、ノートオン、ノートオフなど、音の出し方については
5353 Arduino IDE のメニューからたどれる「スケッチの例」を参考にしてください。
5454
55+ 【サンプルコード】
56+ //
5557 // 必要に応じ、PWMDAC_Synth.h をインクルードする前に #define で下記を指定できます。
5658 //
5759 #define PWMDAC_OUTPUT_PIN 3 // PWM出力ピン番号(省略可:下記「●出力ピン(PWM)」参照)
@@ -101,9 +103,14 @@ Arduino
101103 デフォルトは6重和音です。
102104 PWMDAC_POLYPHONY に数値を設定してコンパイルし直すことで増減可能です。
103105
104- 同時発音数を増やすと、その分、割り込み処理 ISR() の実行に時間がかかります。
105- 割り込み以外の処理を行うための時間的余裕がなくなった時点で動作しなくなります。
106- そうなる寸前が、事実上の同時発音数の上限です。
106+ ※ 同時発音数を増やしていくと、その分
107+ ISR() (Interrupt Service Routine: 割り込みサービスルーチン)における
108+ ループ回数が増え、多忙になってきます。あまりに多忙過ぎて loop() を実行する
109+ 暇がなくなると、動作不能に陥ります。そうなる寸前が、同時発音数の事実上の上限です。
110+
111+ ※ ISR() などで動作速度が要求されるため、PWMDAC_Synth.h には
112+ #pragma GCC optimize ("-O3")
113+ が指定されています。コンパイルの最適化基準を、このライブラリだけ速度優先にするためです。
107114
108115 特定のMIDIチャンネルに対しボイスアサインの優先度を上げることもできます。
109116 後述の「●チャンネル優先度指定」を参照。
@@ -126,27 +133,23 @@ Arduino
126133
127134 ●MIDIチャンネル操作
128135
129- PWM_SYNTH のメソッドで、
136+ PWMDACSynth::getChannel() で
130137
131138 MIDIチャンネル番号(1〜16) ⇔ MIDIチャンネルへのポインタ
132139
133- を相互変換できます。
134-
135- MidiChannel *getChannel(char channel)
136- char getChannel(MidiChannel *cp)
137-
138- MIDIチャンネルへのポインタを介してチャンネル単位に持たせる
139- パラメータを操作できます。
140+ を相互変換できます。MIDIチャンネルへのポインタを介して、
141+ チャンネル単位に持たせるパラメータを操作できます。
142+ (操作方法については PWMDAC_Synth.h を参照)
140143
141144 なお、ノートオン、ノートオフ、ピッチベンドなど、今出ている音
142- (アサインされているボイス)に即座に反映させるには、
143- MidiChannel ではなく PWMDACSynth のメンバ関数を呼び出す必要があります。
145+ (アサインされているボイス)に即座に反映させるには、PWMDACSynth のほうで
146+ 用意しているメンバ関数を呼び出し、チャンネルとボイスを同時に更新する必要があります。
144147
145148
146149 ●MIDI関数
147150
148- PWM_SYNTH 静的オブジェクトには、MIDIライブラリの MIDI.setHandleXxxx() に
149- 直接指定できるよう、引数の順序や型を合わせた関数をいくつか用意しています。
151+ PWMDACSynth で定義されたいくつかの static オブジェクトは、
152+ MIDIライブラリの MIDI.setHandleXxxx() に直接指定できる形式になっています。
150153
151154 ただし、接続相手のMIDIデバイスによっては、NOTE OFF の代わりに
152155 velocity=0 の NOTE ON を送ってくることがあるので、その場合だけ
@@ -158,39 +161,29 @@ Arduino
158161
159162 ●音色変更
160163
161- 波形とエンベロープパラメータ(ADSR)を MidiChannel クラスの
162- wavetable と env_param に指定することで、音色を変更できます。
163-
164- ADSRの設定は EnvelopeParam クラスを介して行います。
165- コンストラクタで次の値を指定して初期化できます。
166-
167- ・attack_time - アタック時間(大きいほどノートオン直後の立ち上がりがゆっくり)
168- ・decay_time - ディケイ時間(大きいほどノートオン後の減衰がゆっくり)
169- ・sustain_level - サスティンレベル(減衰が止まったあと維持する音量)
170- ・release_time - リリース時間(大きいほどノートオフ後の減衰がゆっくり)
171-
172- 値の範囲は sustain_level が 0〜255、それ以外は 0〜15 です。
173- 実時間は loop() 内で update() を呼び出す頻度によって変わります。
164+ 波形テーブルとADSRエンベロープパラメータを、それぞれ MidiChannel クラスの
165+ wavetable と envelope[] に指定することで、音色を変更できます。
174166
175- 各ADSRパラメータ値へのポインタは getParam() メソッドで取得できます。
167+ また、Instrument 構造体定数をプログラムメモリ領域に作り、それを
168+ programChange() に指定するだけで、波形とエンベロープを一度に設定できます。
169+ MIDIのプログラムチェンジを実装するときに便利です。
176170
171+ 【波形】 wavetable
177172 波形テーブルは、要素数256のbyte型PROGMEM配列として生成します。
178173 それを wavetable に指定することで、波形を切り替えることができます。
179-
180- 波形テーブル配列の生成は、PWMDAC_Synth.h 上で定義された
181- マクロを使い、必要な波形テーブルだけを生成してください。
182-
183- このマクロは、同時発音数が増えても信号レベルが255を超えて音割れせず、
184- かつ最大音量の出るような計算式になっています。
185- これに習って自分で波形を定義すれば、それを指定して
186- 独自の音色を生み出すことも可能です。
187-
188- プログラムメモリ領域に Instrument 構造体定数を作って、
189- それを指定することで音色を変更することもできます。
190- MIDIのプログラムチェンジの実装にはこの方法がおすすめです。
191- 現在のバージョンでは、プログラムチェンジ対応に伴い、
192- エンベロープの初期化に Instrument 構造体定数を使うインターフェースに
193- してRAMへの展開を最小限に抑えられるようにしました。
174+ 波形関数のマクロを PWMDAC_CREATE_WAVETABLE() マクロに指定するか、
175+ またはそれにならって自分で配列を定義することで、任意の波形を生成することが可能です。
176+
177+ ※ 波高は(255÷同時発音数:デフォルト6重和音のとき42)を超えないようにしてください。
178+ 同時発音数いっぱいに鳴らしたときに最大音量255を超えてオーバーフローし、ノイズが
179+ 発生する恐れがあります。
180+
181+ 【ADSRエンベロープ】 envelope[]
182+ ADSR_ATTACK_VALUE - アタック時間(0〜15、大きいほどノートオン直後の立ち上がりがゆっくり)
183+ ADSR_DECAY_VALUE - ディケイ時間(0〜15、大きいほどノートオン後の減衰がゆっくり)
184+ ADSR_SUSTAIN_VALUE - サスティンレベル(0〜255、減衰が止まったあと維持する音量)
185+ ADSR_RELEASE_VALUE - リリース時間(0〜15、大きいほどノートオフ後の減衰がゆっくり)
186+ 実時間は loop() 内で update() を呼び出す頻度によって変わります。
194187
195188
196189 ●チャンネル優先度指定
@@ -217,10 +210,6 @@ Arduino
217210 多重和音感が失われることがありますので、適宜調整してください。
218211
219212
220-●その他の関数
221-
222- その他、利用できる関数についてはソースコードのヘッダ PWMDAC_Synth.h を参照。
223-
224213
225214 作者:@きよし - Akiyoshi Kamide
226215 http://www.yk.rim.or.jp/~kamide/
--- a/keywords.txt
+++ b/keywords.txt
@@ -6,10 +6,8 @@
66 # Datatypes (KEYWORD1)
77 #######################################
88
9-EnvelopeParam KEYWORD1
109 Instrument KEYWORD1
1110 MidiChannel KEYWORD1
12-VoiceStatus KEYWORD1
1311 PWMDACSynth KEYWORD1
1412
1513 #######################################
@@ -24,7 +22,6 @@ pitchBend KEYWORD2
2422 controlChange KEYWORD2
2523 systemReset KEYWORD2
2624 getChannel KEYWORD2
27-setEnvelope KEYWORD2
2825 setPriority KEYWORD2
2926
3027 #######################################
@@ -35,3 +32,4 @@ PWMDAC_NOTE_A_FREQUENCY LITERAL1
3532 PWMDAC_POLYPHONY LITERAL1
3633 PWMDAC_OUTPUT_PIN LITERAL1
3734 PWMDAC_CHANNEL_PRIORITY_SUPPORT LITERAL1
35+