Hallo,
ich erzeuge mit einem Xmega auf einem DAC einen Sinus, gebe den auf
einen Kopfhörerverstärker und höre mir das Signal an. Auf dem
Oszilloskop sehe ich keine Auffälligkeiten ich höre
jedoch (zu meinem sehr sauberen Sinus) immer eine zusätzliche Frequenz,
abhängig von der gewünschten Sinus Ausgangsfrequenz. Bei Frequenzen,
dessen Schrittweite ein ganzzahliger
Teiler meiner Samplerate ist, höre ich keine Störungen. Das ist für mich
ein starkes Indiz, dass es ein Software Problem ist, ich vermutete erst
ein analoges Problem.
Ich gebe im folgenden erstmal nur relevante Programmzeilen und nicht den
Code als Ganzes.
Folgende Formel berechnet die Schrittweite des DDS. Da ich die
Kommastelle möglichst groß mitnehmen will, multipliziere ich das ganze
mit 4096. Die Frequenz ist in hunderdstel
angegeben.
1
#define SAMPLE_SIZE 256 //Wieviele Sützstellen hat das Audiosample?
2
#define SPS 128000 //Frames per Second Audioausgabe
3
4
structs_Ton{
5
BYTEcPos;//Aktuelle Position im Sample-Array
6
BYTEcVol;//Lautstärke des auszugebenden Tones 0-0xFF
7
WORDwCounter;//Schrittweite addieren, bei >= 4096 leigt ein Schrittwechsel von cPos vor
8
WORDwStepSize;//Schrittweite pro fps
9
unsignedlongwFreqOld;
10
unsignedlongwFreq;//Frequenz des Tones
11
};
12
13
structs_Tong_asToene[2];//Toneinstellungen, aus denen die Audioausgabe berechnet wird
Per 2x DMA lasse ich zwei Buffer an den DAC ausgeben. Wenn ein DMA
fertig ist, wird dessen Ausgabebuffer neu berechnen und der zweite DMA
wird aktiviert. Der DMA wird von einem
Timer-Überlauf (Event, kein Interrupt) getriggert. Im folgenden der Code
für einen DMA, der zweite ist identisch, hat nur als Quelle einen
anderen Buffer.
1
#define F_CPU 32000000UL
2
#define DMA_BUFFER_SIZE 512
3
4
TCC1_CTRLA=1;//Timer für Audioausgabe
5
TCC1_PERBUF=F_CPU/SPS;//Timer auf Framerate bringen z.B. 1/128000 Sekunde
6
EVSYS.CH0MUX=EVSYS_CHMUX_TCC1_OVF_gc;//Event für DMA, jede 128000. Sekunde z.B.
7
8
DMA.CH0.CTRLA=DMA_CH_SINGLE_bm|DMA_CH_BURSTLEN_2BYTE_gc;//DMA Block macht bei jedem Trigger 2 Byte (signle)
9
DMA.CH0.CTRLB=0x02;//Interrupt Priorität 2
10
DMA.CH0.ADDRCTRL=DMA_CH_SRCRELOAD_BLOCK_gc//Nach jedem Block die Quelladresse reseten
11
|DMA_CH_SRCDIR_INC_gc//Quelladresse immer +
12
|DMA_CH_DESTRELOAD_BURST_gc//Zieladresse nach jedem Burst (2Byte) neu laden
13
|DMA_CH_DESTDIR_INC_gc;//Zieladresse immer +
14
DMA.CH0.TRIGSRC=DMA_CH_TRIGSRC_EVSYS_CH0_gc;//Triggerevtn ist Timer TCC1 overflow
Ich hoffe es ist verständlich und genug auskommentiert - leider
verschiebt das Forum meine Komentare so unschön. Was mache ich falsch,
bzw. kann ich diese überagerten Frequenzen überhaupt eliminieren? Ich
hab vor dem Kopfhörer einen Bandpass von 20Hz-20kHz.
Danke euch allen!
Nils H. schrieb:> Was mache ich falsch,
Zunächst einmal das - du liest nicht vor dem Posten:
>>Wichtige Regeln - erst lesen, dann posten!>>>> Groß- und Kleinschreibung verwenden>> Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang
-----^^^^^^^^^^^^^^^^^^^^
Ich würde noch dazufügen: vermeide unbedingt Tabs als Leerzeichen-
Ersatz. Jeder User hat andere Tab-Einstellungen und meistens
schauen Sourcen, die Tabs enthalten, scheisse aus.
Nils H. schrieb:> ich erzeuge mit einem Xmega auf einem DAC einen Sinus, gebe den auf> einen Kopfhörerverstärker und höre mir das Signal an.
Und wo ist der Tiefpass der dir die Sample-Frequenz unterdrückt?
Der Tiefpass sollte deutlich unter der halben Sampling-Frequenz
liegen sonst bekommst du aus deinem Verstärker Mischprodukte die
du gar nicht hören willst.
Mitlesa schrieb:> Nils H. schrieb:>> ich erzeuge mit einem Xmega auf einem DAC einen Sinus, gebe den auf>> einen Kopfhörerverstärker und höre mir das Signal an.>> Und wo ist der Tiefpass der dir die Sample-Frequenz unterdrückt?> Der Tiefpass sollte deutlich unter der halben Sampling-Frequenz> liegen sonst bekommst du aus deinem Verstärker Mischprodukte die> du gar nicht hören willst.
Bei 128kHz Samplingrate wären das 64kHz. Mein Bandpass hat eigentlich
einen Tiefpass der nach 20kHz wirkt, wobei das ja sowieso ausserhalb des
Hörbaren liegt. Oder ist meine Überlegung falsch?
Bitte keine Leerzeochen/Tabs Diskussion :).
Hier ein Schaltbild. Die Verstärkerung scheint keinen Einfluss zu haben.
Bei 125, 250, 500, 1000 Hz usw. ist vor oder nach dem Lm137000 nichts zu
von den Störungen.
Nils H. schrieb:> Hier ein Schaltbild.
Die Mischprodukte bilden sich in den Verstärkern/Halbleitern.
Ein Tiefpass für die DDS-Filterung muss direkt nach dem DAC
platziert werden.
Mitlesa schrieb:> Nils H. schrieb:>> Hier ein Schaltbild.>> Die Mischprodukte bilden sich in den Verstärkern/Halbleitern.> Ein Tiefpass für die DDS-Filterung muss direkt nach dem DAC> platziert werden.
Wie kann es dann sein, dass ich am Ausgangspin vom Xmega genau das
gleiche höre, wie am Verstärkerausgang?
Nils H. schrieb:> Wie kann es dann sein, dass ich am Ausgangspin vom Xmega genau das> gleiche höre, wie am Verstärkerausgang?
Ganz einfach: Dein Tiefpass taugt nichts.
W.S.
Ohne mir das Ganze im Detail angeguckt zu haben, rate ich mal:
- an mangelndem Tiefpass liegt es nicht,
- Deine Sinus-Tabelle ist mit 256 Samples zu grob,
- dadurch, daß Du die Sample-Position auf diese Tabelle berechnest, und
das ja nur auf ein Sample genau ist, bekommst Du einen Phasenjitter von
1/256tel der Periode. Das dürfte schon deutlich zu hören sein.
- Vermutlich würde eine Interpolation zwischen den Samples auch bei nur
256 Stützstellen reichen, um die Mischprodukte auf ein unhörbares Maß zu
reduzieren.
- Dürfte mit dem XMega schwierig hinzubekommen sein - ist halt auch kein
DSP.
W.S. schrieb:> Nils H. schrieb:>> Wie kann es dann sein, dass ich am Ausgangspin vom Xmega genau das>> gleiche höre, wie am Verstärkerausgang?>> Ganz einfach: Dein Tiefpass taugt nichts.>> W.S.
Aber Mitlesa schrieb, dass diese Störungen nach (und durch) den
Verstärker entstehen sollen.
Vor und nach dem Verstärker höre ich bei 125Hz keine Störungen. Bei 123
Hz z.B. höre ich vor und nach dem Verstärker die gleichen Störungen :/.
Thomas E. schrieb:> Ohne mir das Ganze im Detail angeguckt zu haben, rate ich mal:> - an mangelndem Tiefpass liegt es nicht,> - Deine Sinus-Tabelle ist mit 256 Samples zu grob,> - dadurch, daß Du die Sample-Position auf diese Tabelle berechnest, und> das ja nur auf ein Sample genau ist, bekommst Du einen Phasenjitter von> 1/256tel der Periode. Das dürfte schon deutlich zu hören sein.> - Vermutlich würde eine Interpolation zwischen den Samples auch bei nur> 256 Stützstellen reichen, um die Mischprodukte auf ein unhörbares Maß zu> reduzieren.> - Dürfte mit dem XMega schwierig hinzubekommen sein - ist halt auch kein> DSP.
Dann werde ich mal testweise die Samplerate erhöhen, das schafft der
Prozessor noch.
Thomas E. schrieb:> bekommst Du einen Phasenjitter von> 1/256tel der Periode.
Ja. Und nein. Das ist kein Phasenjitter sondern eine
konstante Frequenz die sich da ausbildet.
Nils H. schrieb:> Bei 128kHz Samplingrate
.... und 256 Stützwerten ergäbe sich also eine Störlinie
von 500Hz.
Dann lieber nur 2, 4 oder 8 Stützwerte bei 128Khz Samplingrate,
das ist leichter zu filtern.
Trotzdem muss man direkt nach dem DAC filtern/tiefpassen.
Mitlesa schrieb:> Ja. Und nein. Das ist kein Phasenjitter sondern eine> konstante Frequenz die sich da ausbildet.
Phasen"jitter" ist vielleicht das falsche Wort - es ergibt sich eine
Sägezahnförmige Modulation der Phase. Dieser Sägezahn hat eine konstante
Frequenz und ist dementsprechend als "Störton" auch höhrbar und liegt
meistens im Bereich der Nutzfrequenz (deshalb kann man es auch nicht
wegfiltern). Mit der Tiefpassfilterung des Signals hinter dem
D/A-Wandler hat das alles jedenfalls nichts zu tun.
Ich benutze ich 512 Byte Samplegröße. Die Störfrequenzen sind nun noch
ein gutes Stück lauter geworden.
Diese Frequenzen sind übrigens nie identisch, bzw. wiederholen ich
periodisch, die Frequenz wandert aber.
Nils H. schrieb:> Diese Frequenzen sind übrigens nie identisch, bzw. wiederholen ich> periodisch, die Frequenz wandert aber.
Wie? D.h., wenn Du eine konstante Frequenz des Nutzsignals erzeugen
willst, verändert sich laufend die Störfrequenz? Das müsste dann ggf.
doch noch ein anderer Effekt sein...
Wenn ich das Ausgangssignal in der Frequenz langsam erhöhe, dann
verändert sich auch die Frequenz des Störsignals periodisch(!) (wabert
also Sinusförmig um eine Grundfrequenz).
Zusätzlich kann ich die Samplerate beliebig ändern, ich höre immer die
selben Störfrequenzen, bzw. bei niedriger Samplerate werden sie nur
deutlicher hörbar.
Nils H. schrieb:> Zusätzlich kann ich die Samplerate beliebig ändern, ich höre immer die> selben Störfrequenzen, bzw
Such mal nach "spur reduction dds" und "phase dithered dds".
Mit einem einfachen Tiefpass ist den numerischen Artefakten jedenfalls
nicht beizukommen...
Nils H. schrieb:> Wenn ich das Ausgangssignal in der Frequenz langsam erhöhe, dann> verändert sich auch die Frequenz des Störsignals periodisch(!) (wabert> also Sinusförmig um eine Grundfrequenz).
Ok, das ist dann doch, was ich erwartet hätte. Natürlich hängt die
Frequenz von der eingestellten Frequenz des Nutzsignals ab. Bei
konstanter Frequenz des Nutzsignals ist also auch das Störsignal
konstant - hatte schon befürchtet, Du hättest etwas anderes beobachtet!
Vorhin beim Hundespaziergang hatte ich mal überlegt, wie man es
vielleicht ohne viel Rechenpower (für eine Interpolation) lösen könnte:
mit einem digitalen Filter beim Berechnen der Ausgabedaten. Ein simpler
Tiefpass als IIR-Filter bräuchte ggf. wenig Recourcen und könnte die
Phasensprünge vielleicht schon ausreichend glätten.
>Vorhin beim Hundespaziergang hatte ich mal überlegt, wie man es>vielleicht ohne viel Rechenpower (für eine Interpolation) lösen könnte:>mit einem digitalen Filter beim Berechnen der Ausgabedaten.
Ich vermute, dass ein lineare Interpolation zwischen zwei Abtastwerden
reichen würde. Man kann das als gewichtete Summe ausführen.
ChrisMicro schrieb:> Ich vermute, dass ein lineare Interpolation zwischen zwei Abtastwerden> reichen würde. Man kann das als gewichtete Summe ausführen.
Ja, denke ich auch! Dachte erst, man man könnte sich die echte
Interpolation durch das Filter mit weniger Rechenschritten pro Sample
sparen, aber bei näherem Hinsehen sieht es so aus, daß ein primitives
Filter allein nicht wirklich weiterhilft. Mit zwei Filtern (eins auf die
Phase, eins auf die Amplitude) würde es vielleicht klappen, aber da ist
die Interpolation direkt wahrscheinlich schon weniger Rechenaufwand.
Vermutlich kann man mit der Interpolation dann auch die Samplerate am
Ausgang auf ein "normales" Maß (<50 kHz) reduzieren, was den erhöhten
Aufwand an Rechenschritten pro Sample ausgleichen könnte.
Nils H. schrieb:> Ich habe diese Interferenzen ünbrigens auch bei einem Dreiecksignal.
Ich denke du musst dein Signal einmal spektral betrachten sonst
siehst du nicht woher die Nebenlinien kommen - das Oszilloskop
zeigt ja nur eine Momentaufnahme in der der (vermutlich weit
höherfrequente) Jitter nicht zu sehen ist.
Aufgrund des sauberen Signals kommt aber doch der Verdacht auf
könnte sich um eine Intermodulation ausserhalb des Synthese-
Vorgangs handeln.
Bei den üblichen Auflösungen von digitalen Oszis gehen die kleinen
Fehler wohl im Quantisierungsrauschen unter - das Ohr ist da aber
verdammt empfindlich! Ein gutes, altes Analog-Oszi könnte da vielleicht
etwas aufschlussreicher sein.
Da das Signal im Audiobereich liegt, kann hier Audacity sehr nützlich
sein:
http://www.audacityteam.org/
Ich verwende es oft dafür. Man kann die Samplelänge der Spektralanalyse
hoch setzen, dann hat man eine gute Frequenzauflösung.
chris_ schrieb:> So wie es aussieht, ist der Thread von einem Spam-Roboter befallen.
Korrekt, da hat einer einen Narren dran gefressen.
> Wahrscheinlich hilft nur schließen, schade um das Thema.
Einfach einen neuen Thread aufmachen und dort den Thread hier verlinken.