Digitale Klangsynthese

Dieses Thema im Forum "DAW / Komposition" wurde erstellt von lindeman, 3. Januar 2011.

  1. lindeman

    lindeman Tach

    hallo zusammen,

    ich habe über die feiertage - so rein aus
    interesse und zum verständniss - mal
    versucht mir einen digitalen oszillator zu
    programmieren. (oder funktionsgenerator, wie auch immer...)
    leider bin ich nicht sehr erfolgreich gewesen
    und tue mich etwas schwer mit der theorie.

    also meine erste idee war ein sägezahn oszillator ...
    aber wie berechnen?
    grundlegend hatte ich an eine linieare funktion gedacht.
    na klar ,,, sieht ja aus wie ein sägezahn.
    man betrachte nun f(x)=mx;
    der anstieg is für die frq irrelevant und stellt die amplitude dar.
    also ist die länge ausschlaggebend für die frq.
    da komme ich auf folgende formel: frq = samplingrate/länge bzw. länge=samplingrate/frq;
    wenn ich einen freq von einem hertz habe brauche ich die kompletten 44100 samples,
    was ja genau 1sek. entspricht.
    wenn diese rechnung aber tatsächlich richtig ist, scheint es mir unmöglich mit 44,1khz
    genaue frq hinzubekommen. die abweichung wird nach oben immer stärker und schon
    ab 400Hz nicht mehr brauchbar.
    schaut man sich das tabellarisch an ergeben sich folgende möglich darstellbare
    frq um den kammerton herum:

    len: 99 frq: 445.45454545454544Hz
    len: 100 frq: 441.0Hz
    len: 101 frq: 436.63366336633663Hz
    len: 102 frq: 432.3529411764706Hz
    len: 103 frq: 428.15533980582524Hz
    len: 104 frq: 424.03846153846155Hz

    meine frage ist nun, ob mein denkansatz generell
    richtig ist. so betrachtet wäre ja digitale klangsynthese
    musikalisch unbrauchbar.
    also was mache/denke ich hier falsch?

    danke schonmal im vorraus
    lindeman
     
  2. Summa

    Summa wibbly wobbly timey wimey

    Du beziehst den Filter im DAC nicht ein und packst von daher keinen Anti Aliasing Filter auf den Saegezahn...
     
  3. lindeman

    lindeman Tach

    okay.
    aber kann ich denn nun genaue frequenzen erzeugen?
    oder anders: wenn ich einen digitalen sinus verwende,
    hab ich doch das selbe problem, oder?
     
  4. Heinz Schnackensiel

    Heinz Schnackensiel ACCOUNT INAKTIV

    Die Frequenz deines Oszillators muss kein ganzzahliges Vielfaches der Samplingrate sein.

    13.34 Samplepunkte pro VCO-Schwingung sind völlig ok.

    Wenn du das "naiv" rechnest, dann bekommst du Aliasing im Ergebnis.
    Naiv rechnen läuft darauf hinaus, das du den "Sprung" im Sägenzahn mal nach 13 und mal nach 14 Samplepunkten machst. Die Frequenz stimmt dann, aber es ist eben von einer Störung überlagert.


    Aliasingfreie Oszillatoren sind schon etwas anspruchsvoller, das können wir hier nicht mal eben zusammen tippseln...


    Es ist m.E. sehr hilfreich, wenn man zunächst versucht zu verstehen, warum man bei Stereo zwei 11kHz Signale mit 3° (beliebig & beliebig genau!) Phasenversatz erzeugen kann, obwohl doch die Samples nur alle 22µs sind, was bei 11kHz 90° entsprechen würde....

    Letztlich ist so ein Samplepunkt, wenn er ins Analoge zurückkonvertiert wurde ein Sin(x)/x Impuls ( http://commons.wikimedia.org/wiki/File: ... zed%29.svg ). Und die analoge Kurve besteht aus der Überlagerung aller solcher Impulse. Nur genau zum jeweiligen Samplezeitpunkt bestimmt nur das aktuelle Sample den Analogwert, zwischen den Samples haben alle umliegenden Samplepunkte da auch etwas mitzureden. (Je weiter weg, desto weniger. )
     
  5. lindeman

    lindeman Tach

    danke für die schönen antworten! :)
    ich glaube ich verstehe langsam ...
    jetzt werde ich mich mal an einen neuen
    algorithmuss setzten.
    jaja und ich dachte digital wird
    einfach als rumlöten ;-)

    danke nochmal!
     
  6. Heinz Schnackensiel

    Heinz Schnackensiel ACCOUNT INAKTIV

    Die Ausrechnerei ist gar nicht so schwierig, nur etwas "andersrum" gedacht.

    Du fängst an eine Formel zu schreiben, die dein Signal für einen (jeden) Zeitpunkt t erzeugt. Ich nehme hier gemeinerweise mal einen Sinus, da muss man die Periode nicht mit Fallunterscheidungen und Modulo-Operationen reinfummeln...

    Dann ist dein Signal s z.B.:
    s=sin(wt); (mit w = 2 pi f)
    Das muss man jetzt auf die Samplerate skalieren.
    Sei n einfach das n-te Sample (also ein Zähler, der mit jedem Sample um eins hochzählt), dann kann man n/44100 als Zeit t einsetzen.
    Also z.B. s=sin(2 * pi * 443.7 * n/44100) (für 443.7 Hz)

    Die Sinusfunktion macht das ganze zwar ohne Aliasing, aber dennoch siehst du hier, wie hier die eigentlich kontinuierliche Sinus-Funktion vom immer ganzzahligen n sozusagen abgetastet wird. (Der Wert für n=1.56 wird besipielsweise nie abgefragt.)
    Das ist die Stelle an der es Aliasing geben könnte - und wenn du das für deinen Sägezahn entsprechend hin fummelst, auch geben wird. (Was natürlich erst mal völlig ok ist, es gibt durchaus kommerzielle VAs, die das nicht besser machen. )
     
  7. lindeman

    lindeman Tach

    vielen dank @Heinz Schnackensiel! :)

    jetzt hab ichs verstanden ...
    hab irgendwie andersrum gedacht.

    wenn ich nun mit überlagernden sinusfunktionen
    (additive synthese....)
    einen sägezahn zusammenbaue, sollte ich doch
    durch die natürliche glättung auch recht aliasing frei
    kommen, oder?
    insgesamt sollte der klang etwas weicher erscheinen.
     
  8. Man erzählt sich, dass das mit komplexer Rechnung sogar ziemlich "schnell" geht. Stichwort: FFT.
    Und ist weitaus CPU-schonender als "triviale" additive Synthese. Weil du ja anhand einer Sinusschwingung entsprechend annäherst. Additiv bräuchtest du Unmengen von Oszillatoren.

    Mal nach "Blit" googlen, (Bandlimitierte) Klangsynthese. Damit lassen sich dann Annäherungen der gewünschten Schwingung über eine Sinusfunktion generieren. Hierbei kann man dann sehr genau sagen, wieviel Obertöne der Klang bzw. die Schwingung haben soll. U.a. auf diese Weise lassen sich die Grenzen der vorgebenen Samplingrate ausreizen, (fast) ohne Klangeinbußen.

    Komplexe Rechnung kann noch ganz anders schön klingen.

    Der Link sei erwähnt:
    https://ccrma.stanford.edu/~stilti/papers/blit.pdf
    Ich bin noch im ersten Semester. Für komplexe Rechnung gabs ganze 3,5 Vorlesungen. Viel habe ich mich mit Thema seitdem nicht befasst. Daher kann ich dazu leider nicht viel sagen.

    Leichter zu verstehen ist der DPW-Algorithmus:
    http://www.music.mcgill.ca/~ich/researc ... cr1071.pdf
    Den Sägezahn glatt zu bügeln, um daraus noch einen Rechteck zu basteln ist nicht ganz so effektiv, wie das Annähern per Sinus, aber CPU-freundlicher, wie mir scheint.
    Erlaubt aber bspw ohne Weiteres keine Phasenmodulation und keine Umrechnung zum Dreieck (wenn man das arithmetisch "vom Sägezahn aus" machen will).

    Zu beiden Links gibts für Reaktorianer Beispiele in der Reaktor-User Library.

    Edit: Bei Filtern und anderen Geschichten lässt sich viel mit viel Oversampling unterdrücken. Die oversamplete Schwingung sieht ca so ähnlich aus wie die Annäherung per Sinus.
     
  9. haesslich

    haesslich Tach

    inverse fft und additive synthese sind im prinzip das gleiche. der trick bei der inversen fft ist nur, dass du es effizient berechnen kannst.
    zynadsubfx's padsynth erzeugt seine wellenformen übrigens so. dazu gibt's eine nette webseite mit erklärungen. dem haftet immer etwas 80er charme an.

    wenn du mit oversampling arbeitest, musst du die grundwellenform auf der hohen samplingrate erzeugen. das downsampling (mit einem guten resampler) ist dann der letzte schritt. der secret rabbit code resampler hat einen sehr guten ruf. durch oversampling erhälst du nie eine alias freie wellenform, aber alias minimiert. aber das kostet natürlich zyklen...
     
  10. Heinz Schnackensiel

    Heinz Schnackensiel ACCOUNT INAKTIV

    Du kannst mit den Sinus-Schwingungen den Sägezahn *perfekt* zusammenbauen. Dazu folgende Überlegung: die Oberwellen werden nur bis zur Nyquist-Grenez (halbe Abtastrate, hier 22.1kHz ) gebraucht, alles was höher ist kannst du ja gar nicht erzeugen - der Versuch erzeugt Aliasing. Insofern ist die begrenzte Sinus-Stapelei nicht "irgendwie weich" oder "unexakt", sondern eine Möglichkeit, die notwendige Bandgrenze (= nix über Nyquist, sonst Aliasing) einzuhalten.

    Bei tiefen Tönen sind das sehr viele Oberwellen, bei hohen Tönen nur wenige. Ein Rechteck (!wieder fiese wahl meinerseits, Rechteck hat keine geradzahligen Harmonischen, es kommt erst das dreifache des Grundtons wieder vor...) von 8 khz hat den ersten Oberton (mit Amplitude größer Null) bei 24kHz, den hört man gar nicht mehr.
    (In einem Versuch, der darauf verzichtet, dumme Fehler zum Resultat zu machen, kann man ein Rechteck mit 8kHz wirklich nicht vom Sinus mit 8kHz unterscheiden! )

    Wenn du die Sinusschwingungen jeweils einzeln per Sinus berechnest, ist das ein recht hoher Rechenaufwand, deshalb macht man das "eher nicht" so. Vor allem nicht damals, als die VAs erfunden wurden - da war noch nicht genug Rechenpower vorhanden.

    Ansonsten mach dir erst mal nicht so viel Gedanken darum, das Aliasing zu vermeiden - verstehen was passiert ist wichtiger als Wunderalgorithmen blind nachbauen. Und, wie gesagt, es gibt genug VAs deren Oszillatoren sich einen feuchten Kehricht darum scheren.
    Wirklich problematisch wird das Aliasing auch erst, wenn der Obertongehalt nicht mehr so gutmütig wie bei einem Sägezahn ist, praktisch sind das schmale Pulswelle und vor allem Sync-Sounds.
    Wenn du aus deinem Sägezahn eine Pulswelle machst, in dem du das analoge Vorbild nachbaust ( if (s > pulsewidth) s=1; else s=0; ), dann wird ja wieder abgetastet. (Die Formel wird nur auf ganzen Abtastwerten ausgeführt, obwohl die eigentliche Schwelle (=der Sprung im Ergebnis) irgendwo zwischen zwei Abtastwerten liegt. )

    Bei den FFT Algorithmen fängt man sich ein paar weitere Probleme ein. Zum einen ist die Frequenzauflösung begrenzt, zum anderen ist (in vielen musikalischen Anwendungen) die periodische Fortsetzung des Signals nicht gegeben (ähm ... huch... eigentlich sind das ja zwei Seiten der gleichen Medaille...).
    Und die Fensterfunktionen (um die Artefakte der erzwungenen Periodizität zu dämpfen) sind zwar für Messtechnik brauchbar, für musikalische Zwecke aber problematisch.
     
  11. lindeman

    lindeman Tach

    sehr interresant!
    danke an alle für die
    sehr hilfreichen antworten :) :) :)

    ich hatte mir das thema etwas einfacher
    vorgestellt, aber das wär ja auch langweilig.
    ich habe jetzt einen algorithmus mit dem
    ich frequenz-saubere sägezähne erstellen kann.
    ich erreche immer eine periode und merke
    mir den rest. läuft der rest auf eine ganze
    zahl über wird die ganzzahlige periode damit
    verlängert und ich merke mir wieder den rest -1
    sozusagen ...

    man müsste das selbe mit dem sinus wohl auch
    machen - hier muss ich zwar nicht direkt auf den
    nulldurchgang achten, aber wenn ich einen
    fortlaufen zähler verwende, läuft diese auch
    irgendwann mal über --- selbst bei 64bit ;-)

    jetzt tauchen aber auch ganz neue probleme auf:
    bei schnellen frequenzänderungen entstehen
    störgeräusche durch den versatz in der perioden-
    berechnung ...
    zb. bei frq modulation durch eine LFO
    was hat man sich hier für die praxis ausgedacht?

    des weitern lese ich mich gerade in die FFT ein -
    ist sicher auch ein interresantes thema für
    digitale filter.
    falls jemand nen schöne link für eine einfach
    erklärung hat, bitte zukommen lassen.
    irgendwie hab ich noch ein problem zu
    verstehen, wie ich die phasen aus den
    einganssamples ermittle ...

    morgen werd ich mal einen sägezahn
    mit additiver synthse basteln und schauen
    was ich dafür an rechenzeit benötige und
    einen bericht posten ...

    schönen abend ihr lieben
    lindeman
     
  12. Hoffe es hat niemand was dagegen wenn ich mich hier rasch einklinke. Auf dem NM G2 arbeite ich ja schon lange mit DIY Oszillatoren und interessiere mich deshalb sehr für diese Thematik. Aufgrund der Architektur des G2 hielt ich es stets für unmöglich, richtiges Anti-Aliasing hinzubekommen. Dieser DPW-Algorithmus (@Heinz: Herzlichen Dank für diese Links) macht aber den Anschein auf dem G2 eventuell realisierbar zu sein. Nur ist meine Mathe recht eingerostet und ich verstehe darum die Nomenklatur nicht ganz. Der "triviale" Modulo-Sägezahn mit exponentiellem Tracking ist kein Problem, den hab' ich wie gesagt schon. Aber was ist mit "raise by the power of 2" genannt? Einfach Signal multipliziert mit sich selber? Und wie wird "differentiate the signal with a first difference filter with transfer function HD(z) = 1–(z–1)" genau umgesetzt? Sowie das anschliessende "scaling"? Was wird da "skaliert"? Die Amplitude des Signals?

    Irgendwie scheint das nicht so schwierig zu sein, ich verstehe (trotz Muttersprache Englisch) jedoch einfach die math. Nomenklatur nicht wirklich.

    Any takers?
     
  13. lindeman

    lindeman Tach

    hallo zusammen,

    nach meinen heutigen studien hab
    ich mal wieder mehr fragen, als
    antworten :)
    deshalb erlaube ich mir mal, selbige
    hier zu stellen:

    fouriertransformation:
    wie bekomme ich aus den einzelnen
    sampels complexe zahlen heraus?
    ich brauche ja auch eine phase, die
    ich drehen kann für die spätere
    summierung ...
    ist der imaginäranteil null?
    oder hab ich mal wieder was nich
    kapiert? :)

    ich hab mir heute verschiedene
    codebeispiele angesehen für die FFT.
    kann mir aber beim besten willen nich
    daraus ableiten was passiert. naja.

    vielleicht hat ja jemand ahnung
    vom thema?

    danke und gruß
     
  14. @tim:
    Glaube, du wolltest dich auch bei mir für die Links bedanken.

    "raise" mit the power of 2" ist der Sägezahn einfach zum Quadrat genommen. Power = Potenz

    Also ja.

    Differenzieren per "Differentiator". Den kann man sich ganz einfach mit einem 1-Sample Delay basteln. (Weiß nicht, ob das auf nem G2 so einfach ist)

    Hierzu wird einfach das Eingangssample von dem vorigen (verzögerten) Eingangssample abgezogen. Das Ausgangssignal ist dann sehr leise und muss daher in Abhängigkeit zur Tonhöhe skaliert werden.
    Nämlich mit: 1/(4*i)

    wobei i die "Schrittweite" bzw das Inkremental der Zähl-Schleife bedeutet. Also die Erhöhung der Amplitude pro Sample.

    Und errechnet sich durch Inkremental = Osc-Frequenz / Samplerate
     
  15. @Rampensau:
    Herzlichen Dank für Deine Ausführungen. 1-sample-delay-Differentiation ist kein Problem auf dem G2, hab da einen Trick. Prinzipiell ist nun alles klar. Mal sehen ob ich das hinkriege. Das numerische System des G2 ist fraktional, das gibt manchmal Probleme. We'll see. Ge-anti-aliaste DIY-Oscs auf dem G2, das wäre wieder ein neuer Durchbruch. Yee-haw :frolic:.

    Nachtrag: Es funktioniert! :frolic: Wen's interessiert:
    http://www.electro-music.com/forum/view ... hp?t=45908

    Nochmals herzlichen Dank und sorry für's Thread-Kapern, ich klink mich hier wieder aus.
     
  16. lindeman

    lindeman Tach

    guten morgen alle miteinander,

    ich hab mein problem gelöst :)
    der eingang für die fourier transofrmation ist zwar eine reihe komplexer zahlen, jedoch ist
    der imaginärteil = 0 und der realteil der wert des samples.
    ich hatte zum vertändnis einen algorithmus für die DFT implementiert - jedoch ist das
    extrem langsam und für realtime-audio unbrauchbar.
    die FFT ist da schon schwerer in der umsetzung zu verstehen - muss man aber nicht selber
    machen.
    für alle Java fan's kann ich nach langem suchen nur die apache libraries empfehlen:

    http://commons.apache.org/math/
    (org.apache.commons.math.transform.FastFourierTransformer)

    mit hilfe der FFT konnte ich nun auch meinen sägezahn auf frequenzgenauigkeit überprüfen und
    siehe da, mit der rechenart von heinz (@Heinz: nochmal danke!) passt das ding! :) :)
    ist auch sehr schön, wenn man sich mal das spektrum der verschiedenen wellenformen anschaut.

    nun werd ich mich mal an BLIT/BLEP/DWP und co versuchen...

    das einzige problem was ich noch habe und noch nicht lösen konnte, ist wie man den perioden
    übergang angleicht bei schnellen frequenzänderungen des oszillators.
    wird z.b. ein solcher oszillator frequenzmoduliert, dann erzeugt der algorithmus im moment
    unsaubere übergänge (sprünge).
    irgendwie muss man bei frequenzänderungen wohl die position in der periode anpassen oder so.
    vielleicht hat ja wer erfahrung oder eine schöne idee? :)

    so, und nun schonmal allen ein schönes wochenende

    lindeman
     
  17. yello

    yello Tach

    Hallo Zusammen bist Du da nun weiter gekommen (BLIT)
    Ich versteh da trotz Beschreibung nicht so ganz wie das nun mit der BLIT Methode gemeint ist. :heul: :selfhammer:
    Kann da jemand beschreiben wie der BLIT Algorithm zur generierung eines Sägezahnoscillator Funktioniert rsp. Umgesetzt wird ??

    Aber mir fehlt warscheinlich der mathematische background um von komplizierten Funktionsbeschreibungen zu der in der Praxis vereinfachten Formel zu unterscheiden !!! :oops:

    Ich hatte auch beim DPW algorithm so meine iterpretationsprobleme :oops:
    Ist das wirklich so einfach mit dem differenzieren HD(z) = Wert - alter Wert ?????

    Gruss
    Yello
     
  18. yello

    yello Tach

    Hmm bei dem Echo hab ich mich wohl zu unverständlich ausgedrückt :oops:

    Nun ich will es nochmals versuchen. Mittlerweile habe ich so glaube ich begriffen was BLIT bedeutet.

    Offensichtlich enthält der Säagezahn Harmonische mit unendlich hoher Frequenz. Deshalb
    führt eine Abtastung zu erheblichem Aliasing, d.h. Frequenzen über fg werden auf Frequenzen
    unterhalb fg abgebildet. Dies führt zu”unsauberem“ Klang oder gar zu falscher
    Tonhöhe und kann nicht durch nachträgliche Filterung behoben werden. Es bleibt nichts
    anderes übrig, als die Wellenform bandbeschränkt (unter Einhaltung des Abtasttheorems)
    zu synthetisieren. Band limited impuls train (BLIT).

    Nun schön und gut erklärt aber was mir noch nicht richtig in den Kopf will ist folgendes.
    Es ist völlig einleuchtend wenn ich ein Eigangssignal erfassen will (Sampling) und dieses eine höhere Frequenz als 1/2 von fs hat, diese
    Abtastung führt dann zu erheblichem Aliasing (Das zu schnelle Signal hat dann nur noch ein Wert pro Periode erfasst und kann somit nicht mehr Rekonstruiert werden!
    Abhilfe höhere Samplerate oder AA-Filter vor der Abtastung. Da ist mir noch alles Klar !!

    Was aber nun hat die Abtastung und das Abtasttheorem von Shannon bei einer Signalerzeugung (Oszillator) zu tun ????? :oops:
    Da wird das gewünschte Signal ja nicht abgetastet sondern direkt mit entsprechenden Algorithmen erzeugt rsp. die nötigen Sampels pro Perioden werden ja bestimmt gesetzt und können
    nicht durch aliasing plötzlich verschwinden und somit das Signal verfälschen.

    Genau da habe ich noch einen knopf in der Leitung :oops: :oops:
    Kann mir da jemand weiterhelfen ?

    Gruss
    Yello
     
  19. >Da wird das gewünschte Signal ja nicht abgetastet sondern direkt mit entsprechenden Algorithmen erzeugt
    Doch, weil die analoge Realität durch die zeitliche Abstufung deiner Klangerzeugung abgetastet wird.

    Nur, wenn die Frequenz exakt ganzzahlig passt, ist das nicht der Fall.
     
  20. yello

    yello Tach

    Abgetastet ??? Du meinst wohl durch zeitliche Abstufung erzeugt wird ????
    Ich begreife es immer noch nicht ganz !!

    :roll:
    Yello
     
  21. falls noch Interesse besteht, ich hab mal was für Reaktorianer gebastelt, die gerne DSP-mäßig in Core Oszillatoren basteln wollen. Lässt sich ja locker in jede Programmiersprache portieren:
    http://www.reaktor.approx.de/phpbb3/vie ... &sk=t&sd=a

    U.a. hab ich mich über BLIT-Generation ausgelassen...
     
  22. Cyclotron

    Cyclotron eingearbeitet

    Hab das Thema gerade erst entdeckt, aber vllt. kann ja doch mal jemand meine Frage beantworten:

    Wie sieht es aus, wenn man geloopte Single Cycle Waveforms innerhalb eines Wavetableverlaufes rendern möchte? Meine 512 IFFT erzeugt Sinuswellen mit 256 Samples länge, aber genau da kommt ja die Problematik, dass man eben nicht mit der Samplerate skalieren kann und somit die Tonhöhe eben auch etwas neben der nächsten Note liegt. Da gibt es wohl keine Lösung außer dem File im Loop - Chunk einen Frequenzoffset mit zu geben und die Korrektur dem abspielenden VSTi zu überlassen - oder übersehe ich da was?
     
  23. ich verstehe deine Problematik nicht. Was heißt: "mit der Samplerate skalieren"? was meinst du mit innerhalb eines Wavetableverlaufes rendern??

    Kannst du bitte versuchen, dich deutlicher auszudrücken und keine Fachtermini zu erfinden?

    Eine Periode der Länge T, egal welcher periodischen Wellenform benötigt genau (Samplerate * T) Samples. Die Anzahl der Samples ist natürlich i.A. nicht ganzzahlig.
    So benötigst du für einen 440Hz-Sinus bei 44.100Hz :

    AnzahlSamples = (44100/440) = 100.227272...

    Aber das ist net schlimm. :dunno:
     
  24. Ich hab den Satz mehrere Male durchgelesen und mein Grinsen wird bei jedem Mal breiter. Sorry. lol
    Ich würde dir ja gerne helfen aber ich kann damit echt nichts anfangen. Tut mir leid.
     
  25. Cyclotron

    Cyclotron eingearbeitet

    Schön, dass ich für Erheiterung sorgen konnte. Ich bin leider kein Fachmann, kann es daher nur versuchen zu umschreiben.

    Meine Software baut Wavetables wie z.Bsp. die im Microwave additiv aus 64 Sinuswellen (Cosinus ist immer 0) und schreibt diese hintereinander in eine *.wav Datei. Dazu werden 33 verschiedene Single Cycle Schwingungen per IFFT erzeugt und mit etwas Abstand in einem Array gespeichert. Die Wellenformen dazwischen werden interpoliert, damit später beim Durchfahren der Wavetable keine Sprünge auftreten. Das ganze wird als WAV auf der Platte gespeichert.

    Die Datei enthält unter anderem einen smpl Chunk, wo die Loopdaten festgehalten sind (Sample 0 - 255, also der erste Wellendurchgang). Lade ich diese Datei in die Wusikstation, kann ich ohne Knackser beispielsweise resynthetisierte Sprachsamples oder sowas durchfahren, indem ich die Loopposition moduliere. Klappt auch alles wunderbar. Hier mal eine solche Wavetable:

    http://www.fileden.com/files/2007/11/26/1607754//KTERMWT.WAV (512 kb)

    Optisch sieht das so aus:

    [​IMG]

    Nun mein Problem am Beispiel der Fundamentalen: Die IFFT schreibt nun mal stur eine Schwingung mit 256 Samples Periodenlänge und diese Länge ist im Gegensatz zur Ausgabe Deiner Sinusformel fix, da man ja die IFFT nicht beliebig anpassen kann und ich wüsste nicht, wo ich da den Faktor "Frequenz/Samplerate" einfließen lassen sollte. Die resultierende Tonhöhe für die Grundschwingung liegt somit knapp unterhalb von F3 (wofür ich ~252,56285 Samples bräuchte). Ich komme ja nicht mal auf 252 Samples. In der *.wav Datei habe ich das so gelöst, dass ich im smpl - Chunk eine MidiUnityNote und eine MidiPitchFraction angegeben habe. Somit stimmt die Tonhöhe beim Abspielen im VSTi wieder.

    Aber wenn ich in meinem Programm die Vorhörfunktion benutze, wird einfach nur die gespeicherte Table per PlaySoundA() aus dem Array abgespielt wie eine ganz normale WAV Datei. Irgendwelche speziellen Chunks funktionieren hier nicht und es klingt immer etwas schräg. Deshalb hätte ich gerne gewusst, ob es einen Weg gibt, mit meiner IFFT wenigstens auf die 252 Samples Periodenlänge zu kommen. Oder muss ich damit leben?

    Sorry, besser kann ich es nicht beschreiben. :dunno:
     
  26. haesslich

    haesslich Tach

    der konservative weg wäre wohl resampling. wenn du das geschickt implementierst, fängst du dir nur minimales aliasing ein.
     
  27. Cyclotron

    Cyclotron eingearbeitet

    Hm ja, das hatte ich befürchtet. :sad: Danke.
     
  28. haesslich

    haesslich Tach

    tröste dich: vermutlich wirds die wusikstation auch nicht anders machen. es gibt ja auch gute resampler.
     
  29. Cyclotron

    Cyclotron eingearbeitet

    Die Qualität in den VSTis ist aber wahrscheinlich höher als meine selbstverbrochenen Algos und eine externe *.dll wollte ich eigentlich aus diversen Gründen nicht benutzen. Na mal gucken...
     
  30. hört sich auch sehr spannend an ;-). hehe ... egal.

    Was der Volksmund "Wavetable" schimpft, besteht aus einzelnen Wavetables. Eine Wavetable ist einfach eine Tabelle von N Funktionswerten. Eine Wavetable, die keinen periodischen Vorgang beschreibt, bezeichnet der Volksmund einfach Sample.
    Normale Sampleplayer rattern diese Tabellen Wert für Wert einfach inkrementell in einer Schleife durch. Die Wavetable wird quasi mit "unity-frequency" abgespielt.

    Wenn du die Frequenz steuern möchtest, musst du die Abspielgeschwindigkeit verändern und nicht die Abtastrate und auch nicht die Anzahl der Samples pro Table.
    Das heißt, du musst die Schrittweite steuern können, in der die Tabelle ausgelesen wird.
    Eine langsamere Frequenz als "unity-Frequenz" würde Werte mehrfach auslesen. Eine Schnellere Frequenz als "unity-Frequenz" würde Werte in der Tabelle überspringen.
    Die Formel für diese Schrittweite ist hier: i = (N * Frequenz)/ Samplerate. N ist die Anzahl der Samples in der Tabelle.

    Dein Schleifenzähler zum Durchfahren einer einzelnen(!) Wavetable heißt also nicht "i++", sondern "i = i + (N * Frequenz)/ Samplerate". Dadurch entsteht natürlich Aliasing.
    Einfache lineare Interpolation der Funktionswerte reicht dann aus, wenn das Signal bandbeschränkt(d.h. hier, das Band darf nicht die halbe Abtastrate überschreiten) und überabgestastet ist (d.h. mehr als 2 Abtastwerte pro Periode), um eine bessere Näherung des Wunschssignals zu erhalten.

    Beliebig verändern kann man die Anzahl der berechneten Samples nicht, da die Anzahl der Samples, die durch FFT verarbeitet werden immer eine 2er Potenz ist.
     

Diese Seite empfehlen