Forum: Mikrocontroller und Digitale Elektronik Lautstärke der PCM Datei ändern


von Nils (Gast)


Lesenswert?

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

von foo (Gast)


Lesenswert?

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?

von Nils (Gast)


Lesenswert?

>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?

von foo (Gast)


Lesenswert?

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.

von Rolf M. (rmagnus)


Lesenswert?

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?

von c-hater (Gast)


Lesenswert?

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.

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.