Forum: Mikrocontroller und Digitale Elektronik Audiowiedergabe Mehrkanal mit Tiny1614


von CATCO (Gast)


Lesenswert?

Hallo,

ich habe eine kurze Frage. Ich gebe Sounddateien die im Flash des 
Tiny1614 sind wieder über den DAC und danach ist ein PAM. Ein Problem 
habe ich wenn ich mehrere Kanaäle gleichzeitig wieder geben will, 
grundsätzlich geht das, aber die der Sound des einzelnen Geräusch ist um 
50% in der Lautstärke reduziert. Wie macht man das, dass ich 2 Sounds 
wiedergebe und die Ihre ursprüngliche Lautstärke behalten?

Momentan nehme ich die 2-3 (mehr als 3 kanäle sind es nicht 
gleichzeitig) addiere die auf und teile die dann durch die Summe der 
addierten Kanäle, also MIttelwert quasi.

von CATCO (Gast)


Lesenswert?

Keiner eine Ahnung!?

von K. S. (the_yrr)


Lesenswert?

CATCO schrieb:
> Keiner eine Ahnung!?

könnte daran liegen dass dein "Text" völlig unverständlich ist.

> und teile die dann durch die Summe der
> addierten Kanäle, also MIttelwert quasi.
du meinst durch die Anzanhl? Was sind deine Werte, Int, Float, Fixed 
Point? Welchen Wertebereich haben die Daten, welcher passt in die Zahl 
rein?

Wie wäre es mit deinem Code(ausschnitt), das hört sich nach 
Programmierfehler an.

Wenn du in Zukunft Antworten willst, versuche dich strukturierter 
Auszudrücken und alles wichtige im Ausgangspost zu erwähnen, hier z.b. 
den Code.

von CATCO (Gast)


Lesenswert?

K. S. schrieb:
> CATCO schrieb:
>> Keiner eine Ahnung!?
>
> könnte daran liegen dass dein "Text" völlig unverständlich ist.
>
>> und teile die dann durch die Summe der
>> addierten Kanäle, also MIttelwert quasi.
> du meinst durch die Anzanhl? Was sind deine Werte, Int, Float, Fixed
> Point? Welchen Wertebereich haben die Daten, welcher passt in die Zahl
> rein?
>
> Wie wäre es mit deinem Code(ausschnitt), das hört sich nach
> Programmierfehler an.
>
> Wenn du in Zukunft Antworten willst, versuche dich strukturierter
> Auszudrücken und alles wichtige im Ausgangspost zu erwähnen, hier z.b.
> den Code.

Tschuldigung!

Datentyp is uint8_t (also 8 Bit unsigned),

Ansonsten wie ich gesagt habe.

DAC = Soundsample1;


DAC = ((Soundsample1 + Soundsample2) / 2)

oder

DAC = ((Soundsample1 + Soundsample2 + Soundsample3) / 3);


Dabei ist mir noch aufgefallen, das hohe Töne, (hörbar) nicht verändert 
werden, aber tiefere Töne werden leiser. Wo liegt das Problem?

von mIstA (Gast)


Lesenswert?

CATCO schrieb:
> wenn ich mehrere Kanaäle gleichzeitig wieder geben will,
> grundsätzlich geht das, aber die der Sound des einzelnen Geräusch ist um
> 50% in der Lautstärke reduziert.

Na ist doch logisch, wenn ein Lautsprecher gleichzeitig 2 Geräusche 
wiedergeben soll, daß dann für jedes einzelne Geräusch nur die halbe 
Lautstärke überbleibt; sonst könntest Du ja die Lautstärke (und damit 
die Leistung des Lautsprechers) einfach verdoppeln oder sogar 
vervielfachen, indem Du zwei bzw. mehrere identische Geräusche 
gleichzeitig abspielst.

CATCO schrieb:
> Wie macht man das, dass ich 2 Sounds
> wiedergebe und die Ihre ursprüngliche Lautstärke behalten?

Einfach auch schon beim Abspielen eines einzelnen Geräuschs die 
Lautstärke halbieren bzw. - wenn auch mal drei Geräusche gleichzeitig 
tönen sollen - dritteln.

von CATCO (Gast)


Lesenswert?

mIstA schrieb:
> CATCO schrieb:
>> wenn ich mehrere Kanaäle gleichzeitig wieder geben will,
>> grundsätzlich geht das, aber die der Sound des einzelnen Geräusch ist um
>> 50% in der Lautstärke reduziert.
>
> Na ist doch logisch, wenn ein Lautsprecher gleichzeitig 2 Geräusche
> wiedergeben soll, daß dann für jedes einzelne Geräusch nur die halbe
> Lautstärke überbleibt; sonst könntest Du ja die Lautstärke (und damit
> die Leistung des Lautsprechers) einfach verdoppeln oder sogar
> vervielfachen, indem Du zwei bzw. mehrere identische Geräusche
> gleichzeitig abspielst.
>
> CATCO schrieb:
>> Wie macht man das, dass ich 2 Sounds
>> wiedergebe und die Ihre ursprüngliche Lautstärke behalten?
>
> Einfach auch schon beim Abspielen eines einzelnen Geräuschs die
> Lautstärke halbieren bzw. - wenn auch mal drei Geräusche gleichzeitig
> tönen sollen - dritteln.


Das passiert aber völlig dynmaisch und unerwartet. Wie machen das denn 
die anderen Soundmodulhersteller für MOdellbahnen? Da ist der Sound auch 
laut und man kann bis zu 6 Geräusche gleichzeitig abspielen die gleich 
laut bleiben. Das muss also noch irgendwie anders gehen

von Mittelwert? (Gast)


Lesenswert?

>addiere die auf und teile die dann durch die Summe der
>addierten Kanäle, also MIttelwert quasi.

Stell Dir mal vor 3 Geräusche.
Das erste hat normalen Pegel z.B. Dampfpfeife.
Das zweite hat grad eine Stille  z.B. Luftpumpe.
Das dritte hat auch grad Stille z.B. Kohlenschaufeln.

Was macht Deine Software daraus?

1/3 Dampfpfeife.

Kann ja wohl nicht in Deinem Sinne sein? Und doch machst Du es.
Peng.

von CATCO (Gast)


Lesenswert?

Mittelwert? schrieb:
>>addiere die auf und teile die dann durch die Summe der
>>addierten Kanäle, also MIttelwert quasi.
>
> Stell Dir mal vor 3 Geräusche.
> Das erste hat normalen Pegel z.B. Dampfpfeife.
> Das zweite hat grad eine Stille  z.B. Luftpumpe.
> Das dritte hat auch grad Stille z.B. Kohlenschaufeln.
>
> Was macht Deine Software daraus?
>
> 1/3 Dampfpfeife.
>
> Kann ja wohl nicht in Deinem Sinne sein? Und doch machst Du es.
> Peng.

Ich mache das aktuell nicht so. Das stimmt nicht.

Ich spiele immer den Sound ab (bspw. Fahrgeräusch). Der kommt 100% 
durch.
Jetzt drücke ich an der digitalen Steuerung F1, dann wird die Pfeiffe 
abgespielt. Meine Software macht jetzt erst die Addition der 
Pfeiffen-Samples auf das Fahrgeräusch und teilt es durch 2. Wenn eine 
Stille dort wäre, würde keine Teilung erfolgen (bspw. Glocke), das habe 
ich schon berücksichtigt. Bei der hört man es am schlimmsten. Beim 
Glockenschlag ist das Fahrgeräusch 50% leiser, bei der Glockenpause dann 
wieder 100% laut. Wie machen das die anderen Hersteller?! Ich verstehe 
das nicht

von c-hater (Gast)


Lesenswert?

CATCO schrieb:

> mIstA schrieb:
>> Einfach auch schon beim Abspielen eines einzelnen Geräuschs die
>> Lautstärke halbieren bzw. - wenn auch mal drei Geräusche gleichzeitig
>> tönen sollen - dritteln.
>
>
> Das passiert aber völlig dynmaisch und unerwartet. Wie machen das denn
> die anderen Soundmodulhersteller für MOdellbahnen?

Na genau so, wie Mista schrieb. Dein Problem ist eigentlich nur, dass du 
nicht begriffen hast, was er schrieb.

> Das muss also noch irgendwie anders gehen

Nein, geht es nicht. Die sinnvolle (und deshalb auch übliche) Lösung 
ist: Du legst vorab fest, wieviele Kanäle maximal gleichzeitig 
abgespielt werden sollen. Dann schreibst du den entsprechenden Code für 
diese Maximalzahl und benutzt immer diesen, unabhängig davon, wieviele 
Kanäle aktuell tatsächlich abgespielt werden. Aktuell nicht 
abzuspielende Kanäle werden dann mit Nullsamples gefüttert. Das ist 
alles.
Aus Perfomancegründen sollte die Maximalzahl übrigens eine Zweierpotenz 
sein. Sonst wird es auf MCUs ohne Hardwaredivision u.U. knapp mit der 
Rechenzeit, weil wirklich dividiert werden muss.

Achso: dein Code war übrigens auch noch falsch, sogar gleich doppelt.
1) Du produzierst Überläufe
2) Du skalierst den DC-Anteil der unsigned Samples mit

Korrekt wäre etwa sowas (für maximal zwei Kanäle):

#define ZEROSAMPLE 127

uint8_t mix_samples(uint8_t Sample1, uint8_t Sample2)
{
  int ts1 = (int)Sample1 - ZEROSAMPLE;
  int ts2 = (int)Sample2 - ZEROSAMPLE;
  return (uint8_t)((ts1 + ts2) / 2 + ZEROSAMPLE);
}

Und das rufst du dann halt für zwei abzuspielende Känäle so auf:

DAC = mix_samples(Sample1, Sample2);

oder für einen Kanal so:

DAC = mix_samples(Sample1, (uint8_t)ZEROSAMPLE);

von Horst (Gast)


Lesenswert?

CATCO schrieb:
> Wie machen das die anderen Hersteller?!

Nimm die maximale Anzahl der Geräusche, die gleichzeitig abgespielt 
werden können und teil alle Pegel durch diese Zahl.
Jetzt kannst Du beliebig addieren und jedes Geräusch hält seine 
Lautstärke.

von CATCO (Gast)


Lesenswert?

c-hater schrieb:
> CATCO schrieb:
>> Das muss also noch irgendwie anders gehen
: dein Code war übrigens auch noch falsch, sogar gleich doppelt.
> 1) Du produzierst Überläufe
> 2) Du skalierst den DC-Anteil der unsigned Samples mit
>
> Korrekt wäre etwa sowas (für maximal zwei Kanäle):
>
> #define ZEROSAMPLE 127
>
> uint8_t mix_samples(uint8_t Sample1, uint8_t Sample2)
> {
>   int ts1 = (int)Sample1 - ZEROSAMPLE;
>   int ts2 = (int)Sample2 - ZEROSAMPLE;
>   return (uint8_t)((ts1 + ts2) / 2 + ZEROSAMPLE);
> }
>
> Und das rufst du dann halt für zwei abzuspielende Känäle so auf:
>
> DAC = mix_samples(Sample1, Sample2);
>
> oder für einen Kanal so:
>
> DAC = mix_samples(Sample1, (uint8_t)ZEROSAMPLE);

1. Nein, ich produziere keine Überläufe, da (uint16_t) als Cast davor
2. Das stimmt, ich hatte als ZEROSAMPLE allerdings die 128 genommen!? 
256/2 = 128. 0-255 => 256 Schritte. So meine Idee.

Deinen Code kann ich nicht ganz nachvollziehen. Ich bekomme bei vielen 
Werten ein negatives Ergebnis, da die Samples < 128 liegen. Die würden 
sich ja dann aufheben.

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.