Aliasing und digitale Algorithmen

Welche art von Aliasing ist hörbar? Ist es besser auf akkurate Phasenlage/ Frequenz zu verzichten um aliasing zu minimieren?

Welche Synth Engines / Synthesetechniken sind besonders Anfällig?

Einfachstes Beispiel:
Ein Oszillator... Ein Zähler erhöht die Phasenlage in abhängigkeit von der Frequenz. Jetzt ist es möglich immer wenn der Zähler überläuft die Phase auf den letzten wert rückzusetzen.
zb 8 bit phase: der höchste wert ist 11111111 angenommen der letzte wert vor dem überlauf war 11111011 und nach dem überlauf 00001010.
Ist es zielführend den zähler nach dem überlauf auf 00000000 rückzusetzen oder gibts da bessere Methoden?
 
Computerliebe schrieb:
Einfachstes Beispiel:
Ein Oszillator... Ein Zähler erhöht die Phasenlage in abhängigkeit von der Frequenz. Jetzt ist es möglich immer wenn der Zähler überläuft die Phase auf den letzten wert rückzusetzen.
zb 8 bit phase: der höchste wert ist 11111111 angenommen der letzte wert vor dem überlauf war 11111011 und nach dem überlauf 00001010.
Ist es zielführend den zähler nach dem überlauf auf 00000000 rückzusetzen oder gibts da bessere Methoden?

was hat das beispiel mit aliasing zu tun?
aliasing tritt auf, wenn die frequenz deines abgetasteten (digitalen) signals die nyquist-frequenz überschreitet. dein beispiel hat damit erstmal nichts zu tun, oder?
 
haesslich schrieb:
Computerliebe schrieb:
Einfachstes Beispiel:
Ein Oszillator... Ein Zähler erhöht die Phasenlage in abhängigkeit von der Frequenz. Jetzt ist es möglich immer wenn der Zähler überläuft die Phase auf den letzten wert rückzusetzen.
zb 8 bit phase: der höchste wert ist 11111111 angenommen der letzte wert vor dem überlauf war 11111011 und nach dem überlauf 00001010.
Ist es zielführend den zähler nach dem überlauf auf 00000000 rückzusetzen oder gibts da bessere Methoden?

was hat das beispiel mit aliasing zu tun?
aliasing tritt auf, wenn die frequenz deines abgetasteten (digitalen) signals die nyquist-frequenz überschreitet. dein beispiel hat damit erstmal nichts zu tun, oder?
So weit ich das verstanden habe schon.

Wenn der Zähler einfach so weiterläuft, bei einem einfachen Oszillator kein großes problem, dann schwankt der Pegel einfach ein bischen bei jeder Periode.
aber wenn du zb nach einer Phase die Wellenform oder die Frequenz umschalten willst gibts probleme...

klar je weiter sich die Frequenz von der Samplingfrequenz entfernt, also je tiefer der Ton wird desto weniger effekt hat das ganze, aber vorhanden ist es schon noch...


PS: Insoweit hast du schon recht, ein umschalten von wellenformen entspricht quasi der nyquist frequenz. Aber das tritt auch auf wenn ich das kontinuierlich mache man hört es dann halt nicht mehr so aber vorhanden ist es schon.

Und der fehler akkumuliert sich... klar ich höre es immernoch nicht bei 96khz und 24 bit aber was mach ich bei 8 bit gedöns...
 
Computerliebe schrieb:
Wenn der Zähler einfach so weiterläuft, bei einem einfachen Oszillator kein großes problem, dann schwankt der Pegel einfach ein bischen bei jeder Periode.

das klingt trotzdem noch höchst wirr. wieso sollte der pegel schwanken? hä?

aber wenn du zb nach einer Phase die Wellenform oder die Frequenz umschalten willst gibts probleme...
"nach einer phase"? die phase ist ein wert, eine eigenschaft, die das signal zu einem zeitpunkt hat. es gibt nicht eine phase, die nächste phase etc.. du meinst einen zyklus? eine periode? einen durchlauf der phase von 0° bis 360°?

dir geht es dann um die umschaltposition, oder? wenn du die wellenform änderst, und an der aktuellen position, an der du umschaltest, ist das signal unstetig oder das signal "macht einen knick" (erste ableitung ist unstetig), weil die steigung der wellenformen an der umschaltstelle nicht identisch ist?
ja, die könnte aliasing hervorrufen. aber der knick alleine hat ja ein breites spektrum und klingt wie "knack", und dieses geräusch wird theoretisch vorhandenes aliasing maskieren.
 
Ja ich mach zb das hier:
bei 90 grad phasenlage bei einem sinus wird jeweils die frequenz umgeschaltet. Oben ist mit rücksetzen der Phasenlage unten ohne. Wie man erkennen kann hat die untere Wellenform "Kanten" oben geht das glatt, auch wenn die Frequenz sich verändert. (das ist beides ein ausschnitt des selben samples, die Phasenverschiebung entspricht den Fehler in der Frequenz über das gesamte Sample)
 

Anhänge

  • waveform.png
    waveform.png
    2,4 KB · Aufrufe: 257
ja gegenüber vorher oben und unten vertauscht :selfhammer:
 

Anhänge

  • waveform1.png
    waveform1.png
    1 KB · Aufrufe: 251
  • waveform2.png
    waveform2.png
    1,6 KB · Aufrufe: 246
  • waveform4.png
    waveform4.png
    18,4 KB · Aufrufe: 236
zum ersten bild:
für mich sieht das so aus, als wären bei beiden varianten die phasenlage beim umschalten der frequenz beachtet worden, denn sin(0) = 0 und nicht -1.
dennoch verstehe ich worauf du hinauswillst. der "knick" ist angeblich beim einen härter, als beim anderen. da kommt mehreres zusammen. erstens haben wir hier das gleiche phänomen wie beim bild mit den pegelschwankungen. siehe dort ;-) und lass dich von der computeranzeige nicht irreführen! aber abgesehen davon musst du IMMER die phasenlage speichern, wenn du etwas am oszillatormodell einstellst. mach das beispiel mal mit einer niedrigeren frequenz (So dass man in der umgebung des knicks mehr samples hat), und mit einer niedrigeren differenz (so dass der knick nicht zu hart ist). dann siehst du ja, dass mit speichern der phasenlage der knick VIEL weicher ist, als ohne. trotzdem ist es ein knick, ergo in diesem punkt sehr viele hohe frequenzen.
jetzt wird's etwas theoretisch: dieser effekt an sich hat noch nichts mit aliasing zu tun, sondern liegt am zusammenhang zwischen welle und frequenz. nehmen wir mal einen ganz starken knick- den stärksten den wir darstellen können. das ist das rechteck. [1 1 1 1 0 0 0 0]. die periodische rechteckschwingung hat die frequenzkomponenten sin(wt), 1/3 * sin(3wt), 1/5 * sin(5wt) usw.
wie du ja weißt, erzeugen all jene komponenten bei denen x*wt > 0.5*fs (also der nyquistfrequenz) ist, aliasing. diese sind aber sehr leise (eben 1/x). dein spektrogramm geht ja nur bis 5kHz - ist das nyquist?
weiterhin über das spektrogramm: das gauss fenster wird doch benutzt um zeitlich zu fenstern. es kann ja sehr wohl eine dieser unstetigkeiten mitten in einem fenster liegen. das spektrogramm wird ja overlap add berechnet, und das fenster dient nur dazu unstetigkeiten an der overlaps auszublenden.

beim zweiten sehe ich überhaupt nicht, worauf du hinauswillst.

aber zu den "pegelschwankungen" kann ich etwas sagen. da hast du dich hereinlegen lassen. :) die samples sind schon alle korrekt, und auch der maximalpegel ist bei allen perioden der gleiche (!). der computer kann dir das nur nicht anzeigen. denn was der computer dir dort anzeigt, ist einfach jedes sample mit einer linie verbunden. das ist aber mitnichten dein signal! dein signal sind NUR die samples, nicht die durchverbundenen linien. und für die einzelnen samples gibt es keine garantie, dass sie immer exakt das maximum und das minimum treffen, oder? und bevor du fragst, wieso dann doch ein signal ohne pegelschwankungen rauskommen kann, wenn der maximal und minimal pegel nicht immer durch samples repräsentiert sind: das ist das wunder des DA wandlers. der DA wandler wird nämlich (im idealfall) für das signal was du dort zeigst, einen sinus bauen, der genau durch die punkte verläuft, die deine samples darstellen. und so ein sinus ist eindeutig - und hat die korrekten maxima und minima.

ich kann dir mal einen screenshot von einer wellenform schicken, wo die darstellung am computer völlig versagt. ich würde das aber gerne per PM machen, um nicht unnötig diskussion über ein anderes thema hier im thread zu schaffen ;-)
 
Im moment ist das ein chuck script das ganze will ich dann aber auf dem Shruthi rennen lassen ein neuer Oszillator quasi.

Um das "rücksetzen" zu ersparen könnte ich einen Wavetable berechnen für die lange und kurze Periode zusammen für verschiedene Verhältnisse, mit chuck kein Problem aber auf dem Shruthi würde mir der Speicher ausgehen.

Ich muss mir den Shruthi quellcode noch ansehen vielleicht geht das dort auch anders als mit chuck und ich komme auf Sachen an die ich vorher nicht gedacht habe ;-)


Mein Ziel ist erstmal eine Art PWM mit Sinus zu machen eben wie oben dargestellt und eventuell später mehr. Das prinzip ist verschiedene Teilperioden von Sinusen oder anderen Wellenformen in unterschiedlichen Frequenzen so aneinanderzureihen das nirgends eine Unstetigkeit ensteht. Der obrige Sound ist der einfachste Sound dieser Art der mir eingefallen ist, außerdem lässt der sich als etwas steriler Bass einsetzen.

Was anderes wäre zb Sinus+Dreieck. Beim Nulldurchgang haben die beide die selbe Steigung oder Sinus+Säge mit doppelter Frequenz etc... gibts massenhaft möglichkeiten.
Um wellenabschnitte mit unterschiedlicher Frequenz aneinander zu kleben muss dann entweder die Amplitude angepasst werden so das die resultierende Funktion wieder Stetig ist oder bei einer anderen Phasenlage umgeschaltet werden.
 
Computerliebe schrieb:
Mein Ziel ist erstmal eine Art PWM mit Sinus zu machen eben wie oben dargestellt und eventuell später mehr.

ah! das habe ich aus den obigen informationen so nicht enthemen können.
nun macht das auch mehr sinn - ich verstehe glaube ich nun, warum du die phase zurücksetzen willst.

Um das "rücksetzen" zu ersparen könnte ich einen Wavetable berechnen für die lange und kurze Periode zusammen für verschiedene Verhältnisse, mit chuck kein Problem aber auf dem Shruthi würde mir der Speicher ausgehen.

ja das wird n ziemlicher brocken so. aber ich denke, dass das auch einfacher geht. ich denke, es reicht, wenn du mit einer tabelle arbeitest: du legst dir ne look-up-table an - beispielhaft 1024 werte. bei duty cycle von 0.5 also 512 für die positive halbwelle, 512 für die negative. und immer, wenn du den duty cycle änderst, berechnest du die tabelle neu. z.b. duty cycle geht auf 0.25 -> 256 samples für die positive halbwelle, 768 für die negative halbwelle. der vorteil ist, dass die grundfrequenz dieser wellenform immer gleich ist nämlich 1024 / Samplingrate. pitchen kannst du dann über interpolation.
bei sehr hohen pwm modulationsgeschwindigkeiten wird das natürlich nicht mehr funktionieren.
die audioqualität dieses oszillators hängt dann von zwei faktoren ab, der größe der look-up-table und der qualität des interpolators. einen versuch ist es wert, weil man das mit dieser methode ziemlich schnell implementieren und ausprobieren kann, wo die grenzen der rechenleistung und die grenzen der audioqualität liegen.

wie machst du das denn jetzt? mit einer sin(x) funktion, die du immer wieder berechnest mit abwechselnden frequenzen? wie hälst du da die grundfrequenz?
 
haesslich schrieb:
ich denke, es reicht, wenn du mit einer tabelle arbeitest: du legst dir ne look-up-table an - beispielhaft 1024 werte. bei duty cycle von 0.5 also 512 für die positive halbwelle, 512 für die negative. und immer, wenn du den duty cycle änderst, berechnest du die tabelle neu. z.b. duty cycle geht auf 0.25 -> 256 samples für die positive halbwelle, 768 für die negative halbwelle. der vorteil ist, dass die grundfrequenz dieser wellenform immer gleich ist nämlich 1024 / Samplingrate. pitchen kannst du dann über interpolation.
Ja das würde auch funktionieren. Das Problem bei der Sache ist das ich das dann im shruthi in jedem Modulationszyklus machen muss. Kann sein das da genug rechenleistung vorhanden ist oder auch nicht muss ich testen.

haesslich schrieb:
wie machst du das denn jetzt? mit einer sin(x) funktion, die du immer wieder berechnest mit abwechselnden frequenzen? wie hälst du da die grundfrequenz?
Nicht ganz. Ist ein SinOSC objekt wo ich jedes sample die phase mit 0.25 vergleiche das rennt intern über floating point, schön praktisch aber das geht halt nur aufn pc. Ich schalte dann immer bei überschreiten dieses werts die Frequenz des Objekts um das geht ganz einfach mit freq => osc.freq();

Im prinzip geht es ja nur um den Wert eines einzigen samples:
Nämlich der Wert den die Welle haben muss an dem Sample das am nächsten zu der Umschaltperiode ist. Idealerweise bei einer unendlich hohen samplerate wäre das in meinem fall jeweils immer 1 bzw das jeweilige maxima. Tatsächlich aber eben ein etwas kleinerer wert in abhängkeit von der phasenlage & periode.


Beim shuthi kommts jetzt draufan wo platz ist den code so unterzubringen das der rechtzeitg fertig wird. Vielleicht gibts ja möglichkeiten nicht das gesamte array neu zu berechnen ohne zu viele artifakte zu erzeugen. Das kommt natürlich draufan wie das moduliert wird.
 
Computerliebe schrieb:
Ja das würde auch funktionieren. Das Problem bei der Sache ist das ich das dann im shruthi in jedem Modulationszyklus machen muss. Kann sein das da genug rechenleistung vorhanden ist oder auch nicht muss ich testen.

genau! bei hohen modulationsfrequenzen wird das auf jeden fall kritisch.

Nicht ganz. Ist ein SinOSC objekt wo ich jedes sample die phase mit 0.25 vergleiche das rennt intern über floating point, schön praktisch aber das geht halt nur aufn pc. Ich schalte dann immer bei überschreiten dieses werts die Frequenz des Objekts um das geht ganz einfach mit freq => osc.freq();

warum 0.25? sollte es nicht 0.5 sein? (du willst ja beim nulldurchgang die frequenz ändern, nehme ich an). und wie schaltest du die frequenz um? die frequenzen müssen ja genau so berechnet werden, dass ein gesamter zyklus zusammen (also positive + negative halbwelle) die gewünschte frequenz hat. rechnest du dann nach jeder halbwelle die frequenz neu aus, wenn sich der duty cycle geändert hat?

Beim shuthi kommts jetzt draufan wo platz ist den code so unterzubringen das der rechtzeitg fertig wird. Vielleicht gibts ja möglichkeiten nicht das gesamte array neu zu berechnen ohne zu viele artifakte zu erzeugen. Das kommt natürlich draufan wie das moduliert wird.

genau. ich weiß nicht, was für ein controller im shruti ist, aber das wird ganz schön bitschieberei, egal wie du das machst.

das ganze in chuck auszuprobieren ist zwar nicht schlecht, weil man sehr schnell prototypen kann. aber den chuck-code kann man ja schlecht portieren und auch den rechenaufwand eines algorithmus in chuck kann man nur schwer schätzen. ich prototype deswegen immer in einer skriptsprache, meist Octave / Matlab, weil man diesen code besser beurteilen kann.
 
haesslich schrieb:
warum 0.25? sollte es nicht 0.5 sein? (du willst ja beim nulldurchgang die frequenz ändern, nehme ich an). und wie schaltest du die frequenz um? die frequenzen müssen ja genau so berechnet werden, dass ein gesamter zyklus zusammen (also positive + negative halbwelle) die gewünschte frequenz hat. rechnest du dann nach jeder halbwelle die frequenz neu aus, wenn sich der duty cycle geändert hat?
0.25 weil das ein extrema ist. Nulldurchgang würde auch gehen, ist aber bei unterschiedlichen frequenzen und gleicher amplitude unstetig. Da müsste ich die Amplitude so ausrechnen das es wieder stetig ist, außerdem klingt das bissl anders.. aber ja ginge auch, kommt später, ist aufwendiger ;-)
Die Frequenzen der Halbwellen wird im nach jeder Periode neu berechnet.


haesslich schrieb:
genau. ich weiß nicht, was für ein controller im shruti ist, aber das wird ganz schön bitschieberei, egal wie du das machst. das ganze in chuck auszuprobieren ist zwar nicht schlecht, weil man sehr schnell prototypen kann. aber den chuck-code kann man ja schlecht portieren und auch den rechenaufwand eines algorithmus in chuck kann man nur schwer schätzen. ich prototype deswegen immer in einer skriptsprache, meist Octave / Matlab, weil man diesen code besser beurteilen kann.

Mutable Instruments schrieb:
You can now add two static methods to the Oscillator template class. Update is called at 1kHz – everytime the pitch and parameter change – while Render is called for every sample, and is responsible for updating the held_sample_ variable containing the actual 8 bits, unsigned sample.

Also eine millisekunde hab ich zeit das ist eigendlich reichlich, der AVR rennt mit 20mhz das sind 20000 takte da sollte es sich eigendlich ausgehen eine Periode durchzuackern, da lässt sich dann schaun wie viele werte die tabelle haben darf aber überschlagsmäßig bei 256 samples und 8 operationen pro sample brauche ich grob 1/10 der verfügbaren rechenleistung. Naja knapp wird sicher da es 2 oszillatoren sind und da noch jede menge anderes zeug drauf rennt aber mal schaun.

Matlab/Octave kenn ich mich nicht aus.
 
Computerliebe schrieb:
0.25 weil das ein extrema ist. Nulldurchgang würde auch gehen, ist aber bei unterschiedlichen frequenzen und gleicher amplitude unstetig. Da müsste ich die Amplitude so ausrechnen das es wieder stetig ist, außerdem klingt das bissl anders.. aber ja ginge auch, kommt später, ist aufwendiger ;-)
Die Frequenzen der Halbwellen wird im nach jeder Periode neu berechnet.

aber dann ist es kein PWM äquivalent, oder? denn da ist der duty cycle ja definiert als das verhältnis von positiver zu negativer halbwelle. also müsste exakterweise auch dort umgeschaltet werden.
dass das signal im maximum beim wechseln der frequenz stetig ist, im nulldurchgang unstetig wäre, sehe ich nicht ein. es liegt in der natur der sache, dass das signal beim umschalten der frequenz unstetig in der umschaltstelle wird - dabei ist egal ob du das bei 90° oder 180° tust.


Matlab/Octave kenn ich mich nicht aus.
das schöne an Matlab und Octave ist, dass du den algorithmus in der bit auflösung in der du arbeitest prototypen könntest. wenn du nun also aus effizienzgründen rein in integer implementierst, könnteset du das in octave auch so testen und mal anhören, wie das klingt. geht halt nicht realtime, sondern alles offline und als wav speichern.

mir fällt grad noch was ein.
sinus in look-up-table und nur über die interpolation den duty cycle einstellen. das müsste eigentlich passen!
 
haesslich schrieb:
aber dann ist es kein PWM äquivalent, oder? denn da ist der duty cycle ja definiert als das verhältnis von positiver zu negativer halbwelle. also müsste exakterweise auch dort umgeschaltet werden.

Nein, ist es nicht du hast recht. Es ist sozusagen sub-oktav pwm oder sowas, oder einfach der einfachheit halber ein "Sinuswellen-umschalt-Oszillator".
Das was ich mache hat aber den vorteil das es keinen DC offset erzeugt, aber ja genaugenommen ist es kein PWM aber es klingt bissiger ;-)

haesslich schrieb:
das schöne an Matlab und Octave ist, dass du den algorithmus in der bit auflösung in der du arbeitest prototypen könntest. wenn du nun also aus effizienzgründen rein in integer implementierst, könnteset du das in octave auch so testen und mal anhören, wie das klingt. geht halt nicht realtime, sondern alles offline und als wav speichern.

Interessant, nur den Code muss man dann ja trotzdem extra schreiben. Der shruthi ist in c++ programmiert (achtung shruti ist der vorgänger der benutzte afik arduino)


haesslich schrieb:
sinus in look-up-table und nur über die interpolation den duty cycle einstellen. das müsste eigentlich passen!
Einen Sinus hat der Shruthi ja schon eingebaut, nur ich glaube das das im endeffekt aufs gleiche hinausläuft wie oben, ich muss ja die Interpolation im richtigen zeitpunkt ändern und der Zeitpunkt geht ja erst recht über die sample rate.


PS: bei dieser Art von Zitats Diskussionen kannst du auf Antworten klicken das markieren das du zitieren willst und auf den Zitat Knopf oben am jeweilen post klicken, da macht dann Javascript oder so den rest.. aber psst erzähls nicht weiter ;-)
 
Computerliebe schrieb:
Nein, ist es nicht du hast recht. Es ist sozusagen sub-oktav pwm oder sowas, oder einfach der einfachheit halber ein "Sinuswellen-umschalt-Oszillator".
Das was ich mache hat aber den vorteil das es keinen DC offset erzeugt, aber ja genaugenommen ist es kein PWM aber es klingt bissiger ;-)

okay, das leuchtet ein. schaltest du denn beim minimum die frequenz auch wieder um? sonst gibt's ja doch DC offset.

Computerliebe schrieb:
Interessant, nur den Code muss man dann ja trotzdem extra schreiben. Der shruthi ist in c++ programmiert

klar - den code musst du schon noch schreiben ;-) aber matlab ist näher an C bzw. lässt sich C ähnlicher schreiben, als eine sprache wie chuck.

Computerliebe schrieb:
Einen Sinus hat der Shruthi ja schon eingebaut, nur ich glaube das das im endeffekt aufs gleiche hinausläuft wie oben, ich muss ja die Interpolation im richtigen zeitpunkt ändern und der Zeitpunkt geht ja erst recht über die sample rate.

ja da hast du recht. ist die samplingrate denn fix im shruti und gepitcht wird über resampling (=interpolation) oder pitcht er über änderung der samplingrate? im zweiteren fall ginge mein jüngster vorschlag nämlich nicht.


Computerliebe schrieb:
PS: bei dieser Art von Zitats Diskussionen kannst du auf Antworten klicken das markieren das du zitieren willst und auf den Zitat Knopf oben am jeweilen post klicken, da macht dann Javascript oder so den rest.. aber psst erzähls nicht weiter ;-)

schon, aber ich tippe lieber - geht schneller ;-) dir zuliebe habe ich aber diesmal deinen namen hinzugefügt. :adore:

evtl. bekomm ich das nach meiner methode schnell in octave zusammengeschustert. dann könnten wir die audioqualität der mtethoden vergleichen :)
hast du mac, linux oder pc? unter umständen geht das auch in C ganz schnell.
 
haesslich schrieb:
okay, das leuchtet ein. schaltest du denn beim minimum die frequenz auch wieder um? sonst gibt's ja doch DC offset.
Nein eben nicht, das sind sozusagen cosinus wellen, jede Periode durchläuft von 0.25 bis 0.25 ---> kein dc offset.

haesslich schrieb:
ja da hast du recht. ist die samplingrate denn fix im shruti und gepitcht wird über resampling (=interpolation) oder pitcht er über änderung der samplingrate? im zweiteren fall ginge mein jüngster vorschlag nämlich nicht.

Das muss ich noch schaun, die Samplerate im am PWM output pin ist fix, wie das intern abrennt kommt dann darauf an. Ich glaub der nimmt einfach das nächste sample das passt und überspringt die Werte die er nicht braucht.

haesslich schrieb:
evtl. bekomm ich das nach meiner methode schnell in octave zusammengeschustert. dann könnten wir die audioqualität der mtethoden vergleichen hast du mac, linux oder pc? unter umständen geht das auch in C ganz schnell.

Linux und Gentoo (mir wurde mal gesagt ich muss masochistisch veranlagt sein ;-) )

Was brauch ich denn am besten für octave? Ich nehm an Qtoctave als IDE?

comiliert wohl mit
fftw
Global: Use FFTW library for computing Fourier transforms
opengl
Global: Adds support for OpenGL (3D graphics)

sonst noch was?

edit: oh....
Total: 21 packages (21 new), Size of downloads: 103,302 kB
100mb quellcode das wird dauern...
 
Computerliebe schrieb:
Nein eben nicht, das sind sozusagen cosinus wellen, jede Periode durchläuft von 0.25 bis 0.25 ---> kein dc offset.
aber DC offset hast du doch nur dann nicht, wenn positive halbwelle und negative halbwelle gleich viel energie haben. d.h. du brauchst von jeder halbwelle genau die hälfte einmal mit höherer, und einmal mit niedrigerer geschwindigkeit. dafür musst du beim sinus von 0.25 die geschwindigkeit ändern und bei 0.75 wieder rückgängig machen. machst du das so? hab ich jetzt nicht so verstanden :sad:
wieso eigentlich nicht gleich cosinus? :)

Computerliebe schrieb:
Das muss ich noch schaun, die Samplerate im am PWM output pin ist fix, wie das intern abrennt kommt dann darauf an. Ich glaub der nimmt einfach das nächste sample das passt und überspringt die Werte die er nicht braucht.

wenn er das so macht, mach dir um aliasing in deinem algorithmus mal keine sorgen. :) das ist dann die geringste aliasingquelle. der audio output geht echt über pwm?


Computerliebe schrieb:
Was brauch ich denn am besten für octave? Ich nehm an Qtoctave als IDE?

du ich wollt dir nix aufschwatzen. ich nehme immer irgendeinen editor mit syntax highlighting, mir ist recht egal welcher, weil octave eh keinen debugger hat. der rest geht über die shell.
habe auch noch nicht angefangen :sad: bin am ehx 2880 kleben geblieben.
 
uh das wird auch nix mehr bei mir heute :-/ aber ich hab blut geleckt. ich werd mich nächste woche mal dran geben :) vielleicht gibt's ja dann schon was vom shruti, dann weiß ich, wo die messlatte liegt! :)
 
So ich hab jetzt angefangen ein bischen im shruhi quellcode zu schmökern.

Das beste wird wohl sein 2 Tabellen zu benutzen in eine die neue Wellenform zu schreiben und dann an der richigen Stelle die dann auszutauschen. Quasi "buffering" wie das bei Grafik gemacht wird.
Hat dann den Vorteil das es nicht so tragisch ist wenn die neue Wellenform nicht rechtzeitig fertig wird da ja noch die alte vorhanden ist (im zweifelsfall wird weitergemacht und erst zeiger ausgetauscht wenns fertig ist) und es keine Artifakte geben kann.
 
mit meinem octave code klingt das ganze so:


klingt alles ziemlich "grainy" und schmutzig, weil die lookup table nur 2048 einträge hat und als resampler nur eine lineare interpolation genutzt wird. aber so würde ich das ganze auch auf einem leistungsschwachen chip machen.
 

Anhänge

  • sineMod.mp3
    180,6 KB · Aufrufe: 6
Ui das ging aber schnell :shock:
Das ist aber die Symmetrieverschiebung die du oben angesprochen hast, klingt etwas anders aber ja das Prinzip ist das selbe.

Wäre aber interressant welche sachen sich mit dem Prinzip noch erzeugen lassen.

Jetzt wäre es möglich phasen auszulassen, mit unterschiedlichen frequenzen zu arbeiten oder an anderen stellen umzuschalten. Da gibts sicher noch möglichkeiten, wobei da der shruthi als plattform warscheinlich bald nicht mehr ausreicht. Da gibts auch nur 1 1/2 parameter, eines ist fürs frequenzverhältnis (oder "pulsebreite" ) ein anderes kann auch noch benutzt werden indem die fußlage dazu benutzt wird. (Das macht die FM implementation so)


Und klangmäßig reicht das doch, wie gesagt der shruthi ist 8 bit mit 39khz sample rate.. Die interpolation aufn shruthi hab ich mir noch nicht genau angeschaut, aber da ist schon was eingebaut und einen Sinus gibts auch, da ist die meiste arbeit sich mit der Basis vertraut zu machen der eigendliche code ist dann schnell erledigt..

Jetzt haben wir quasi schon 2 verschiedene Algorithmen: 1x Steigende und fallende Flanke unterschiedlich (deins) und 1x eine gesamte Periode abwechselnd (meins)
 
Computerliebe schrieb:
1x eine gesamte Periode abwechselnd (meins)

das hatte ich zuerst - aus versehen (kleiner bug in meinem code ;-) ).
ich hab grad mal in den shruti code geschaut. die wellenformen da drin sind look up tables mit 256 samples, wenn ich das richtig sehe, die interpolation ist im inline assembler. das hab ich mir jetzt noch nicht genauer angeschaut ;-)
die wellenformen haben 8 bit, sind aber bandlimitiert. warum die square wellenform nun aber gleich mehrmals drin ist, hab ich noch nicht verstanden. könnte aber klappen, den sinus code da reinzubekommen :)

Computerliebe schrieb:
Jetzt wäre es möglich phasen auszulassen, mit unterschiedlichen frequenzen zu arbeiten oder an anderen stellen umzuschalten.

an anderen stellen umzuschalten wird wohl nicht anders klingen, das ist in der fouriertransformierten ohnehin nur ein konstanter phasenoffset.
 
haesslich schrieb:
ich hab grad mal in den shruti code geschaut. die wellenformen da drin sind look up tables mit 256 samples, wenn ich das richtig sehe, die interpolation ist im inline assembler. das hab ich mir jetzt noch nicht genauer angeschaut
achja genau, das ist das assembler stück...
Wo hast du denn die länge der Lookup Tables gefunden, hab da gesucht und nichts gesehen :sad:

haesslich schrieb:
die wellenformen haben 8 bit, sind aber bandlimitiert. warum die square wellenform nun aber gleich mehrmals drin ist, hab ich noch nicht verstanden. könnte aber klappen, den sinus code da reinzubekommen
Sinus verwendet die FM implementation, das ist im Shruthi im dreieck wavetable abgelegt das geht von dreieck bis sinus. Ach da kommt mir gleich eine Idee wie man das interessanter klingend machen kann.
Das geht ja auch mit dreieck und allen dingern dazwischen ;-)

haesslich schrieb:
an anderen stellen umzuschalten wird wohl nicht anders klingen, das ist in der fouriertransformierten ohnehin nur ein konstanter phasenoffset.
Eben nicht, zumindest bei mir nicht. Es klingt "ähnlich" aber wenn ich beim nulldurchgang umschalte klingt das ganze viel heller als beim maxima. Wie das bei deinem Algo ist weis ich nicht, aber ich vermute das ist ähnlich.
Du musst bedenken das das "umschalten" selber eigendlich hörbar ist nur wie es sich auswirkt unterscheidet sich.

Am nulldurchgang zb hast du einen sichtbaren knick der sich dann als hochfrequentes auswirkt. Selbstverständlich kannst du aber die amplitude so anpassen das der knick verschwindet, dann klingt es vielleicht gleich, aber wer weis, müsste man ausprobieren...

In der Fourieranalyse siehts auch anders aus, das eine geht mit den Frequenzspitzen bis an die Nyquist Frequenz das andere lässt die Spitzen souverän verschwinden bevor sie oben anstoßen :D
 
Computerliebe schrieb:
Eben nicht, zumindest bei mir nicht. Es klingt "ähnlich" aber wenn ich beim nulldurchgang umschalte klingt das ganze viel heller als beim maxima. Wie das bei deinem Algo ist weis ich nicht, aber ich vermute das ist ähnlich.
Du musst bedenken das das "umschalten" selber eigendlich hörbar ist nur wie es sich auswirkt unterscheidet sich.

Am nulldurchgang zb hast du einen sichtbaren knick der sich dann als hochfrequentes auswirkt. Selbstverständlich kannst du aber die amplitude so anpassen das der knick verschwindet, dann klingt es vielleicht gleich, aber wer weis, müsste man ausprobieren...

ich probiere das einfach mal aus und melde mich dann wieder. momentan ist mein code ja so geschrieben, dass ein cos erzeugt wird, und immer beim maximum / minimum umgeschaltet wird, wie du es ja auch machst.

und wie groß die look up tables sind habe ich in der ressource.h / ressource.cc einfach abgezählt ;-)
 
ausprobiert. da lag ich wohl falsch - also das spektrum ist nicht identisch. geht ja auch gar nicht - es gibt ja einen großen DC offset, wenn man am nullpunkt umschaltet, und nicht am max/min. die hohen frequenzen sind auch etwas weniger gedäinmpft, etwas schärfer.
 
haesslich schrieb:
und wie groß die look up tables sind habe ich in der ressource.h / ressource.cc einfach abgezählt
ah thx, aber ich hab da 257 werte, auch in oscillator.h so drinnen afik.
Oder sind das dann 256 "praktische" werte? eigenartig... :?
haesslich schrieb:
ausprobiert. da lag ich wohl falsch - also das spektrum ist nicht identisch. geht ja auch gar nicht - es gibt ja einen großen DC offset, wenn man am nullpunkt umschaltet, und nicht am max/min. die hohen frequenzen sind auch etwas weniger gedäinmpft, etwas schärfer.
Ja wäre ja wunderlich wenn 2x der selbe algortithmus 2x unterschiedliche ergebnisse liefert.
Was jetzt interessant zu wissen wäre ist ob ein anpassen der amplitude zu einem ähnlichen ergebnis führt, auch wenn ich das nicht ganz glaube... Das extrema scheint ja ein ausnahmefall zu sein.

Im Prinzip müsste eigendlich nur die Amplitude entsprechend des Frequnzverhältnisses angepasst werden damit der knick verschwindet. Höhere Frequenz => niedrigere Amplitude, so müsste dann die steigung konstant bleiben. Ich glaub aber trotzdem nicht das sich das dann gleich anhört wie beim extrema da die energie die in die höherfrequente Schwingung geht geringer ist.
Obwohl, wer weis wie das das Ohr/das Hirn wahrnimmt.
Was jedenfalls sicher ist ist das es sich anders anhört als eine einfache mischung eben jener frequenzen, das habe ich schon früher mal ausprobiert ;-)


Mit dem Shruthi Quellcode komm ich leider nicht ganz klar, auch wenn auf der Seite das wunderschön beschrieben ist. Da befürchte ich fast das der Code im gesamten context verstanden werden muss um zu begreifen wie ein neuer Oszillator da rein soll, insoweit ist chuck schon viiel einfacher...
Wie machen das dann die ganzen OSS Developer? Haben die Zeit gepachtet oder sind das einfach solche freaks... ? Ich jedenfalls versteh auf dem ersten blick bahnhof :|
 
Computerliebe schrieb:
ah thx, aber ich hab da 257 werte, auch in oscillator.h so drinnen afik.
Oder sind das dann 256 "praktische" werte? eigenartig... :?
hab das nur überschlagen ;-) aber sind tatsächlich 257 werte. warum es keine 2er potenz ist, hab ich nicht nachgeschaut.
Computerliebe schrieb:
Ja wäre ja wunderlich wenn 2x der selbe algortithmus 2x unterschiedliche ergebnisse liefert.
letztlich ist es ja nicht der selbe algorithmus.
Computerliebe schrieb:
Was jetzt interessant zu wissen wäre ist ob ein anpassen der amplitude zu einem ähnlichen ergebnis führt, auch wenn ich das nicht ganz glaube... Das extrema scheint ja ein ausnahmefall zu sein. Im Prinzip müsste eigendlich nur die Amplitude entsprechend des Frequnzverhältnisses angepasst werden damit der knick verschwindet.
Höhere Frequenz => niedrigere Amplitude, so müsste dann die steigung konstant bleiben. Ich glaub aber trotzdem nicht das sich das dann gleich anhört wie beim extrema da die energie die in die höherfrequente Schwingung geht geringer ist.
edit: jetzt hab ich's glaub ich geschnallt mit der amplitude - es geht um die amplitude des signals insgesamt oder? das ist ja suboptimal: der oszillator sollte schon gleich laut bleiben ;-)

Computerliebe schrieb:
Mit dem Shruthi Quellcode komm ich leider nicht ganz klar, auch wenn auf der Seite das wunderschön beschrieben ist. Da befürchte ich fast das der Code im gesamten context verstanden werden muss um zu begreifen wie ein neuer Oszillator da rein soll, insoweit ist chuck schon viiel einfacher...
Wie machen das dann die ganzen OSS Developer? Haben die Zeit gepachtet oder sind das einfach solche freaks... ? Ich jedenfalls versteh auf dem ersten blick bahnhof :|
ja das sind freaks, und leute, die wirklich viel programmieren. ich habe leider keine shruti hier (und auch keine lust mehr auf's löten ;-) ) sonst würd ich das selber ausprobieren. AVR Studio und ISP hardware sind hier nämlich vorhanden.
Chuck ist da auch nicht einfacher: Du kannst ja versuchen, deinen Oszillator mal als Chuck Befehl / Modul in Chuck einzubauen - Chuck ist ja auch open source... Da siehst du dann, dass das auch nicht einfacher ist, als das gleiche beim Shruti zu tun.
 
haesslich schrieb:
edit: jetzt hab ich's glaub ich geschnallt mit der amplitude - es geht um die amplitude des signals insgesamt oder? das ist ja suboptimal: der oszillator sollte schon gleich laut b
Nein umgekehrt, die Amplitude der höheren frequenz wird verringert, die niedrigere bleibt auf 0db. (Ein Sinus mit 3facher frequenz aber 1/3 amplitude hat die selbe steigung am nulldurchgang)

haesslich schrieb:
sonst würd ich das selber ausprobieren. AVR Studio und ISP hardware sind hier nämlich vorhanden. Chuck ist da auch nicht einfacher: Du kannst ja versuchen, deinen Oszillator mal als Chuck Befehl / Modul in Chuck einzubauen - Chuck ist ja auch open source... Da siehst du dann, dass das auch nicht einfacher ist, als das gleiche beim Shruti zu tun.
Ja ich glaube ich werd das einfach mal in chuck soweit bringen das es produktiv benutzbar ist und dann weitersehen. In chuck als extra unit generator einbauen ginge ja auch das ist ja auch in c++ und benutzt ein akademisches dsp libary, das ist sicher besser um sowas zu lernen.
Chuck selbst hat halt schon eine menge fertige sachen eingebaut, besonders wie zeit gehandhabt wird ist gegenüber anderen sprachen im vorteil (einfacher, höhere abstaktionsebene)


Was anderes, Mathematisches: Auch wenn das mit dem Shruthi warscheinlich nicht hinhauen würde, aber mit chuck ginge das toll.
Tim Stinchcombe hat auf seiner Seite Filtermodelle von 303 und monotron aus den Schaltungen abgeleitet. Jetzt würde ich gerne diese modelle dazu benutzen in chuck die entsprechenden filter drinnen zu haben.

Das sind die "Übertragungsfunktionen von der Laplace Transformation". Ich hab aber leider nicht die nötige bildung um das zu begreifen, die Frage ist jetzt wie schnell lässt sich das nachholen...
Sagen wir mal so: Ich weis zwar was Differntialgleichungen machen habs aber noch nie benutzt.

Was ich machen muss hab ich glaube ich schon herausgefunden:
http://en.wikipedia.org/wiki/Bilinear_transform
... ich weis aber nicht wie.
 
filter sind der heilige gral. das ist nicht so einfach, wie es auf den ersten blick scheint, du kommst schnell in gebiete rein, die du erstmal aussen vor gelassen hast, z. b. stabilität, oversampling, etc. bis hin zu numerischer genauigkeit bei berechnung mit float zahlen. ich habe nicht die leisesten zweifel, dass du mit etwas zeit und fleiß die laplace transformation genug beherrschen lernst, und auch die bilineare transformation, aber wenn es dann zur implementierung kommt, ist es eben damit nicht mehr getan. ab da reden wir über einen zeitraum von jahren des lernens.

und was den lautstärkeknick angeht: da reden wir offenbar aneinander vorbei ;-) wenn es dir nun um die steigung am nulldurchgang geht: die darf unstetig sein. dagegen KANNST du letztlich nichts tun, ausser du änderst die frequenz nur in kleinen schritten.
 


Neueste Beiträge

News

Zurück
Oben