Cage-synth

Mij dansen de cijfertjes inmiddels voor mijn ogen, dus voor wie het wil nakijken :D :

Code:
<CsoundSynthesizer>

<CsOptions>
</CsOptions>

<CsInstruments>

sr = 44100
ksmps = 32
nchnls = 2
0dbfs  = 1

instr 1   
asig poscil .8, 220, 1   
     outs asig, asig
endin

</CsInstruments>


<CsScore>
f 1 0 390 7 829  10  829  0  37330  10 37330 0  41478 10  41478  0  31523  10  31523  0  42308 10 42308 0  3318 10 3318  0  18250  10 18250 0  34841 10  34841  0  60558  10  60558  0  38160 10 38160 0 13273 10 13273 0   7466  10  7466 0  8295  10   8295  0  45626  10  45626  0  21568 10 21568 0 53092 10 53092 0  29864  10 29864 0  33182 10  33182  0  51433  10  51433  0  20739 10 20739 0 15761 10 15761 0  53922  10 53922 0   1659 10   1659  0   9125  10   9125  0  17420 10 17420 0 63047 10 63047 0  19080  10 19080 0   6636 10   6636  0  36501  10  36501  0   4147 10  4147 0 55581 10 55581 0  10784  10 10784 0  26546 10  26546  0  14932  10  14932  0  16591 10 16591 0 25716 10 25716 0  43137  10 43137 0  40648 10  40648  0  59729  10  59729   

i 1 0 10
e
</CsScore>
</CsoundSynthesizer>

Audacity:

Audacity79.png



En het geluid:

 
Op het eerste gehoor klinken alle tot nog toe geproduceerde geluidjes als doktersbelletjes. Maar toen ik het laatste geluidje gisterenavond nog even in een sampler (ADSR, fliter en wat reverb) stopte klonk het lang niet gek! Een priem-synth zou dus vermoedelijk kunnen bestaan uit een rompler met een keuzeknop voor het priemgetal p en als gebruikte samples de (genormaliseerde) 65536-tallige representaties (voor CD-kwaliteit) van 1/p.
 
Hier het genormaliseerde wav-bestand van 1/79 voor wie er ook verder mee wil experimenteren:
 
Een stukje Handel afgespeeld in een sample player met het wav-bestandje van mijn vorige post:

 
Klinkt niet gek voor een 'doktersbelletjessynth'... :D Een filter is niet zo ingewikkeld om toe te voegen in je code, wat experimenteren met de coëfficiënten, of de waarden daarvoor gebruiken van een andere breuk, etc.
 
Voor 1/83 komt er als periode:

1 geeft cijfer: 789
2 geeft cijfer: 38689
3 geeft cijfer: 60798
4 geeft cijfer: 30004
5 geeft cijfer: 28425
6 geeft cijfer: 16581
7 geeft cijfer: 26056
8 geeft cijfer: 31583
9 geeft cijfer: 40269
10 geeft cijfer: 7106
11 geeft cijfer: 20529
12 geeft cijfer: 22898
13 geeft cijfer: 7895
14 geeft cijfer: 59219
15 geeft cijfer: 18160
16 geeft cijfer: 37900
17 geeft cijfer: 22108
18 geeft cijfer: 34741
19 geeft cijfer: 63956
20 geeft cijfer: 53692
21 geeft cijfer: 9475
22 geeft cijfer: 5527
23 geeft cijfer: 8685
24 geeft cijfer: 32373
25 geeft cijfer: 13423
26 geeft cijfer: 2368
27 geeft cijfer: 50533
28 geeft cijfer: 51323
29 geeft cijfer: 24477
30 geeft cijfer: 19739
31 geeft cijfer: 49744
32 geeft cijfer: 12633
33 geeft cijfer: 29214
34 geeft cijfer: 55271
35 geeft cijfer: 21318
36 geeft cijfer: 61588
37 geeft cijfer: 3158
38 geeft cijfer: 23687
39 geeft cijfer: 46585
40 geeft cijfer: 54481
41 geeft cijfer: 48165

Dat zou ook een interessant signaal kunnen zijn. Maar de grote vraag is dan of het heel veel anders dan 1/79 zal klinken...
 
Heb het Python progje even aangepast zodat het resultaat makkelijker voor het afspelen naar het Csound progje kan worden gekopieerd:

Code:
import mpmath as mp
from mpmath import *

mp.dps = 10000


n = 65536 #Voer base (=grondtal) in!


R = 1/(mp.mpf("89"))


for k in range(1,300):
    
    ck = int( ( (mp.mpf(n))**(mp.mpf(k)) ) * mp.mpf(R) )
    
    print( ck, 10 , ck, 0)

    
    R = R - (mp.mpf(ck)) * ( (mp.mpf(n))**(-mp.mpf(k)) )
 
Zojuist de geluiden voor nog wat andere priemgetallen uitgeprobeerd en ze zijn (na bewerking in de sample player) voldoende verschillend om interessant te zijn. :)
 
De eerste 30 priemgetallen zijn 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109 en 113.[1]
Bron: Priemgetal - Wikipedia

1/2 geeft: 0,[32768][0][0][0]...
1/3 geeft: 0,[21845][21845][21845]...
1/5 geeft: 0,[13107][13107][13107]...
1/7 geeft: 0,[9362][18724][37449][9362][18724][37449]...
1/11 geeft: 0,[5957][53620][23831][17873][29789][5957][53620][23831][17873][29789]...
1/13 geeft: 0,[5041][15123][45371][5041][15123][45371]...
1/17 geeft: 0,[3855][3855][3855]...

Niet alle priemgetallen zijn kennelijk voor de priem-synth even interessant...
 
Deze reeks geeft de langste perioden. Wel is het zo dat bij grotere getallen de priemgetallen die daar niet onder vallen juist weer interessant worden. Althans, dat vermoeden heb ik. De verdeling van de decimalen is waarschijnlijk in essentie willekeurig, dat je iets van tonen hoort komt omdat het maar een heel klein stukje is met voordurende herhaling. Bij veel grotere getallen en perioden krijg je witte ruis, mag je verwachten. Behalve dan in het geval van priemgetallen die niet in de reeks vallen beschreven in de link, die kunnen juist een korte periode hebben met een toonachtige kwaliteit. Makes sense? :D
 
Ik verwacht inderdaad ook dat je uiteindelijk voor langere perioden meestal binnen 1 periode zoveel variatie krijgt dat onze oren en hersens daar geen wijs meer uit worden.
 
Je bedoeling was me wel duidelijk. :-) En je kunt het ook rustig synthesizer noemen. Waar het mij meer om ging: als kastje met twee draaiknoppen en een toetsenbord zou ik de aanschaf niet overwegen, maar in de vorm van eurorack module wel.

Inmiddels heb ik een sample in wav-formaat gepost die je in een sample player kunt afspelen, dus als je een sample player in je Eurorack hebt kun je daarmee aan de slag. Zie: Cage-synth
 

Attachments

  • 79norm.wav
    1,7 MB
Mijn plan is nu om de "Priem-Synth 79" in Faust te programmeren, zodat die (hopelijk) cross-platform als plugin geëxporteerd kan worden. Ik gebruik Faust's online IDE: Faust IDE

Ik denk dat we dan dit nodig hebben: Faust Programming Language
 
Het voorbeeldprogje voor de boven gelinkte Waveform Primitive kun je in een tekstbestandje met extensie .dsp stoppen en dan naar de online IDE uploaden; van daaruit kun je het dan als VSTi plugin voor Windows exporteren. En dat werkt. Nu is het dan zaak dat voorbeeldprogje zodanig te versleutelen dat het een priem-synth wordt. Hier is het voorbeeldprogje:

Code:
import("stdfaust.lib");
triangleWave = waveform{0,0.5,1,0.5,0,-0.5,-1,-.5};
triangleOsc(f) = triangleWave,int(os.phasor(8,f)) : rdtable;
f = hslider("freq",440,50,2000,0.01);
process = triangleOsc(f);
 
Code:
import("stdfaust.lib");
priemWave = waveform{829, 37330, 41478, 31523, 42308, 3318, 18250, 34841, 60558, 38160, 13273, 7466, 8295, 45626, 21568, 53092, 29864, 33182, 51433, 20739, 15761, 53922, 1659, 9125, 17420, 63047, 19080, 6636, 36501, 4147, 55581, 10784, 26546, 14932, 16591, 25716, 43137, 40648, 59729};
priemOsc(f) = priemWave,int(os.phasor(39,f)) : rdtable : _ - 31000 : _*(0.00002) ;
f = hslider("freq",440,10,2000,0.01);
process = priemOsc(f);

Dit lijkt er al op en geeft als vast toon de 65536-tallige representatie van 1/79. Het normaliseren heb ik voor het gemak maar op het oog gedaan m.b.v. van het oscilloscoopje op de online IDE. Eventueel bereken ik die normalisatie later nog eens exact, maar voor het geluid zal dat niet veel uitmaken.
 
Het geluidje van de plugin:



En zo ziet het eruit:

priem79.png



En dat lijkt als twee druppels water op mijn eerdere resultaat met Csound: Cage-synth 8)
 
Laatst gewijzigd:
Nu moet er nog een synth van gemaakt worden. Misschien kan dat door dit voorbeeld-progje om te bouwen:

Code:
// tosc.dsp - test simple oscillator + MIDI bindings
import("stdfaust.lib");
process = g * a * os.oscrs(f*b) <: _,_;
a = hslider("gain [midi:ctrl 7]",1,0,1,0.001);
f = hslider("freq",392.0,200.0,450.0,0.01);
b = ba.semi2ratio(hslider("bend [midi:pitchwheel]",0,-2,2,0.001));
g = button("gate");
 
OK - dit werkt maar klinkt nog erg scherp en mechanisch:

Code:
import("stdfaust.lib");

priemWave = waveform{829, 37330, 41478, 31523, 42308, 3318, 18250, 34841, 60558, 38160, 13273, 7466, 8295, 45626, 21568, 53092, 29864, 33182, 51433, 20739, 15761, 53922, 1659, 9125, 17420, 63047, 19080, 6636, 36501, 4147, 55581, 10784, 26546, 14932, 16591, 25716, 43137, 40648, 59729};

priemOsc(f) = priemWave,int(os.phasor(39,f)) : rdtable : _ - 31000 : _*(0.00002) ;

f = hslider("freq",440,10,2000,0.01);

process = g * a * priemOsc(f*b) <: _,_;

a = hslider("gain [midi:ctrl 7]",1,0,1,0.001);
b = ba.semi2ratio(hslider("bend [midi:pitchwheel]",0,-2,2,0.001));
g = button("gate");

 
Ik begrijp niet goed waarom het progje uit het vorige bericht überhaupt op MIDI reageert, want ik zie niet bij welke stappen in het programma die MIDI-info dan wordt binnengehaald.

Nog wat verder geëxperimenteerd en het ziet ernaar uit dat MIDI de uitkomst van de sliders bepaalt, maar dan wel enkel voor zover MIDI binnen het minimum en maximum van de betreffende sliders blijft.

Nog wat op internet gezocht: MIDI Support - Faust Documentation (Dat nu eerst eens bestuderen...)
 
Laatst gewijzigd:
Back
Top