out.playNote
は鳴らす長さを入れて音を出すみたいなので、任意の長さで鳴らすのはちょっと難しそうですねぇ(何か方法はあるかもしれませんが)
代わりにMidiで鳴らすのはどうでしょう?最近のPCであれば標準で対応しているはずです。
Processing
1import themidibus.*; // 注1
2import ddf.minim.ugens.Frequency;
3
4MidiBus myBus;
5HashMap<String, Boolean> pressedKeys = new HashMap<String, Boolean>();
6
7void setup() {
8 size(600, 400);
9 MidiBus.list();
10 myBus = new MidiBus(this, -1, 1); // 注2
11 myBus.sendMessage(192, 3); // 注3
12}
13
14void draw() {
15}
16
17void keyPressed() {
18 String pitchName = getPitchName();
19 if (pitchName == null) return;
20 if (pressedKeys.getOrDefault(pitchName, false)) return;
21
22 myBus.sendNoteOn(0, (int) Frequency.ofPitch(pitchName).asMidiNote(), 127);
23 pressedKeys.put(pitchName, true);
24}
25
26void keyReleased() {
27 String pitchName = getPitchName();
28 if (pitchName == null) return;
29
30 myBus.sendNoteOff(0, (int) Frequency.ofPitch(pitchName).asMidiNote(), 127);
31 pressedKeys.put(pitchName, false);
32}
33
34String getPitchName() {
35 switch (key) {
36 case 'z': return "C4";
37 case 's': return "C#4";
38 case 'x': return "D4";
39 case 'd': return "D#4";
40 case 'c': return "E4";
41 case 'v': return "F4";
42 case 'g': return "F#4";
43 case 'b': return "G4";
44 case 'h': return "G#4";
45 case 'n': return "A4";
46 case 'j': return "A#4";
47 case 'm': return "B4";
48 }
49
50 return null;
51}
注1
The MidiBus
を「ライブラリを追加」からインストールしてください。
注2
プログラムを実行したときに、
Available MIDI Devices:
----------Input----------
[0] "Real Time Sequencer"
----------Output----------
[0] "Gervill"
[1] "Microsoft MIDI Mapper"
[2] "Microsoft GS Wavetable Synth"
[3] "Real Time Sequencer"
のよう表示が出ます。
音が出なかったときはnew MidiBus(this, -1, 1)
の1
を、Output
にある数字の中から変えて試してください。
注3
sendMessage(192, 3)
の3
は音色です(192
は気にしないでいいです)
楽器のNo.
の数字からいろいろ試してみてください。
追記
やっぱり気になったのでminimバージョンも。無駄にややこしくしてる気もする^^;
Processing
1import ddf.minim.spi.*;
2import ddf.minim.signals.*;
3import ddf.minim.*;
4import ddf.minim.analysis.*;
5import ddf.minim.ugens.*;
6import ddf.minim.effects.*;
7
8Minim minim;
9AudioOutput out;
10HashMap<String, Keyboard> pressedKeys = new HashMap<String, Keyboard>();
11
12void setup() {
13 size(600, 400);
14 minim = new Minim(this);
15 out = minim.getLineOut();
16}
17
18void draw() {
19}
20
21void keyPressed() {
22 String pitchName = getPitchName();
23 if (pitchName == null) return;
24
25 Keyboard k = pressedKeys.get(pitchName);
26 if (k == null) {
27 k = new Keyboard(pitchName);
28 pressedKeys.put(pitchName, k);
29 }
30
31 k.noteOn();
32}
33
34void keyReleased() {
35 String pitchName = getPitchName();
36 if (pitchName == null) return;
37
38 pressedKeys.get(pitchName).noteOff();
39}
40
41String getPitchName() {
42 switch (key) {
43 case 'z': return "C4";
44 case 's': return "C#4";
45 case 'x': return "D4";
46 case 'd': return "D#4";
47 case 'c': return "E4";
48 case 'v': return "F4";
49 case 'g': return "F#4";
50 case 'b': return "G4";
51 case 'h': return "G#4";
52 case 'n': return "A4";
53 case 'j': return "A#4";
54 case 'm': return "B4";
55 }
56
57 return null;
58}
59
60class Keyboard {
61 Oscil osc;
62 boolean pressed;
63
64 Keyboard(String pitchName) {
65 osc = new Oscil(Frequency.ofPitch(pitchName), 1.0, Waves.SAW);
66 }
67
68 void noteOn() {
69 if (pressed) return;
70
71 osc.patch(out);
72 pressed = true;
73 }
74
75 void noteOff() {
76 osc.unpatch(out);
77 pressed = false;
78 }
79}
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/12/21 07:22
2019/12/21 07:33