«Re: DWG sitar model» by 56228375

on 10 Aug'17 08:55 in guitarcode forkinstrumentphysical modelplucked stringsplucksitar

fork of a sitar model by @snappizz... it sounds better to me although I have no idea how it's supposed to sound. Modifications are in the plucking (while playing with the example I found that the envelope and spectrum of the plucking has a significant influence on the resulting sound - I went for a sharper sound) and I added a GVerb for additional metallic resonance.

Feel free to further improve :)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
/*
Based on a model by David Ronan (http://issta.ie/wp-content/uploads/The-Physical-Modelling-of-a-Sitar.pdf).
Requires sc3-plugins.

Lacks shimmer. Sounds more like a banjo than a sitar. I don't know whether
this is just a matter of tuning parameters or whether the model itself needs
fixing.
*/

(
s.waitForBoot({
	// Single string of a sitar.
	SynthDef(\tar, {
		|
		out = 0, in = 0, inscale = 1.0, freq = 440, bw = 1.03, amp = 0.5
		pos = 0.1,
		hc1 = 1, hc3 = 30, hfreq = 3000,
		vc1 = 1, vc3 = 30, vfreq = 3000
		|
		var inp, jawari, snd;
		// Input audio -- may be a pluck impulse (chikari) or audio (tarafdar)
		inp = In.ar(in, 1) * inscale;
		// Jawari (bridge) simulation. This is the heart of Ronan's model.
		// Violins and guitars have vertical bridges. The jawari is flat, and this causes the tar to buzz against the jawari.
		// Physically, end of the string coming in contact the bridge causes the string to shorten.
		// We assume that the audio output is a reasonable approximation of how much contact the string has with the bridge.
		// So we shorten the DWG (by adjusting its frequency) according to its own audio output.
		jawari = LocalIn.ar(1);
		// Make the jawari control rate
		jawari = A2K.kr(jawari);
		// Make the jawari affect the freq exponentially
		jawari = jawari.linexp(-1, 1, bw.reciprocal, bw);
		// The string itself has horizontal and vertical planes, which we simulate with two different DWGPlucked instances
		snd = [
			DWGPlucked.ar(freq * jawari, pos: pos, c1: hc1, c3: hc3, inp: LPF.ar(inp, hfreq)),
			DWGPlucked.ar(freq * jawari, pos: pos, c1: vc1, c3: vc3, inp: LPF.ar(inp, vfreq))
		].sum;
		LocalOut.ar(snd);
		Out.ar(out, snd * amp);
	}).add;

	SynthDef(\pluckImpulse, {
		|out = 0, t_trig = 0, amp = 0.3|
		Out.ar(out, PinkNoise.ar * EnvGen.kr(Env.perc(0.01, 0.02), t_trig) * amp);
	}).add;

	// Useful for testing. For programmatic usage use \pluckImpulse
	SynthDef(\mousePluck, {
		|out = 0, num = 0, amp = 0.3|
		var m = MouseY.kr(0, 8);
		var trig = (num <= m) & (m < (num + 1)) * MouseButton.kr(0, 1, 0);
		Out.ar(out, HPF.ar(WhiteNoise.ar, 400) * EnvGen.kr(Env.perc(0.001, 0.03, 0.5), trig) * amp);
	}).add;

	SynthDef(\sitar, {
		|out = 0, chikari = 0, tarafdar = 0, dry = 0.5, wet = 0.5, amp = 0.5|
		var snd = In.ar(chikari, 1) * dry;
		var lfo;
		snd = snd + (In.ar(tarafdar, 1) * wet);
		// Dumb gourd model. I randomly picked lope only transitions to the release node when released. Examples are below. Tfreqs/bws/amps.
		// Please let me know if you have some estimates of the resonances of a real sitar gourd.
		snd = snd + BPF.ar(snd, [90, 132, 280], [1.3, 0.9, 1.4], [0.9, 0.6, 0.7]).sum;
		snd = Pan2.ar(GVerb.ar(0.3*snd, roomsize:1, damping:0.7), 0, amp);
		Out.ar(out, snd);
	}).add;

	s.sync;

	// Don't take this example tuning seriously.
	// I know next to nothing about ragas and sitar tuning.
	~chikariFreqs = 48.midicps * [1, 16/15, 5/4, 4/3, 3/2, 8/5, 15/8, 2];
	~numChikari = ~chikariFreqs.size;
	~tarafdarFreqs = 48.midicps * [1, 16/15, 5/4, 4/3, 3/2, 8/5, 15/8, 2, 2*16/15, 2*5/4, 2*4/3, 2*3/2];
	~numTarafdar = ~tarafdarFreqs.size;

	// Pluck impulse busses, one per chikari
	~pluckBus = Bus.audio(s, ~numChikari);
	// Summed output of all chikari (plucked strings)
	~chikariBus = Bus.audio(s, 1);
	// Summed output of all tarafdar (sympathetic strings)
	~tarafdarBus = Bus.audio(s, 1);

	~pluckGroup = Group();
	~chikariGroup = Group.after(~pluckGroup);
	~tarafdarGroup = Group.after(~chikariGroup);

	~pluck = ~numChikari.collect { |i|
		Synth(\mousePluck, [
			\out, ~pluckBus.index + i,
			\num, i,
		], ~pluckGroup);
	};
	~chikari = ~numChikari.collect { |i|
		Synth(\tar, [
			\in, ~pluckBus.index + i,
			\out, ~chikariBus,
			\freq, ~chikariFreqs[i],
			\bw, 1.08,
			\hc1, 4, \hc2, 50,
			\vc1, 3, \vc3, 30,
			\amp, 0.1
		], ~chikariGroup);
	};
	~tarafdar = ~numTarafdar.collect { |i|
		Synth(\tar, [
			\in, ~chikariBus,
			\inscale, 0.1,
			\out, ~tarafdarBus,
			\freq, ~tarafdarFreqs[i] * 1.0.rand.linexp(0, 1, 0.99, 1.01),
			\pos, 0.4,
			\bw, 1.08,
			\hc1, 4, \hc2, 50,
			\vc1, 3, \vc3, 30,
			\amp, 0.1
		], ~tarafdarGroup);
	};
	~sitar = Synth.after(~tarafdarGroup, \sitar, [
		\chikari, ~chikariBus,
		\tarafdar, ~tarafdarBus,
		\dry, 1,
		\wet, 0.5,
		\amp, 0.8
	]);
});
)
raw 4402 chars (focus & ctrl+a+c to copy)
reception
comments
badnumbersmusic user 14 Sep'17 15:30

Oh my goodness. That is stunning.

snappizz user 16 Sep'17 23:46

yessss! much better!

olilarkin user 17 Sep'17 12:41

form a band:

https://github.com/olilarkin/Tambura