www.mikrocontroller.net

Forum: Digitale Signalverarbeitung / DSP Pinknoise wie geht das


Autor: oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo, ich wollte ein Pinknoise Siganl erzeugen (10sec) und dann
ausgeben. Nur funktioniert alles was ich programmiere nicht.
Habe ein Puffer mit Rauschen gebaut den dann stückchenweise mit einer
FFT gewandelt Pinknoise gewichtung und inverse FFT drüber. Dann die
Ergebnisse aneinander gehangen und ausgegeben. Kommt nur nicht das raus
was ich erwarte. Was mach ich falsch? Gibt es irgendwo ein Sourcecode
den ich benutzen kann?

Muss ich überhaupt über den Umweg Rauschen - FFT gehen? Mir reicht es
wenn ich im Signal genau die Frequenzen der FFT habe. Habe ich
versucht, bekomme ich nur auch nicht hin.

PS: Audio ist nicht mein Fachgebiet, wie Ihr sehen könnt. Muss nur
jetzt leider die Studienarbeit durch ziehen.

Autor: Christian G. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nette Datei nur was besagt Sie?  Der Link in der Datei ist auch Tot.

Autor: Christian G. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was sie besagt steht gleich in der ersten Zeile: ein Filter, das rosa
Rauschen aus weissem macht.
Das ist doch, was du haben willst, rosa Rauschen ohne (I)FFTs, oder
nicht?
Rosa Rauschen ist ein Rauschsignal, dessen spektrale Leistungsdichte
mit einer Rate von ~3dB/Oktave oder 10dB/Dekade abnimmt. Du nimmst also
weißes Rauschen und filterst es mit dem im Text beschriebenen Filter ->
rosa Rauschen.
Hier ist noch ein Link, der garantiert nicht tot ist und die Thematik
erschöpfend durchkaut und dabei auch auf das im Textfile beschriebene
Filter eingeht.

http://www.firstpr.com.au/dsp/pink-noise/

Autor: Dirk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Leute, ich habe ein ähnliches Problem.
Ich will ein Audio Signal (48000Hz Samplerate) berechnen, ausgeben und
wieder aufnehmen (Lautsprecheranalyse). In dem Signal sollen nur die
Frequenzen drin sein die ich später wieder aus der FFT (1024 .. 8192)
raus bekomme.
Ich will die Pegel der einzelnen Frequenzen einstellen können
(-90.0dB  - +10.0dB). Zufalls Zahlen kann ich hier nicht gebrauchen da
alles 100% reproduzierbar sein muss.
Habe es anscheinend wie Oliver probiert und bin auch gescheitert.
- Array [1024] mit Level gebaut (Realteil), Imaginärteil = 0 und alles
mit einer Inverse FFT gewandelt --> kommt nur mist raus und den dann in
einer schleife ausgeben. Macht die Sache auch nicht besser.

Also auch meine Frage wie geht das? Was mache ich und wohl auch Oliver
falsch?

Autor: Detlef _a (detlef_a)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Liebe Freunde der IFFT,

so schlicht wie oben geschildert is das auch wieder nich. Die FFT eines
reellen Zeitsignals ist conjugiert komplex, das muß man berücksichtigen
bei der Generierung eines reellen Zeitsignals. Alle Imaginärteile 0
setzen bringts auch nich, dann kommt bei der IFFT nen Impuls raus.

Cheers
Detlef

Gehn tut das in Matlab so:

n =8192;
nh=n/2;
H   =ones(1,n); % alle f drin
H(1)=0;          % ausser Gleichspannung
H(100)=0;        % und f100 zum Beispiel
% bisschen Phasen durchdrehn, sonst gibts nur nen Impuls
H=H.*exp(sqrt(-1)*2*pi*rand(1,n));
H=[H(1:(nh+1)) conj(fliplr(H(2:nh)))];
h=ifft(H);
if(max(abs(imag(h)))>1e10)
    sprintf('Error: Ifft nicht rein reel')
end;
h=real(h);

Autor: Detlef _a (detlef_a)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Huch, so

n =8192;
nh=n/2;
H   =ones(1,n); % alle f drin
H(1   )=0;          % ausser Gleichspannung
H(nh+1)=0;          % und Nyquist
H(100)=0;        % und f100 zum Beispiel
% bisschen Phasen durchdrehn, sonst gibts nur nen Impuls
H=H.*exp(sqrt(-1)*2*pi*rand(1,n));
H=[H(1:(nh+1)) conj(fliplr(H(2:nh)))];
h=ifft(H);
max(abs(imag(h)))
if(max(abs(imag(h)))>1e-10)
    sprintf('Error: Ifft nicht rein reel')
end;
h=real(h);

Autor: Dirk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nun Ja!!??
Kann den Code zwar nicht vollständig verstehen (Habe noch nie was mit
Matlab zu tun gehabt).  Hauptproblem sind die zeilen :
H=H.*exp(sqrt(-1)*2*pi*rand(1,n));      Aufbau von H und H.== ?
H=[H(1:(nh+1)) conj(fliplr(H(2:nh)))];  ??? Verstehe nichts !

Wenn ich es aber richtig verstanden habe muss ich den Imaginär Anteil
jeder der Frequenzen die ich im Siganl habe mit einem zB. Zufalls wert
belegen. Und dann erst die IFFT machen. Werde ich SO mal testen.

Autor: Detlef _a (detlef_a)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nein, nicht den Imaginärteil mit nem Zufallswert belegen, sondern den
jeweiligen Frequenzen eine Zufallsphase geben. Die Zeile
H=H.*exp(sqrt(-1)*2*pi*rand(1,n)); multipliziert die Frequenzen mit 'e
hoch komplexem Zufallswinkel', das dreht die komplexe Zahl um diesen
Winkel, läßt den Betrag gleich. Zum Probieren kannst Du das erst auch
mal rauslassen, dann muß als Zeitsignal nen Impuls rauskommen.(Anders
formuliert: Wenn Du nur Realteile belegst, Imaginärteile alle 0 sind,
summierst Du Cosinusse der Phase 0 auf, die fangen alle mit 1 an, der
erste Zeitwert wird dann groß)

 Die Zeile H=[H(1:(nh+1)) conj(fliplr(H(2:nh)))]; ist der Schlüssel zum
Verstehen warums bei Dir nicht geht. Du muß Dein vorgegebenes Spektrum
um einen symmetrischen, konjugiert komplexen Anteil ergänzen.
'konjugiert komplex' heißt Realeil lassen wie er ist und Vorzeichen
Imaginärteil tauschen. Die Zeile nochmal in lang hingeschrieben, die
Indizes der arrays beginnen Matlab entsprechend bei 1 (vorsicht, in C
fangen die mit 0 an)

for(k=1:(nh+1)) Hneu(k   )=     Halt(k     ); end;
for(k=2:(nh  )) Hneu(k+nh)=conj(Halt(nh-k+2)); end;

Cheers
Detlef

Autor: Dirk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es Zuckt!
Also ich habe als Test geschrieben, in C:

for (i=0; i< 8192; i++) // Alles erstmal Löschen
{
 In_r [i] = 0;
 In_i [i] = 0;
}
In_r [170] = 200;  // ca. 1000 Hz Position (48000 kHz  -- 8192 Punkte)
In_i [170] = 200;
IFFT (In_r, In_I, Out_r,Out_i);  // 8192 Punkte FFT

Out_r ---> ausgeben ==> Ton von 1kHz ==> das was ich haben wollte!

Das ist schon mal Super.
Nur wie bekonne ich damit einen Ton von 10 Sekunden hin?
Als Loop ausgeben geht ja nicht, da ich nur 8192 Werte (= 0,17Sec)
habe und die passen nunmal nicht aneinander (sprung im Sinus Signal).
Das eintragen den gewünschten Frequenzen schaffe ich jetzt alleine,
habe jetzt wirklich "nur" noch das Problem einen 10sec Ton hin zu
bekommen.

Autor: Detlef _a (detlef_a)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nee, so machen:

In_r [170] = 200;  // ca. 1000 Hz Position (48000 kHz  -- 8192 Punkte)
In_i [170] = 200;
In_r [8192-170] = 200;
In_i [8192-170] = -200;

Nach der IFFT müssen die Out_i alle 0 sein, sonst is was faul. Dann
solte auch kein Sprung im Sinus sein, sondern exakt 170 Wellen in das
Fenster passen.

Cheers
Detlef

Autor: Dirk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kann es erst heute Abend wieder Probieren!

Funktioniert das auch mit den anderen Frequenzen?
Also mit 18158,2Hz Position 3099 oder 76,17Hz Position 13.

Autor: Detlef _a (detlef_a)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das funzt mit allen Frequenzen, einzeln oder zusammen, völlig egal!

Viel Spaß
Detlef

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So ich habe mein Pinknoise Generator. Der Link war super.
Danke.
Und den Anderen noch viel Spaß. Sieht ja so aus als wäre auch alles
gelöst.

Autor: Dirk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bei mir Funktioniert es noch nicht ganz.

Um mit dem Siganlstück ein  Dauersiganl zu bauen, darf der 1. Array
Wert (Out_r[0]) nie mit ausgegeben werden, ist immer 0 und past nicht
in das Siganl. Ansonsten kommt schon ein fast perfektes Signal raus.
Den Übergang  zwischen den einzelnen Loops kann ich noch leicht hören,
also werde ich ihn auch messen können. Ich mußte die IFFT auch auf
double umbauen, damit wurde der Out_i Wert auf ca +- 1,1*10^-8
gedrückt. Nur mit float war er deutlich höher. Der Ton wurde auch
besser.

Mir fiel gerade beim schreiben ein warum ich immer noch den Übergang
von Loop zu Loop hören kann. Ist doch klar ich habe doch einen Wert
nicht mit ausgegeben (Timing kann nun nicht mehr stimmen).
Also neuer Test:
Out_r[0]=(Out_r[1] + Out_r[8192-1])/2.0;  Wir basteln uns einen Wert.
Alles ausgeben ==> alles super, kein Plop & keine Phasenverschiebug
mehr

Ich lasse es nun so. Über einwände / Kommentare freue ich mich.
Ansonsten, Danke Detlef für Deine Hilfe, Dirk.

Autor: Dirk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ohje, beim aufräumen der ganzen Test Teile ist mir aufgefallen, das ich
eine gut versteckte Zeile "Out_r[0]=0.0;" drin hatte.
Also alles was ich gerade geschrieben habe geht zwar, ist aber
eigentlich für die Tonne.

Es funktioniert genau so, wie von Detlef beschrieben!
Noch mal Danke.

Autor: Dirk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja mit einer Frequenz funktioniert es Super.
Nur Wenn ich dann mal 10 hintereinander liegende Frequenzen nehme kommt
nur Müll raus. Habe auch mal ein Pinknoise damit versucht.
Das Ergebnis möchte ich mir gar nicht erst ansehen, so wie das vor sich
hin wobbelt und Plopt.
Wieso Funktioniert das mit einer Frequenz, nur nicht mit vielen
(alle)?

PS: mein Out_i Array war immer noch fast bei NUll.

Autor: Domi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi Leute

Tut mir leid das hier einfach so rein poste. Schreibe meine Maturarbeit
über Akustik, so genau hab ich mich noch nicht festgelegt. Wollte eine
Box auf ihre Eigenresonanzen abmessen und bräuchte einen Pinknoise.
Habe dann mal gegooglet und dabei kam nur ne Firma raus die so heisst
und dieses Forum. Leider versteh ich nicht viel von der Materie;
verstand nur Bahnhof was ihr da besprecht. Kann mir wer das mit dem
oben genannten Generator erklären und wo bekomm ich den?

Ich hoffe dieses Forum ist noch aktuell und jemand schreibt darauf!

Autor: Dirk (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hier ist ein Teil aus meinem Projekt. Ich hoffe ich habe genug drin
gelassen.
Ist nur ein Pink Noise Generator der nicht über eine FFT geht.
Hatte ihn irgendwo gefunden, wo kann ich nicht mehr sagen. Habe ihn an
meine Aufgabe angepasst.
Das Spektrum von dem Signal ist ein 1A Pink Noise.

Viel Spass!

Autor: Dirk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi Domi.

Hat der Code Dich weiter gebracht?

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.