Bei meinen Versuchen, bin ich auf eine Merkwürdigkeit gestoßen.
In der Regel werden im Hauptprogramm die Doppelpuffer zur Sound-Ausgabe
gefüllt und mittels ISR (Overflow oder Compare Match) an OC...
übergeben. So weit so gut. Klappt einwandfrei. Hacken ist hierbei, keine
anderen Aktionen im Hauptprogramm können durchgeführt werden, bis die
Datei komplett abgespielt ist.
Aus diesem Grund habe ich sowohl das Einlesen als auch die Ausgabe in
die ISR-Routine gelegt. Eine Ausgabe findet auch statt, aber eine Art
Vibrator überlagert die Ausgabe. Ähnlich, wie hier beschreiben:
Beitrag "Sprachausgabe mit AVR"
Egal ob ich zwei Overflow vom Timer1 und/oder Timer2 oder zwei Compare
Match vom Timer1 und/oder Timer2 nehme, ich bekomme immer diesen
Vibrator-Effekt. Dieser Effekt hält solange an, wie die Timer für PWM
und CTC an sind. Unabhängig davon, wann ich die Datei schließe.
Unabhängig davon, ob der Puffertausch innerhalb der Ausgabe-ISR oder
beim Einlese-ISR liegt.
Weiß jemand Rat??
Hier mal beispielhafter Code:
1 | #define PLAY_BUFFER_SIZE 256
|
2 |
|
3 | uint8_t* playBuffer = BufferA;
|
4 | uint8_t* readBuffer = BufferB;
|
5 |
|
6 | uint16_t actByte;
|
7 | uint8_t bufferChanged;
|
8 |
|
9 |
|
10 | ISR(TIMER1_COMPA_vect)
|
11 | {
|
12 | OCR0A = playBuffer[actByte++];
|
13 | }
|
14 |
|
15 | ISR(TIMER0_COMPB_vect)
|
16 | {
|
17 | if( actByte == PLAY_BUFFER_SIZE ) {
|
18 |
|
19 | uint8_t* tmp = playBuffer;
|
20 | playBuffer = readBuffer;
|
21 | readBuffer = tmp;
|
22 | actByte = 0;
|
23 | Fread(readBuffer,PLAY_BUFFER_SIZE);
|
24 | }
|
25 | }
|