aboutsummaryrefslogtreecommitdiff
path: root/sonics/instrument_portchord.udo
blob: 1948f6e5db197185f206c1cdbc9dfe9f5b75d589 (plain)
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
#ifndef UDO_FNMI_PORTCHORD
#define UDO_FNMI_PORTCHORD ##
/*
	Portamento recursive chord players
	Slim excerpt for Partial Emergence

	This file is part of the SONICS UDO collection by Richard Knight 2021
		License: GPL-2.0-or-later
		http://1bpm.net
*/

#include "sonics/sequencing_melodic_persistence.udo"
#include "sonics/sequencing_melodic_portamento.udo"
#include "sonics/wavetables.udo"
#include "sonics/soundxdb.udo"




/*
	Play continuous chords from melodic sequencer with portamento, using a sounddb collection as source sounds

	aL, aR portchord_sound icollectionid [, imode=1, ifreqmult=1, ifftsize=giFFTsize, index=0]

	aL, aR			stereo outputs
	icollectionid	collection ID from sounddb to use for the playback
	imode			0 = read with sndwarp; 1 = read with mincer
	ifreqmult		frequency multiplier of the chord note frequencies to be applied
	ifftsize		FFT size to use when imode = 1 ; default to global setting in __config__.udo
	index			internal start index of the chord notes; could also be used to specify starting note offset
*/
opcode portchord_sound, aa, ippjo
	icollectionid, imode, ifreqmult, ifftsize, index xin

	ifftsize = (ifftsize == -1) ? 512 : ifftsize

	inote = round(random(50, 80))
	ibasefreq = cpsmidinn(inote)
	ifileid, ipitchratio sounddb_mel_nearestnote icollectionid, inote

	ifn = gisounddb[ifileid][0]
	ichannels = gisounddb[ifileid][1]
	idur = gisounddb[ifileid][2]
	irmsnorm = gisounddb[ifileid][3]

	kampb table index, gimel_amps
	kfreq table index, gimel_freqs

	kamp portk kampb, (i(gkseq_beattime) * gimel_portamento_beatratio) ; fade out when change

	kpitch = (kfreq / ibasefreq) * ifreqmult ; actual pitch adjustment

	istart = random(0.05, 0.2)
	iend = random(istart+0.1, 0.8) 
	

	if (kamp != 0) then
		atime = abs(oscil(iend - istart, random(0.001, 0.1), gifnSine, random(0, 1))) + istart
		klfo = oscil:k(random(0.0001, 0.009), random(1, 5)) + 1
		kpitch *= klfo

		if (imode == 0) then
			kpitch *= (ftsr(ifn) / sr) ; adjustment for sndwarp required
			
			;apitch interp kpitch
			aL, aR sndwarpst kamp, atime, kpitch, ifn, istart, 4410, 441, 8, gifnHalfSine, 1

		else
			if (ichannels == 2) then
				aL, aR mincer atime, kamp, kpitch, ifn, 0, ifftsize
			else
				aL mincer atime, kamp, kpitch, ifn, 0, ifftsize
				aR = aL
			endif
		endif
	endif

	aL *= (1 - irmsnorm) * 0.5
	aR *= (1 - irmsnorm) * 0.5

	; recursion for all chord parts
	if (index + 1 < ftlen(gimel_amps)) then
		aLx, aRx portchord_sound icollectionid, imode, ifreqmult, ifftsize, index + 1
		aL += aLx
		aR += aRx
	endif
	xout aL, aR
endop




#end