Forum: PC-Programmierung Wie addiert man digitale Audiosignale?


von Gerd_B (Gast)


Lesenswert?

Hallo,

ich beschäftige mich grade mit der Frage, wie man digitale Audiosignale 
addiert.

Der Anschaulichkeit halber mögen folgende Bedingungen gelten:

Zwei Audiosignale sind mit diesen Parametern digitalisiert worden:
-Samplingrate 12kHz/s
-Auflösung 8 Bit
-Samplelänge 1 sec.
-Mono

Jetzt möchte man diese Signale digital addieren.
Also rechnet man von Signal1 den n-ten Sample plus den n-ten Sample von 
Signal2 für n von 0 bis 11.999

So weit, so gut.
Probleme entstehen erst, wenn die Addition der beiden Werte größer als 
255 wird (Auflösung war ja 8Bit), dann kann die Summe nicht mehr mit 
einem Byte dargestellt werden.

Also darf jedes der beiden Signale für Vollaussteuerung nur Werte bis 
127 enthalten, damit keine Übersteuerung eintritt (Werte größer 255 sind 
ja bei 8Bit nicht möglich).
D.h. im Klartext, damit zwei digitale Audiosignale problemlos gemischt 
werden können, dürfen sie jeweils nur die Hälfte des maximalen 
Aussteuerbereichs benutzen.
Bei vier Audiosignalen wären es nur noch 1/4 der maximal möglichen 
Aussteuerung für ein Einzelsignal.

Ist das so korrekt?

von Peter (Gast)


Lesenswert?

da du ja auch nicht willst das es am ende "lauter" ist, warum nicht 
(a+b/2) rechnen?

von Gerd_B (Gast)


Lesenswert?

Peter schrieb:
> da du ja auch nicht willst das es am ende "lauter" ist, warum nicht
> (a+b/2) rechnen?

Interessante Idee!

Dann müßte man intermediär mit zwei Bytes rechnen, aber nach der 
Division käme man wieder mit einem Byte aus.

So wie ich das sehe, macht es fast keinen Unterschied, ob man die 
Amplituden vorher oder nachher halbiert. Wobei die zweite Variante 
wahrscheinlich weniger "Rundungsfehler" enthält.

von B e r n d W. (smiley46)


Lesenswert?

Müßte das dann nicht (a+b)/2 heißen?

von Gerd_B (Gast)


Lesenswert?

B e r n d W. schrieb:
> Müßte das dann nicht (a+b)/2 heißen?
richtig! so muß es geschrieben werden. man sieht zwar trotzdem, was 
peter meint, wenn man den beitrag liest. aber danke für den hinweis!!!

von NurEinGast (Gast)


Lesenswert?

(a+b)/2  ist mir auch als Erstes eingefallen als ich den Thread las.
Aber das bedeutet auch, wenn nur a oder b "aktiv" ist, dann kommt nur 
noch a/2 bzw. b/2 an.

Keine Ahnung um welche Audiosignale es hier geht, also ob aus a und b 
immer ein Signal ankommt. Wenn nicht könnte man auch über eine Art 
gleitenden Faktor für jedes Signal nachdenken.

von Peter (Gast)


Lesenswert?

wie wird es dann analog gemacht wenn man 2 signale addiert? Ich denke 
mal dabei wird es einfach einen "Anschlag" bei der maximalen spannung 
geben. Somit müsste die digitale Version auch a + b machen und bei >255 
auf 255 setzen.
Sollte man das ganze nicht als -127 bis +127 beachten? Damit müsste man 
dann auch noch die untere Schranke definieren a+b<0 = 0.

von HildeK (Gast)


Lesenswert?

Gerd_B schrieb:
> Ist das so korrekt?

Ja und nein.
Ja - wenn du immer in der 8-Bit-Welt bleiben willst/musst.
Nein, denn für Operationen innerhalb eines Gerätes wird man intern die 
Wortbreite erhöhen, um Spielraum für diese Operationen zu haben. Wenn du 
das Ergebniss wieder auf 8 Bit darstellen willst/musst, dann muss 
anschließend geteilt werden.

Das ist digital nicht anders wie analog. Normalerweise wird weder 
digital noch analog das Signal bis an die Aussteuergrenze ausgereizt. 
Speziell bei Audiosignalen sind relative hohe Impuls möglich, die nicht 
mal laut erscheinen müssen - weil sie z.B. sehr kurz sind - dafür brauch 
man Reserve.
Auch analog hast du das Problem, zwei vollausgesteuerte Signal zu 
addieren: das ergibt zwingend eine Übersteuerung.
Deshalb gibt es bei analogen Einrichtungen hohe Anforderung an den 
Rauschabstand der einzelnen Stufen, bei digitalen wird man eine 
entsprechend hohe Wortbreite wählen, so dass man ohne (merkliche) 
Beeinträchtigung mit der vorzuhaltenden Aussteurungsreserve noch gute 
Signale erhält.

Und spätestens am Ende der Kette steht ein Pegelregler.

von Gerd_B (Gast)


Lesenswert?

NurEinGast schrieb:
> (a+b)/2  ist mir auch als Erstes eingefallen als ich den Thread las.
> Aber das bedeutet auch, wenn nur a oder b "aktiv" ist, dann kommt nur
> noch a/2 bzw. b/2 an.

das macht ja nicht unbedingt was aus, weil zum schluß noch mal eine 
analoge verstärkung um den faktor 2 möglich wäre. allerdings bleibt das 
problem maximaler aussteuerbarkeit spätestens beim endverstärker 
bestehen.

von Gerd_B (Gast)


Lesenswert?

Peter schrieb:
> wie wird es dann analog gemacht wenn man 2 signale addiert? Ich denke
> mal dabei wird es einfach einen "Anschlag" bei der maximalen spannung
> geben. Somit müsste die digitale Version auch a + b machen und bei >255
> auf 255 setzen.
das gibt aber übersteuerung! man darf deshalb gemischt gar nicht erst 
über die 255 hinaus!

> Sollte man das ganze nicht als -127 bis +127 beachten? Damit müsste man
> dann auch noch die untere Schranke definieren a+b<0 = 0.
praktisch ja, d.h., beim wav-format liegt die null beim digitalen wert 
127 (8bit), so weit ich weiß.
für die theoretische betrachtung hier spielt das aber erst mal keine 
rolle, mir geht es nur um das additionsprinzip.

von Mano W. (Firma: ---) (manow)


Lesenswert?

Fließ- bzw. Festpunktkommazahlen eignen sich besser für 
Audiooperationen. Am Ende der Bearbeitungskette wird das Ergebnis mit 
einem Faktor, der Verstärkung, multipliziert.
1
float amp = 0.75;
2
3
float a = einlesen8BitA() / 255.0;
4
float b = einlesen8BitB() / 255.0;
5
6
float val = a + b;
7
val = val * amp;
8
9
ausgabe(val);

Wenn val größer als 1.0 ist, dann ist das Signal zu laut und wird 
verzerrt. Die Spitzen werden dann abgeschnitten.

von Gerd_B (Gast)


Lesenswert?

HildeK schrieb:
> Auch analog hast du das Problem, zwei vollausgesteuerte Signal zu
> addieren: das ergibt zwingend eine Übersteuerung.
> Deshalb gibt es bei analogen Einrichtungen hohe Anforderung an den
> Rauschabstand der einzelnen Stufen, bei digitalen wird man eine
> entsprechend hohe Wortbreite wählen, so dass man ohne (merkliche)
> Beeinträchtigung mit der vorzuhaltenden Aussteurungsreserve noch gute
> Signale erhält.

dann ist ein analoges 16-kanalmischpult ein wunderwerk der technik und 
des rauschabstandes!?!

von HildeK (Gast)


Lesenswert?

Gerd_B schrieb:
> dann ist ein analoges 16-kanalmischpult ein wunderwerk der technik und
> des rauschabstandes!?!

Schön wäre es.
Tatsächlich wird man auch dort immer wieder zwischendurch Pegel 
zurücknehmen müssen - auf Kosten des Rauschabstandes. Wenn du 16 Signale 
addierst, dann wird nun mal die Amplitude größer als wenn nur eines 
verarbeitet werden muss - dies kann dann entsprechend höher ausgesteuert 
werden und die in den Stufen dazukommenden Rauschanteile sind anteilig 
geringer.
Beim digitalen Addieren muss man immer wieder teilen (wenn man nicht die 
Wortbreite erhöht) und erhält damit zusätzliche Rauschanteile. Eine 
PC-Software für Audiobearbeitung arbeitet deshalb intern mit 
Float-Darstellung oder zumindest mit 32Bit Integer bei 16Bit Signalen, 
um die Verluste in Grenzen zu halten.

von (prx) A. K. (prx)


Lesenswert?

Es ist bei DSP-Arithmetik nicht unüblich, dass ein Zwischenergebnis in 
einer Kette von Operationen mehr Stellen hat als Operanden und 
abschliessendes Resultat. Addition und Skalierung (/2) sind so 
problemlos.

NB: Bei dafür vorgesehenen Prozessoren bzw. Befehlssätzen findet sich 
häufig auch saturierende Rechnung, bei saturierender vorzeichenloser 
8-Bit Rechnung gilt 200+201=255. Das ist in dieser Frage zwar nicht 
angebracht, vermeidet aber immerhin Artefakte durch die sonst übliche 
Modulo-Rechnung.

von André H. (dk2oaf)


Lesenswert?

Hallo,
auch wenn dieser Thread ziemlich alt ist, möchte ich den Beitrag noch 
ergänzen.

Und zwar wird in der Profibereich sich umschaut, geschrieben, das einmal 
paar Bit's als Überstuerungsreserve dazu gegeben werden. zusätzlich wird 
gesagt, das Pro Kanalzug, der zu mischen ist 1 Bit an das Summensignal 
angefügt wird. D.h 10 Kanäle = 10 zusätzliche Bit's, wenn es vollständig 
Digital verarbeitet werden soll.

Besser ist es, das Digitale Siganl in Anaolg zu wandeln, Abmischen und 
weitere Bearbeitung und dann das Mischprodukt wieder Digitaliesieren.
Somit werden auch Phasenfehler vermieden.

von Georg A. (georga)


Lesenswert?

> das Pro Kanalzug, der zu mischen ist 1 Bit an das Summensignal
> angefügt wird. D.h 10 Kanäle = 10 zusätzliche Bit's, wenn es vollständig
> Digital verarbeitet werden soll.

Das macht irgendwie keinen Sinn... Bei 8 Bit signed wäre der Maximalwert 
10*-128=-1280, d.h. man kommt mit 12Bit signed (-2048...2047) gut aus, 
also 8+ceil(log2(10)).

von Rolf M. (rmagnus)


Lesenswert?

André H. schrieb:
> zusätzlich wird gesagt, das Pro Kanalzug, der zu mischen ist 1 Bit an das
> Summensignal angefügt wird.

Ein Bit pro Verdoppelung der Kanalzahl wäre ausreichend. Bei 16 Kanälen 
also z.B. 4 zusätzliche Bits.

von uwe (Gast)


Lesenswert?

Naja man hat in einer "normalen" CPU auch ein Carry Flag.
r16=200
r17=200
add r16,r17
ror r16
clc

von c-hater (Gast)


Lesenswert?

HildeK schrieb:

> Ja und nein.
> Ja - wenn du immer in der 8-Bit-Welt bleiben willst/musst.

Nein. Man muss einfach nur die richtige Sprache verwenden, dann geht 
sowas auch in der gegebenen Datenwortbreite. Weil in einer richtigen 
Sprache die CPU-Flags verfügbar sind und von kompetenten Programmierern 
auch sinnvoll gebraucht werden können.

Beispiel: Mittelwertbildung von zwei "unsigned" 8-Bit-Samples auf einem 
AVR8:

 add reg0,reg1
 ror reg0

Zwei Takte und das Äquivalent von C'isch (a+b)/2 ist schon fertig...

von c-hater (Gast)


Lesenswert?

c-hater schrieb:

> Nein. Man muss einfach nur die richtige Sprache verwenden...

Verdammt, man sollte bis ganz unten durchscrollen, bevor man antwortet. 
Schon 14:16 kam der Hinweis auf die Lösung.

von J. S. (engineer) Benutzerseite


Lesenswert?

Mano W. schrieb:
> Fließ- bzw. Festpunktkommazahlen eignen sich besser für
> Audiooperationen.
Wieso? Audio ist nur EINE Form von Signalverarbeitung und ob sich eine 
bestimte Art der Berechung einfacher oder besser darstellt, hat doch 
nichts mit dem Kontext zu tun, sondern einfach damit, auf welcher 
Plattform man arbeitet. In DSPs mag es einfacher sein, FP zu benutzen, 
weil es einen CO-Pro gibt. Dennoch arbeiten viele Audiosysteme mit 
festen Integerwertbreiten.

Zudem ist die Fragestellung damit noch nicht wirklich angegangen:

André H. schrieb:
> auch wenn dieser Thread ziemlich alt ist, möchte ich den Beitrag noch
Das Thema ist noch älter, als der Thread und zwar ungefähr 10x so alt!

Selbstredend ist es so, daß sich die Amplituden erhöhen, wenn sich 
Signale mischen (= addieren!), sonst würde es auch nicht lauter werden 
;-) - das hat weder was mit Analog noch Digital zu tun. In beiden Fällen 
gibt es damit das Problem der Übersteuerung und um die zu vermeiden, 
brauche ich an jeder Stelle einen ausreichenden headroom!

Das gilt für das Eingangssignal, das in der Regel NICHT die volle 
mögliche Bitbreite belegt und auch das Ausgangssignal

> D.h 10 Kanäle = 10 zusätzliche Bit's, wenn es vollständig
> Digital verarbeitet werden soll.
Da müssen wir nochmal nachdenken:

Wenn man z.B. 16 Kanäle addiert, kommt als maximales Ergebnis die 
16fache Vollausteuerung raus. Das sind bei mir dann "nur" 4 Bit mehr!

> Besser ist es, das Digitale Signal in Analog zu wandeln, Abzumischen
> und die weitere Bearbeitung und dann das Mischprodukt wieder
> Digitalisieren.
Abgesehen von der Rechtschreibung, die ich mir im Zitat erlaubt habe, zu 
korrigieren D: sind da zwei Fehler drin: 1. Es gibt hier keine 
"Mischprodukte". Die gibt es beim Mischen in Form der Multiplikation, 
die aber beim Audio nur beim Vibrato auftritt und somit auch kein 
Problem aufwirft, da die beiden Frequenzen weit auseinander liegen. 
Vibrato liegt im Bereich von 5Hz abwärts.

> Somit werden auch Phasenfehler vermieden.
... 2. sind Phasenfehler kein Problem digitialer Mischungen und ich 
wüsste auch nicht, wo die hier aufträte, sodaß sie zu vermeiden wäre. 
Eher schon bringen zusätzliche Wandlungsschritt Latenzen und damit 
Probleme, mehre Quellen und Pfade sychron zu halten, die nur teilweise 
durch einen DSP laufen und teilweise noch durch einen Analogkette 
sollen.

Um das Thema mal zu konkretisieren:

Ein AD-Wandlersignal, wird man bei Einzelstimmen so bemessen, dass der 
Normalpegel von 80dBspl vielleicht bei einer Aussteuerung von maximal 18 
Bit von 24 liegt, was knapp 110dBfs sind. Damit hat man für Piano von 
volle 16 Bit und die hohen Resonanztöne bei z.B. dem Sopran noch 
ausreichend headroom. So gewonnenen Signal kann man schon unbearbeitet 
direkt mischen, ohne an Übersteuerungsgrenzen zu gelangen oder Auflösung 
zu verlieren. Der peak liegt bei einer solchen Einzelstimme dann bei 
vielleicht 110 dBspl und z.B. bei 135dBfs.

Nach dem Mischen mit 16 solcher Stimmen bekommt man z.B. einen 
Mittelpegel von 95dB-100dB (also nicht etwa das 16-fache von fast 
110dB). Diese 100dB sind locker ausreichend, um sie auf die 96dBfs einer 
Audio-CD zu quetschen.

Bei Mehrfachstimmen, also einem Chor kann (und muss!) man sofort mit der 
ersten Aufnahme, die 24 Bit gut treffen, z.B. lautes Einsingen das 23. 
bit ankratzen, weil sonst die Pianissiopassagen zu leise werden, um die 
16 Bit auszulasten,

Bei Klangsynthese ist es wiederum viel einfacher:

Ein sauberer Sinus braucht gerade 12bit "echte Güte", weil er mit 100 
anderen Stimmen zusammengemischt wird und damit sehr rasch die full 
scale 16 Bit einer CD erreicht werden. Daher arbeiten viele ROM-Systeme 
nach wie vor mit 16 Bit Samples an Audiomaterial und könnten trotzdem 24 
Bit Qualität erzielen, z.B. bei Orchestersamples.

von Johann Klammer (Gast)


Lesenswert?

Wenn sie n signale addieren, empfiehlt es sich einen akkumulations 
buffer zu verwenden, der den overflow aufnehmen kann 8->32 bit int. die 
addition sollte mit vorzeichenbehafteten integern erfolgen. also, wenn 
die quelle in
8 bit unsigned samples vorliegt:
(sample buffer s zuerst auf 0 setzen. i ist sample index.)
1
int i;
2
int s;
3
uint8_t input;
4
s[i]+=(((int)input)&0x0ff)-(0x080);
danach wollen sie typ. das Ergebnis wieder in 8 bit quetschen.
division durch n daempft das ganze meistens zu stark.
Wenn Sie aber annehmen, dass die samples unkorrelliert sind,
koennen sie RMS abschwaechen.
1
faktor=16/sqrt(n);
2
s[i]=(s[i]*faktor)/16;
Danach noch saturieren.
1
s[i]=(s[i]>127)?127:s[i];
2
s[i]=(s[i]<-128)?-128:s[i];
...und evtl noch offset fuer unsigned..

von Jens U. (Gast)


Lesenswert?

Johann Klammer schrieb:
> Danach noch saturieren.
> s[i]=(s[i]>127)?127:s[i];
> s[i]=(s[i]<-128)?-128:s[i];

Das macht aber einen Cliping-Fehler!

Beitrag #6310018 wurde von einem Moderator gelöscht.
von Mathias A. (mrdelphi)


Lesenswert?

c-hater schrieb:
> HildeK schrieb:
>
>> Ja und nein.
>> Ja - wenn du immer in der 8-Bit-Welt bleiben willst/musst.
>
> Nein.

Doch. S.u.


> Man muss einfach nur die richtige Sprache verwenden, dann geht
> sowas auch in der gegebenen Datenwortbreite. Weil in einer richtigen
> Sprache die CPU-Flags verfügbar sind und von kompetenten Programmierern
> auch sinnvoll gebraucht werden können.

Nun die Preisfragen:

1. Welches CPU-Flag kommt hier zum Tragen?

Hint: das Carry-Flag

2. Was macht das Carry-Flag?

Hint: es speichert den Übertrag der Addition.

3. Wie macht es das?

Hint: Der Übertrag ist ein Bit. Das Carry-Flag speichert ein Bit. 
Überraschung: es ist hier also das neunte Bit!


> Beispiel: Mittelwertbildung von zwei "unsigned" 8-Bit-Samples auf einem
> AVR8:
>
>  add reg0,reg1
>  ror reg0
>
> Zwei Takte und das Äquivalent von C'isch (a+b)/2 ist schon fertig...

Es ist davon auszugehen, dass dieser Term in C zu genau jenem 
Assemblercode führt...

von Ex-Boygroupmember (Gast)


Lesenswert?

Addierender Subtrahierer schrieb im Beitrag #6310018:
> Dieses Problem wurde bereits in den 70er Jahren von Hildegard Knef
> gelöst:

LOL

von J. S. (engineer) Benutzerseite


Lesenswert?

Mathias A. schrieb:
> Hint: Der Übertrag ist ein Bit. Das Carry-Flag speichert ein Bit.
> Überraschung: es ist hier also das neunte Bit!

Es bleibt aber immer das Problem, dass zwei Signale insgesamt die 
doppelte Amplitude liefern können und damit die Auflösung, die ja hier 8 
Bit sein soll, beschränkt ist. Also geht Dynamik dahin.

von Mathias A. (mrdelphi)


Lesenswert?

Jürgen S. schrieb:
> Mathias A. schrieb:
>> Hint: Der Übertrag ist ein Bit. Das Carry-Flag speichert ein Bit.
>> Überraschung: es ist hier also das neunte Bit!
>
> Es bleibt aber immer das Problem, dass zwei Signale insgesamt die
> doppelte Amplitude liefern können und damit die Auflösung, die ja hier 8
> Bit sein soll, beschränkt ist. Also geht Dynamik dahin.

Das stimmt. Meine Antwort bezog sich auf das Posting von c-hater, der 
meinte dass man mit Assembler den Mittelwert zweier 8-Bit-Werte 
berechnen, und dabei innerhalb 8 Bit bleiben könne. Das stimmt so eben 
nicht, da durch das Carry ein neuntes Bit dazukommt. Bzw es ist in C 
genauso, auch da kommt in dem Fall das neunte Bit dazu, ohne dass man 
Datentypen mit mehr als 8 Bit verwenden müsste.

von Rolf M. (rmagnus)


Lesenswert?

Mathias A. schrieb:
> Das stimmt. Meine Antwort bezog sich auf das Posting von c-hater,

…das er vor 3 Jahren verfasst hat…

> der meinte dass man mit Assembler den Mittelwert zweier 8-Bit-Werte
> berechnen, und dabei innerhalb 8 Bit bleiben könne. Das stimmt so eben
> nicht, da durch das Carry ein neuntes Bit dazukommt.

Er hat eigentlich nirgends behauptet, dass seine Berechnung das 
Carry-Flag nicht benutzt.

> Bzw es ist in C genauso, auch da kommt in dem Fall das neunte Bit dazu, ohne
> dass man Datentypen mit mehr als 8 Bit verwenden müsste.

Wie soll das denn funktionieren?

von Jens U. (Gast)


Lesenswert?

Rolf M. schrieb:
>> Bzw es ist in C genauso, auch da kommt in dem Fall das neunte Bit dazu, ohne
>> dass man Datentypen mit mehr als 8 Bit verwenden müsste.
>
> Wie soll das denn funktionieren?

Impliziter Überlauf? Dass es rechenmäßig klappt, heißt aber noch nicht, 
dass die daraus erzeugte Signalstruktur später auch klappt.

Und das Limitieren, wie oben gezeigt, macht einen Clip-Fehler:
Jens U. schrieb:
> Das macht aber einen Cliping-Fehler!

Geht also so oder so nicht.

von Thomas Z. (usbman)


Lesenswert?

Beim Mischen sorgt man In der Regel für einen Headroom von 6db dann 
passt das auch nach der Addition ob nun 8bit oder mehr. 6db ist halber 
Pegel somit passt das Ergebnis wieder zur Bitbreite ganz ohne Clipping.

von Rolf M. (rmagnus)


Lesenswert?

Jens U. schrieb:
> Rolf M. schrieb:
>>> Bzw es ist in C genauso, auch da kommt in dem Fall das neunte Bit dazu, ohne
>>> dass man Datentypen mit mehr als 8 Bit verwenden müsste.
>>
>> Wie soll das denn funktionieren?
>
> Impliziter Überlauf?

Was meinst du damit?
Abgesehen davon werden in C alle Berechnungen automatisch mindestens mit 
int durchgeführt. Man kann also gar nicht verhindern, dass ein Datentyp 
mit mehr als 8 Bit verwendet wird.

Thomas Z. schrieb:
> Beim Mischen sorgt man In der Regel für einen Headroom von 6db dann
> passt das auch nach der Addition ob nun 8bit oder mehr. 6db ist halber
> Pegel somit passt das Ergebnis wieder zur Bitbreite ganz ohne Clipping.

Allerdings nur dann, wenn du dich darauf beschränkst, nur genau zwei 
Signale zusammenzumischen.
Am Ende ist es aber auch eigentlich egal, ob du das Bit schon von vorne 
herein ungenutzt lässt, indem du 6 dB Headroom lässt oder ob du vor der 
Addition das Bit entfernst durch Division durch 2.

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.