Schrijf je eigen soft-synth!

Trouwens voor het schrijven van eenvoudige, maar toch zeer krachtige filters die ook redelijk goed verklaarbaar zijn, heb je nauwelijks enige DSP-kennis nodig, dat bewijst de al genoemde Sound Design cursus voor scholieren.
Ook het allerbelangrijkste en meest veelzijdige filter in spraak en muziek, het 2de-orde resofilter, is goed te bespreken (al gebeurt dat niet in de Sound Design cursus).

Zelf een gebruiker van synthedit. Ik ga dit verhaal van het weekend eens lezen. Maar, geen vst export? Dit vond ik niet zo snel terug op de waveguide site.

Bye

AlternatieveX
 
Hmmm, beetje raar verhaal dit. Ik ken een aantal mensen die zelf plugins ontwikkelen en daarbij toch echt wel de nodige ervaringen nodig hebben op het gebied van geluidstechniek en -synthese, natuur- en wiskunde en de nodige aanvullende specifieke DSP kennis.

Daarnaast draait het bij het ontwikkelen van plugins voor een heel groot gedeelte ook om het efficient omgaan met geheugen. En daar heb je feitelijk alleen echt controle over als je zo dicht mogelijk tegen de hardware aan zit te praten. C / C++ zijn hiervoor het beste geschikt (tenzij je assembly wilt gaan schrijven). Zelfs de Microsoft talen zoals bijvoorbeeld C# of VB.NET worden hiervoor sterk afgeraden.

Ik zeg hiermee niet dat het niet zou kunnen, maar het gaat om wat het beste is. Het aan elkaar knopen van bestaande componenten met voorgedefinieerd algoritmen, dat kan natuurlijk met bestaande pakketten zoals bijv. Reaktor. Welke daar ook uitermate goed voor zijn. Iets meer met wiskundige insteek is Max/MSP.

Om spelenderwijs een beetje iets te leren over sound design en instrument ontwerp is het wel ok. Maar ik denk dat je redelijk aan het oversimplificeren bent als je denkt met een paar bladzijden info en wat eenvoudige software kwalitatief volwaardige (geluid en performance) plugins en instrumenten zou kunnen maken.

Maar da's mijn mening natuurlijk.
 
Hoewel ik je vraag totaal niet begrijp:?:?:?:?:?:?:?:?:?
durf ik met absolute zekerheid te beweren dat een toongenerator geen paradox is!, (laat staan een instabiele, wat je daaronder in vredesnaam ook moge verstaan).

Maar ik ben wel echt heel benieuwd hoe je op die vraag komt! Kun je er wat meer over kwijt? Ik kan je gedachtengang niet volgen!

Verder is de code voor een primtieve toongenerator vreselijk simpel. Maar eentje waar echt muziek in zit, dat is heel iets anders!
Deze draad is juist bedoeld om je een idee te geven van wat wel en wat niet moeilijk te maken is.

Sander02 mengt twee zaken die eigenlijk niets met elkaar te maken hebben : de praktische toepassing van een oscillator en de logische beschrijving van omgekeerde terugkoppeling.

Hardwarematig kan een oscillator gebouwd worden met een terugkoppelings-circuit (de uitgang van een signaal-versterker/verwerker wordt al dan niet bewerkt -vb omgekeerd - teruggekoppeld naar de ingang, waardoor de uitgang beïnvloed wordt, en bvb gaat oscilleren door de vertraging die optreed in de terugkoppeling).

Als je zo'n circuit (met een negatief teruggekoppelde uitgang) logisch gaat beschrijven dan krijg je dat "de uitgang evenredig is met het ingangssignaal en omgekeerd evenredig met zichzelf. En dat is wat het Wikipedia-artikel een instabiele paradox noemt.


grtz.
D.
 
Een simpel basic-code-voorbeeldje

Een simpel basic-code-voorbeeldje

For i = 1 to 360
a = sin(i)
Print a
Next i

Wel hierboven een heel simpel basic-code-voorbeeldje om de waarde van een sinus uit te printen...
Nu is het in deze topic niet de bedoeling iets te visualiseren maar auditief weer te geven.
'Hoe maak ik een toongenerator?'
Mijn vraag is dan wie kan deze code aanpassen zodat je inderdaad iets realtime gaat horen i.p.v. zien op het scherm (onder Windows).
Dit zou toch een 'zeer eenvoudige opdracht' moeten zijn (... ik ben er nog niet in geslaagd :stupid)
Opgelet er mankeert nog wel wat : geen toonhoogtebepaling en geen volumebepaling.
 
Laatst gewijzigd:
Dank Rael! dat bedoelde ik inderdaad.. dat ik 2 zaken door elkaar haalde had ik niet in de gaten, weet ook niet meer hoe ik daar terecht kwam.

Ik dacht toen ik dat las, dat zo'n vergelijking (wellicht op de achtergrond) de toongeneratie in gang zou zetten als je zoiets dergelijks codeert, maar zo diep en moeilijk is het gelukkig dan weer net niet. :)

Onder het kopje "praktijk vs theorie" stond er:
Goed gedimensioneerd leidt dit echter tot een stabiel systeem in plaats van een tegenstrijdigheid. Echter, als instabiel systeem kan dit proces ook gebruikt worden als oscillator.

Ook stellingen uit de formele logica, de grondslagen van de wiskunde en de theoretische informatica vertonen overeenkomsten met paradoxen. Voorbeelden hiervan zijn de onvolledigheidsstelling van Gödel en het beslissingsprobleem.
Vandaar m'n gedachtegang.. sorry voor de verwarring, het was wat vergezocht hehe
 
Mijn vraag is dan wie kan deze code aanpassen zodat je inderdaad iets realtime gaat horen i.p.v. zien op het scherm (onder Windows).
Dit zou toch een 'zeer eenvoudige opdracht' moeten zijn (... ik ben er nog niet in geslaagd :stupid)
Opgelet er mankeert nog wel wat : geen toonhoogtebepaling en geen volumebepaling.

Wat voor basicsmaak gebruik je? Het is waarschijnlijk niet zo makkelijk als je denkt; je moet gaan nadenken over geluidskaarten, buffersizes, samplefrequenties, sampleformaten, channels etc. Ik weet niet of jouw basicsmaak daar faciliteiten voor biedt (maar Google weet dat vast:)).
 
met basic ga je het in ieder geval niet redden, en al helemaal nie in een for next loop.
dat gaat wel met pascal, c+ en assembler.
ik ben zelf al een aantal jaren bezig met praktisch bruikbare dco´s te programmeren, en gebruik daarvoor wavetables.
zet de golfvorm in een tabel, en lees die uit in de gewenste frequentie.
en voor polyfonie, voor iedere toon met een andere freq uitlezen.
( dit is wel erg simpel uitgelegt, maar is wel een basis)

:mega:


For i = 1 to 360
a = sin(i)
Print a
Next i

Wel hierboven een heel simpel basic-code-voorbeeldje om de waarde van een sinus uit te printen...
Nu is het in deze topic niet de bedoeling iets te visualiseren maar auditief weer te geven.

Mijn vraag is dan wie kan deze code aanpassen zodat je inderdaad iets realtime gaat horen i.p.v. zien op het scherm (onder Windows).
Dit zou toch een 'zeer eenvoudige opdracht' moeten zijn (... ik ben er nog niet in geslaagd :stupid)
Opgelet er mankeert nog wel wat : geen toonhoogtebepaling en geen volumebepaling.
 
Realtime geluidscode...

Realtime geluidscode...

met basic ga je het in ieder geval niet redden, en al helemaal nie in een for next loop.
dat gaat wel met pascal, c+ en assembler.
Ik weet dat het ook met basic talen kan (Power Basic en diegene die ik gebruik is GFA-BASIC 32). Qua snelheid zijn die ruim voldoende, zoniet soms sneller dan vele C versies ! (Dat kan en mag jezelf uittesten als je dat niet gelooft). Bovendien hebben beiden ook een inline assembler mogelijkheid. Het gaat enkel om de juiste code die de juiste poort aanspreekt.
En waarom niet in een for next loop ? Do While o.i.d. kan ook hoor, het is een 'simpel voorbeeldje'.

ik ben zelf al een aantal jaren bezig met praktisch bruikbare dco´s te programmeren, en gebruik daarvoor wavetables.
zet de golfvorm in een tabel, en lees die uit in de gewenste frequentie.
en voor polyfonie, voor iedere toon met een andere freq uitlezen.
Dat zou dan toch iets van realtime moeten zijn hé (praktisch bruikbare DCO, wel zonder FM-mogelijkheid dan...).

Heb je een voorbeeldje van code in C (of basic, met of zonder tabel, die maak ik zelf wel) ?

Wat voor basicsmaak gebruik je? Het is waarschijnlijk niet zo makkelijk als je denkt; je moet gaan nadenken over geluidskaarten, buffersizes, samplefrequenties, sampleformaten, channels etc. Ik weet niet of jouw basicsmaak daar faciliteiten voor biedt (maar Google weet dat vast:)).
GFA-BASIC 32 v2.3.1165
Gratis download van volledig werkende versie :
http://www.freewarefiles.com/GFA-BASIC-32_program_50033.html

Ja alle API-functies kunnen gebruikt worden en ik kan mijn geluidskaart functies aanroepen en uitlezen.
Ik kan er ook een bufferblok naar toe sturen maar ik zou realtime golfvorm creaties willen.
 
Laatst gewijzigd:
(...) Ja alle API-functies kunnen gebruikt worden en ik kan mijn geluidskaart functies aanroepen en uitlezen.
Ik kan er ook een bufferblok naar toe sturen maar ik zou realtime golfvorm creaties willen.

Realtime betekent niet dat je vanuit je programmatje bepaalt wanneer ie een bepaald sample moet spelen. Dat werkt ook niet, want als je PC dan even 1ms iets anders aan het doen is, heb je al een underrun. Uiteindelijk bepaalt je geluidskaart namelijk wanneer een sample wordt afgespeeld, niet jouw programmatje.

Realtime betekent in informaticatermen dat je software+hardware garandeert dat je binnen een bepaald tijdsbestek reageert op een seintje. In die zin is het afspelen van audio altijd "realtime", maar dat hoeft nog niet te betekenen dat het 0ms latency heeft. 0ms latency zul je met je PC met een gewone audiointerface nooit bereiken. Je kunt wel proberen de buffersize op 1 sample te zetten, maar dan heb je nog 1 sample latency, bovendien zal je PC dat niet zo goed trekken. En je hebt er niet zoveel aan. Tussen het moment dat het geluid je monitors verlaat en het moment dat het je oor bereikt zit immers ook al gauw 3ms...

Dus je moet gewoon de API gebruiken en een buffer sturen. Wil je lage latency, dan maak je die buffer zo klein mogelijk. Maar niet te klein:)

Verder met je eens: het moet prima met basic lukken, het gaat erom hoe goed je compiler is. Maar ook eens met j.baars: je gaat uiteindelijk tegen beperkingen aanlopen.
 
sommige basics zijn idd behoorlijk snel, dat is zeker.
zelfs de qbasic compiler.
meer wat ik meer bedoelde, als je een complete synth applicatie in basic zou schrijven, dan kon het wel eenst te traag zijn.
zeker als windows ook nog in de weg zit.
wat wel meestal goed werkt is inline assembly, maar ja, dat is dus assembler, geen basic.
code voorbeelden heb ik zo even niet bij de hand, maar bedenk die zelf.
voor wavetabel uitlezen staat de code prakties al omschreven in mijn voorbeeldzin....

maar laat eens wat horen als je zover bent, ik ben wel benieuwd.

:koffie:

Ik weet dat het ook met basic talen kan (Power Basic en diegene die ik gebruik is GFA-BASIC 32). Qua snelheid zijn die ruim voldoende, zoniet soms sneller dan vele C versies ! (Dat kan en mag jezelf uittesten als je dat niet gelooft). Bovendien hebben beiden ook een inline assembler mogelijkheid. Het gaat enkel om de juiste code die de juiste poort aanspreekt.
En waarom niet in een for next loop ? Do While o.i.d. kan ook hoor, het is een 'simpel voorbeeldje'.


Dat zou dan toch iets van realtime moeten zijn hé (praktisch bruikbare DCO, wel zonder FM-mogelijkheid dan...).

Heb je een voorbeeldje van code in C (of basic, met of zonder tabel, die maak ik zelf wel) ?


GFA-BASIC 32 v2.3.1165
Gratis download van volledig werkende versie :
http://www.freewarefiles.com/GFA-BASIC-32_program_50033.html

Ja alle API-functies kunnen gebruikt worden en ik kan mijn geluidskaart functies aanroepen en uitlezen.
Ik kan er ook een bufferblok naar toe sturen maar ik zou realtime golfvorm creaties willen.
 
met basic ga je het in ieder geval niet redden, en al helemaal nie in een for next loop.
dat gaat wel met pascal, c+ en assembler.
ik ben zelf al een aantal jaren bezig met praktisch bruikbare dco´s te programmeren, en gebruik daarvoor wavetables.
zet de golfvorm in een tabel, en lees die uit in de gewenste frequentie.
en voor polyfonie, voor iedere toon met een andere freq uitlezen.
( dit is wel erg simpel uitgelegt, maar is wel een basis)

:mega:

Een kleine anecdote: toen ik met mijn sine DCO bezig was, ben ik begonnen met de golfvorm gewoon uit te rekenen (als 64 bit double). Dat werkte prima, maar echt snel was het niet. De volgende stap was - dacht ik - een wavetable (van 200kB). Werkte ook prima, maar ook dat was niet echt snel. Na wat profiling kwam ik erachter dat het uitrekenen van een sinus op een pentium4 precies even lang duurt als het opzoeken in een wavetable. Alleen is de Level1 cache op een pentium4 maar 8kB en daar paste mijn wavetable niet in zijn geheel in. Netto resultaat was dat de wavetable-oplossing langzamer was.

Voor simpeler golfvormen dan de sinus (pulse, square, saw, triangle) is het verschil nog veel groter. Mijn uiteindelijke conclusie: je kunt voor reguliere golfvormen en alle mengelingen daarvan op moderne PC-hardware beter "zelf" rekenen dan een wavetable gebruiken. Uiteindelijk gebruik ik nu 32 bits floats berekeningen en geen enkele wavetable meer en pers ik enkele tientallen voices polyfonie uit een oud pentium4tje.

Dedicated DSP-hardware zal wel veel betere oplossingen hebben voor wavetables en voor complexere golfvormen/samples ben je natuurlijk sowieso aangewezen op wavetables, maar voor mij was dit wel een kleine openbaring. CPUs worden veel sneller sneller dan geheugen en het zal dus voorlopig wel zo blijven.
 
Wat voor basicsmaak gebruik je? Het is waarschijnlijk niet zo makkelijk als je denkt; je moet gaan nadenken over geluidskaarten, buffersizes, samplefrequenties, sampleformaten, channels etc. Ik weet niet of jouw basicsmaak daar faciliteiten voor biedt (maar Google weet dat vast:)).

Waar het om draait is dat je data vanuit je ontwikkelomgeving (wat die ook is, C++, basic etc) doorsluist naar het audio-systeem en daar zit altijd het operating system tussen, voor de meesten zal dat Windows zijn.

Je moet dus een ontwikkelomgeving hebben die je in staat stelt om rechtstreeks met de Windows-audio-doorsluisfuncties te praten. Het beste is C of C++, want dat is de taal waarin Windows is geformuleerd.

De communicatie verloopt via interrupts. Windows geeft jouw software een seintje als een pakket samples verstuurd is van of naar audio, zodat je nieuwe data kunt opsturen of ontvangen.
 
Ik weet niet hoeveel polyfonie je eruit kan persen, maar de uberbasis oscillator die een sinus uitrekent en via Directsound functies hoorbaar maakt, loopt zelfs onder visual basic 6 (dat onterecht de naam heeft traag te zijn; het is behoorlijk snel als je van de VBTimers afblijft) netjes in realtime.

Nu kom je met DirectSound8 standaardfuncties niet zover, want je kan dan enkel kiezen om ofwel FM ofwel AM toe te passen. Dus moet je creatief worden.
 
met rekenen gaat het idd sneller dan met wavetables, dat heb ik ook al eens gemerkt.
maar aangezien ik dicht bij de 8bit basis wil blijven, met sampleopties, zit ik een beetje aan het wavetable gebeuren vast gebakken.
en ik vindt het ook wat makkelijker werken om verschillende waveforrms/samples op alle mogelijken manieren met mekaar leuke dingen te laten doen.
:koffie:

Een kleine anecdote: toen ik met mijn sine DCO bezig was, ben ik begonnen met de golfvorm gewoon uit te rekenen (als 64 bit double). Dat werkte prima, maar echt snel was het niet. De volgende stap was - dacht ik - een wavetable (van 200kB). Werkte ook prima, maar ook dat was niet echt snel. Na wat profiling kwam ik erachter dat het uitrekenen van een sinus op een pentium4 precies even lang duurt als het opzoeken in een wavetable. Alleen is de Level1 cache op een pentium4 maar 8kB en daar paste mijn wavetable niet in zijn geheel in. Netto resultaat was dat de wavetable-oplossing langzamer was.

Voor simpeler golfvormen dan de sinus (pulse, square, saw, triangle) is het verschil nog veel groter. Mijn uiteindelijke conclusie: je kunt voor reguliere golfvormen en alle mengelingen daarvan op moderne PC-hardware beter "zelf" rekenen dan een wavetable gebruiken. Uiteindelijk gebruik ik nu 32 bits floats berekeningen en geen enkele wavetable meer en pers ik enkele tientallen voices polyfonie uit een oud pentium4tje.

Dedicated DSP-hardware zal wel veel betere oplossingen hebben voor wavetables en voor complexere golfvormen/samples ben je natuurlijk sowieso aangewezen op wavetables, maar voor mij was dit wel een kleine openbaring. CPUs worden veel sneller sneller dan geheugen en het zal dus voorlopig wel zo blijven.
 
Ik kan er ook een bufferblok naar toe sturen maar ik zou realtime golfvorm creaties willen.


1) Thread bouwen met daarin een toongenerator loop die in de achterground continue een blok met sampledata uitrekend en vervolgens naar de geluidskaart buffer pompt.

2) Publieke parameters toevoegen in deze thread waarmee je de toongenerator 'bediend'.

3) Deze thread parameters vanuit de GUI Thread instellen d.m.v. sliders, buttons etc.

En viola, daar heb je jou 'realtime' golfvorm uit de speakers. Geproduceerde frequency in de loop is afhankelijk van de afspeelsnelheid van de buffer (samplerate). Dit kun je uitrekenen.

En let op: denk vanuit de samples in de buffer. Ieder blok in de buffer moet naadloos op elkaar aansluiten. Dus je moet het zo bouwen dat iedere cycle de golfvorm wordt verder gebouwd op het vorige blok, en niet steeds bij 0 begint. Anders krijg je tikken enz.

Dit is 'een' manier. Er zijn uiteraard nog meer (betere) manieren. Maar dit is wel één van de eenvoudigste.
 
Laatst gewijzigd:
Bedankt allen maar blijkbaar kan het onder Windows niet anders dan telkens de events en buffertoestanden van dat systeem af te wachten. Ik had ooit in een Alsa code diezelfde simpele for next lus gezien waarmee een realtime signaal naar de betreffende poort gestuurd werd. Op m'n zoektocht (toendertijd) naar een equivalent of alternatief voor windows heb ik nooit een oplossing gevonden. Blijkbaar is die er ook niet tenzij met de omslachtige windows werkwijzen. (Omslachtig : ooit iemand geprobeerd een progje om de volume regelingen van meerdere audio-kaarten te regelen ?! Daaruit leer je : 'Waarom makkelijk als moeilijk ook kan !')

Ik denk dat ik beter overstap naar die preset-pakketten, (als ik ooit nog eens terug zin krijg).

...met rekenen gaat het idd sneller dan met wavetables, dat heb ik ook al eens gemerkt.
Dit kan ik moeilijk geloven. Pointers, mensen ?
 
Ik ben het helemaal met je eens als je het hebt over 'omslachtigheid' van programmeren voor Windows in vergelijking tot het programmeren in assembler of low-level C voor DOS, microcontrollers i.o.d. Toen kon je inderdaad in een simpele endless loop direct naar de geluidskaart schrijven.

Feit wil echter dat men tegenwoordig graag een multitasked computer wil waar tergelijkertijd softwaresynthesizers, notatieprogramma's, internet, email, printfunctionaliteit gedraaid worden, en dan ook nog eens met allerlei verschillende onderliggende hardware.

Dan moet je als programmeur de knop omzetten naar een andere denkwijze, en genoegen nemen met hetgene wat het OS je voorschrijft: APIs, events, threads, buffers, etc.

Vergeet niet dat deze manier van programmeren ook een hele hoop voordelen kent.
 
de snelste sinusgenerator

de snelste sinusgenerator

Een kleine anecdote: toen ik met mijn sine DCO bezig was, ben ik begonnen met de golfvorm gewoon uit te rekenen (als 64 bit double). Dat werkte prima, maar echt snel was het niet. De volgende stap was - dacht ik - een wavetable (van 200kB). Werkte ook prima, maar ook dat was niet echt snel. Na wat profiling kwam ik erachter dat het uitrekenen van een sinus op een pentium4 precies even lang duurt als het opzoeken in een wavetable. Alleen is de Level1 cache op een pentium4 maar 8kB en daar paste mijn wavetable niet in zijn geheel in. Netto resultaat was dat de wavetable-oplossing langzamer was.

Als het puur gaat om een sinusgenerator, dan is de implementatie d.m.v. een 2de orde IIR pulsresponsie het snelst. Mogelijkheid tot exponentiële demping (bijv. voor imitatie van een stemvork) krijg je er (qua rekentijd) gratis bij.
 
Waar het om draait is dat je data vanuit je ontwikkelomgeving (wat die ook is, C++, basic etc) doorsluist naar het audio-systeem en daar zit altijd het operating system tussen, voor de meesten zal dat Windows zijn.

Je moet dus een ontwikkelomgeving hebben die je in staat stelt om rechtstreeks met de Windows-audio-doorsluisfuncties te praten. Het beste is C of C++, want dat is de taal waarin Windows is geformuleerd.

De communicatie verloopt via interrupts. Windows geeft jouw software een seintje als een pakket samples verstuurd is van of naar audio, zodat je nieuwe data kunt opsturen of ontvangen.
Mag je niet de al eerder genoemde Synthedit en Synthmaker gebruiken?
Ik heb namelijk geen zin om C/C++ te leren.
 
Als het puur gaat om een sinusgenerator, dan is de implementatie d.m.v. een 2de orde IIR pulsresponsie het snelst. Mogelijkheid tot exponentiële demping (bijv. voor imitatie van een stemvork) krijg je er (qua rekentijd) gratis bij.

Een nadeel van die aanpak kom je tegen als je gaat pitchbenden of portamento'en: het cpu-gebruik neemt dan ineens toe omdat de nieuwe filtercoefficienten berekend moeten worden met als mogelijk gevolg underruns bij het pitchbenden in een track die het verder prima doet. Hetzelfde probleem heb je natuurlijk bij filtersweeps e.d.

Wat dat betreft is software synthesizer-ontwerp heel vaak een afweging tussen een zo constant/laag mogelijke CPU-usage tijdens het tweaken enerzijds en een zo laag mogelijke CPU-usage bij "normaal" gebruik zonder tweaken anderzijds.
 
Back
Top