Forum: Compiler & IDEs White Noise DAC


von mirko (Gast)


Lesenswert?

hallo,

ich weiß, es gibt schon ein paar Foreneinträge zum Thema, aber ich habe 
leider nicht das richtige gefunden.

ich möchte mit einem ATtiny 44a per DAC weißes Rauschen zum Hören 
erzeugen.
Das ganze kann ohne Proble Psudozufall sein.

ich habe srand() und rand() der stdlib gefunden und damit folgendes 
gemacht:

#include <avr/io.h>
#include <stdlib.h>
void pwminit(void)
{
  DDRA = (1 << PA6 );    // ATtiny44A OC1A pin
  TCCR1A = (1<<COM1A0);  // Compare Output Mode for Channel A
  TCCR1B = (1<<WGM12)  | (1<<CS10);  // CTC (Clear Timer on Compare) | 
no prescaling
}
int main()
{
  srand((unsigned int)600); // Startzahl für Pseudozufall setzen
  pwminit();
  while (1)
  {
   OCR1A = ((rand()%500) + 200); // Zufällige Freq in Dauerschleife
  }
}


nun höre ich ganz schnell viele zufällige Töne, aber kein Rauschen, 
dafür ist es noch zu langsam obwohl der Prescaler Null ist.

Vielleicht benutze ich den falschen PWM-Mode für sowas?
Fast-PWM?

Ich möchte ja eigentlich nicht zufällig verschiedene Frequenzen ausgeben 
sondern zufällig verschiedene Spannungen --> Rauschen

Funktioniert es vielleicht wenn ich ein RC-Glied an den Ausgang schalte 
um das ganze zu glätten?
Wenn ja, wie dimensioniere ich dieses?

Kann ich mir das nicht sparen und irgendwie direkt ein Rauschen 
ausgeben?
daher dachte ich zufällig verschiedene Frequenzen. Er Schaltet nur 
leider zu langsam.


Für Antworten, Anmerkungen, Tips und Tricks bin ich sehr dankbar

Mirko

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Das rand() wird wohl viel zu lange brauchen, denn das beinhaltet
bereits Divisionsoperationen.  Deine zusätzliche Division macht
es nicht besser.

Ich glaube, ein Controller dieses Formats ist mit einem LFSR einfach
in der Geschwindigkeit überfordert.  Sowas könnte man am besten auf
einem FPGA implementieren, ein CPLD könnte ebenfalls genügen.

von mirko (Gast)


Lesenswert?

> Das rand() wird wohl viel zu lange brauchen, denn das beinhaltet
> bereits Divisionsoperationen.
 Ja genau, die Rechnung selbst ist zu langsam. Der Versuch mit fast PWM 
ergab schnelleren Zufall, teilweise auch Rauschen, aber auch immer ein 
hohen Dauerton mit Rauschanteilen.
>Deine zusätzliche Division macht
> es nicht besser.
OCR1A = ((rand()%500) + 200  bedutet doch nur dass 500 Zufallszahlen ab 
199 möglich sind. Also 199, 200, 201, ... , 699
?

auch die Primzahlinkremitierung habe ich versucht, was ja schneller ist 
(siehe Post Beitrag "pseudo zufall als pwm ersatz"), ergab aber 
leider kein Rauschen, sonder interresante Töne.

FPGA und CPLD hören sich kompliziert an
ich möchte das eigentlich auch nur digital erzeugen um verschieden 
gefärbtes Rauschen schnell programmieren zu können.

dac <-- zu teuer

Da gibt es noch die Möglichkeit mit externen Rauschgeneratoren 
(Zehnerdiode+OPamp, Radio ect.) und diese dann analog zu Filtern...

hat jemand noch eine Idee?

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

mirko schrieb:

> OCR1A = ((rand()%500) + 200  bedutet doch nur dass 500 Zufallszahlen ab
> 199 möglich sind. Also 199, 200, 201, ... , 699
> ?

Ja, allerdings ist eine Division durch 500 langsam.  Wenn du durch
512 dividieren würdest, geht es viel schneller.

> FPGA und CPLD hören sich kompliziert an

Naja, ein LFSR dürfte dort eher zu den Einsteigerübungen gehören.
Gut, die PWM müsste man noch mit drauf implementieren, aber sowas
findest du bestimmt als fertigen IP-Block.

von Arc N. (arc)


Lesenswert?

mirko schrieb:
> dac <-- zu teuer

Wie hoch ist denn die Stückzahl...
Selbst bei Farnell gibt's z.B. Stereo-Audio-DACs (WM5824) mit LineOut 
für 1.34 € (ab 1 St.)
MCP4725 (12-Bit DAC) für 1.39 €

von Juergen (Gast)


Lesenswert?

Versuchs mal mit einem Twisted GFSR, die brauchen nur wenige schnelle 
Operationen pro Zufallszahl.

http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/ARTICLES/tgfsr3.pdf

Deren Hauptproblem ist, dass die vorgegebenen zu viel Speicher brauchen, 
und dass man gute Parameter für kleinere finden muss.
Das kann man durch Ausprobieren und Testen mit Diehard o.ä. machen.

von mirko (Gast)


Lesenswert?

> Selbst bei Farnell gibt's z.B. Stereo-Audio-DACs (WM5824) mit LineOut
> für 1.34 € (ab 1 St.)
> MCP4725 (12-Bit DAC) für 1.39 €
danke, guter Tip, ist mir dafür jetzt leider auch noch zu teuer.

> Versuchs mal mit einem Twisted GFSR, die brauchen nur wenige schnelle
> Operationen pro Zufallszahl.
hört sich sehr gut an, guck ich mir mal genauer an

mir ist eingefallen, dass es doch auch die Möglichkeit gibt die Zahlen 
fest einzuprogrammieren und geloopt wiederzugeben. Dann braucht er keine 
Rechnung zu machen sondern muss nur nachgucken welchen wert er als 
nächstes ausgibt.
Also pseudo-pseudo-zufall (kein Zufall). Irgendwie etwas wirres wie 
011110010000100000000111101111111111100001001010000001001000000000 
müsste doch Rauschen ergeben, wenn es lange genug ist bevor es sich 
wiederholt.

Wie gebe ich sowas schnell aus? einfach nacheinander
DDRA = (1 << PA3 );
DDRA = (0 << PA3 );
DDRA = (0 << PA3 );
DDRA = (1 << PA3 );
DDRA = (1 << PA3 );
...
?

also eine Liste die, die Zahlen für Rauschen schon enthält. 1-Bit Sound.

vielen Dank    Mirko

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

mirko schrieb:
> Also pseudo-pseudo-zufall (kein Zufall).

Was anderes ist rand() ja auch nicht, allerdings hat es meiner
Meinung nach 2^31 verschiedene Zustände.  Die willst du nicht im
Flash-ROM haben. ;-)

von mirko (Gast)


Lesenswert?

> 2^31 verschiedene Zustände.  Die willst du nicht im
> Flash-ROM haben. ;-)

ein Bruchteil davon würde schon genügen? Eben den Flash voll machen? und 
dann wiederholt es sich. Gegen wiederholung vielleicht eine sehr 
einfache Rechnung noch dazu?

Mirko

von Detlef _. (detlef_a)


Lesenswert?

LFSR sollte doch auch schnell hinzukriegen sein: Man nimmt für jeden TAB 
ein ganzes Byte um ohne die Bitschiebereien hinzukommen, Länge des 
arrays ne Potenz von 2 zB 32, dann nen Pointer auf das array, damit man 
die Bytes nicht schieben muß. Insgesamt also zB vier Speicherzugriffe, 
XOR, abspeichern, Pointermanipulation, fertig ist die Laube. Ich denke, 
da sollten 20 oder 30 Assemblerbefehle ausreichen, mit 16MHz getaktet 
ist man da bei 500KHz Schleifenfrequenz, reicht.

Cheers
Detlef

von geb (Gast)


Lesenswert?

Ich hab das schon mal gelöst.Allerdings auf einem ADUC841 mit externem 
RAM.
Die simle Funktion für Zufallszahlen:

void make_audio_buf(void)
{
unsigned int i,temp1;
temp1=0x7FFF; //Startwert
for(i=0;i<0x4000;i++){temp1=(temp1*5+3);

    audio_buf[i]=temp1/32;
    }

}
Die Ausgaberate (auf dem 12bit DAC) war 16384Hz. Das lieferte ein 
schönes konstantes Rauschen ohne hörbare Periodizität.
Bei höherer Rechenleistung und/oder geringerer Ausgaberate können die 
Werte auch in Echtzeit gerechnet werden.

Grüße Gebhard

von Michael U. (amiga)


Angehängte Dateien:

Lesenswert?

Hallo,

vielleicht ein Ansatz:

das ist mein Kaminfeuer im Puppenhaus.
2 Pseudo-Zufallsroutinen (rückgekoppeltes Schieberegister), irgendwo im 
Netz gefunden.

Mein Ansatz für das Rauschen wäre jetzt entweder auf einen Port ausgeben 
und dann ein R2R-Netzwerk dran oder das Compareregister einer PWM damit 
füttern.

Gruß aus Berlin
Michael

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.