Hallo zusammen,
für ein Freizeitprojekt brauche ich mal Eure Hilfe.
Das Projekt an sich ist eher "langweilig".
Das habe ich schon im Rahmen der Ausbildung gemacht und wollte das nun
etwas erweitern.
Das ist eine Uhr.
Das "besondere" daran ist, dass es jede Minute, und Stunde ein
unauffäliger akustischer Ton abgespielt wird.
Jetzt kommt die Herausforderung: Die Lautstärke soll den
Umgebungsgeräuschen angepasst werden. Das Abspielen des Tons ist kein
Problem, die Lautstärke messen auch.
Leider bekomme ich Probleme bei der Lautstärkeregelung.
Als "Ton" benutze ich einfach die Rohe PCM Daten als Variable, die ich
mit PWM abspiele.
Mein Problem ist ganz einfach: wie erhöhe ich die Laustärke?
Der Pegel muss großer werden, dies ist klar.
Aber einfach "offset" draufaddieren (im unteren Teil der Kurve, bei
8-bit ist das unter 0x7F wird natürlich subtrahiert) geht nicht, weil
ich die kleinen Zahlen weniger ändern darf als die großen. Ansonsten
wird der Ton kaputt gehen.
Wie wird so was gemacht?
Ich hoffe, das ist genug Input für den Anfang.
Danke schon mal.
Grüße Nils
Nils schrieb:> Als "Ton" benutze ich einfach die Rohe PCM Daten als Variable, die ich> mit PWM abspiele.> Mein Problem ist ganz einfach: wie erhöhe ich die Laustärke?> Der Pegel muss großer werden, dies ist klar.> Aber einfach "offset" draufaddieren (im unteren Teil der Kurve, bei> 8-bit ist das unter 0x7F wird natürlich subtrahiert) geht nicht, weil> ich die kleinen Zahlen weniger ändern darf als die großen. Ansonsten> wird der Ton kaputt gehen.> Wie wird so was gemacht?
Wie wärs mit Multiplizieren statt Addieren?
>Wie wärs mit Multiplizieren statt Addieren?
war die erste Idee!
Leider funktioniert das nicht.
Der 8-bit PWM Register will die 8 bit.
80 (DEC) ist die Mitte.
Ich muss also MINDESTENS alles mit 2 Multiplzieren, da ich keine Zahl
mit z-B. 83,479 abspielen kann.
Und alles mit 2,3,4.. multiplizieren geht auch nicht. Selbst bei 2
werden die Spitzen abgeschnitten, und ich bekomme keine "stufenlose"
Regelung.
Habe ich einen Denkfehler?
Nils schrieb:> 80 (DEC) ist die Mitte.
Wohl eher 80 hex, nicht dezimal.
> Ich muss also MINDESTENS alles mit 2 Multiplzieren, da ich keine Zahl> mit z-B. 83,479 abspielen kann.
Dann wirds eben auf 83 gerundet. Geht eben nicht anders wenn du nur 8
Bit hast.
> Und alles mit 2,3,4.. multiplizieren geht auch nicht. Selbst bei 2> werden die Spitzen abgeschnitten, und ich bekomme keine "stufenlose"> Regelung.
Dann eben eine beliebige andere Zahl zwischen 1.0 und 2.0.
Oder du verstärkst das Ausgabesignal und machst dann bei Bedarf in
Software leiser statt lauter.
Nils schrieb:> Und alles mit 2,3,4.. multiplizieren geht auch nicht. Selbst bei 2> werden die Spitzen abgeschnitten,
Dann bist du schon beim Lautstärkemaximum. Egal wie du es machst, müßte
das Signal verzerrt werden, um es noch lauter zu bekommen.
Du solltest es anders herum angehen. Das Originalsignal ist maximal
ausgesteuert, nun skalierst du es entsprechend herunter, wenn es leiser
sein soll (Multiplikation mit < 1). Bedenke, daß bei dieser Skalierung
die Auflösung des Signals sich verringert. Bei 0,5 hast du z.B. nur noch
7 von deinen 8 Bit übrig.
Noch eine ganz andere Idee: Könntest du nicht die Lautstärke des
Lautsprecherverstärkers ändern?
Nils schrieb:>>Wie wärs mit Multiplizieren statt Addieren?> war die erste Idee!> Leider funktioniert das nicht.
Natürlich funktioniert das. Wenn man es richtig macht.
> Der 8-bit PWM Register will die 8 bit.> 80 (DEC) ist die Mitte.
Wie oben schon jemand bemerkt hat, ist wahrscheinlich eher 80 Hex die
Mitte.
> Ich muss also MINDESTENS alles mit 2 Multiplzieren, da ich keine Zahl> mit z-B. 83,479 abspielen kann.> Und alles mit 2,3,4.. multiplizieren geht auch nicht. Selbst bei 2> werden die Spitzen abgeschnitten, und ich bekomme keine "stufenlose"> Regelung.> Habe ich einen Denkfehler?
Ja. Gespeichert sein muß natürlich der "lauteste" Fall, denn nur damit
ist sichergestellt, daß die verfügbare Bitbreite bestmöglich ausgenutzt
wird.
Und multipliziert wird dann mit Zahlen zwischen 0.0 und 1.0. Natürlich
in Festkomma-Arithmetik repräsentiert als Zahl zwischen 0 und 255. Von
dem 16Bit-Ergebnis der Multplikation benutzt man nur die oberen 8 Bit
und fertig. Naja, fast. Je nach Hardware kann es nötig sein, eine
Offsetkompensation vorzunehmen, um wieder auf den Mittelwert von 80 Hex
zu kommen. Dazu muß dann ein konstanter Wert zu allen skalierten Samples
addiert werden. Konstant ist er aber nur, solange der Faktor der
Multiplikation konstant ist und berechnet wird der Offsetwert einfach
mit derselben Multiplikation, mit der auch die die Samples skaliert
werden.
.equ M=$80
.def R16=F
.def R17=O
.def R1=S
Also, einmal nach Änderung der Lautstärke und damit des Faktors F zu
berechnen der Offsetwert O aus dem Soll-Mittelwert M:
O = M - M * F
ldi O,M
mul F,O
sub O,R1
und dann für jedes einzelne Sample aus der Waveform im Flash, auf deren
Anfang Z initialisiert wird:
S = S * F + O
calcsam:
lpm S,Z+
mul S,F
add S,O
out DACPORT,S
Fertsch.