ESP8266 - Musikstück um die ersten 16 Einheiten verkürzt / Kampf mit dem timer1

Hallöle!

Mit eurer Unterstützung habe ich jetzt den ESP8266 endgültig dazu überreden können, Musik auszuspucken. Sogar mit primitiven Drums und sovielen OSCs, wie ich es gerade brauche. Ein Problem gibt es doch noch: Ich habe jetzt einen ganz gut gelungenen Remix des Song 3 aus dem Amiga-Spiel “Super Cars” auf den ESP gezogen. Das Programm:

#define soundPin 5

#define  octave  12

#define  o1      1
#define  o2      1 + octave
#define  o3      1 + (octave * 2)
#define  o4      1 + (octave * 3)
#define  o5      1 + (octave * 4)
  
#define  C       0
#define  Cis     1
#define  D       2
#define  Dis     3
#define  E       4
#define  F       5
#define  Fis     6
#define  G       7
#define  Gis     8
#define  A       9
#define  B       10
#define  H       11

#define min(a, b) (a < b ? a : b)
#define max(a, b) (a > b ? a : b)
#define constrain(a, b, c) min(max(a, b), c)

int8_t _pos = 0;
uint8_t pos = 0;
bool state = false;

struct basicOsc{
  int16_t pos = 0;
  uint16_t add = 0;
  uint16_t filter = 0;
  uint16_t vol = 0;
};
struct melodyOsc : basicOsc{
  uint16_t sustain = 0x3FFF;
  bool released = true;
};
basicOsc drumsOscs[2];
melodyOsc melodyOscs[5];

uint64_t lastSoundUpdate = 0;
uint64_t lastSoundLoopControl = 0;

uint16_t musicPos = 0;
byte drumsData[] = {
  1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 2,
  1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 6, 5, 4, 3,
};
byte drumsFreq[] = {
  17, 37, 25, 40, 47, 55
};

byte bassData[] = {
  o1+D, o1+D, o2+D, o1+D, o2+C, o2+D, o1+D, o1+A, o2+C, o1+G, o1+A, o2+C, o1+D, o1+Gis, o1+G, o1+F,
  o1+D, o1+D, o2+D, o1+D, o2+C, o2+D, o1+D, o2+D, o2+F, o2+D, o2+E, o2+C, o2+D, o1+A, o2+C, o1+A,
};

byte chordsData[] = {
  0, 0, 0,
  0, 0, 0,
  o4+C, o4+D, o4+F,
  0, 0, 0,
  
  o4+C, o4+D, o4+F,
  o4+C, o4+D, o4+F,
  0, 0, 0,
  o4+C, o4+D, o4+F,
  
  0, 0, 0,
  o4+C, o4+D, o4+F,
  0, 0, 0,
  o4+C, o4+D, o4+F,
  
  o4+C, o4+D, o4+F,
  0, 0, 0,
  o4+C, o4+D, o4+F,
  0, 0, 0,

  
  0, 0, 0,
  0, 0, 0,
  o3+A, o4+C, o4+F,
  0, 0, 0,
  
  o3+A, o4+C, o4+F,
  o3+A, o4+C, o4+F,
  0, 0, 0,
  o3+A, o4+C, o4+F,
  
  0, 0, 0,
  o3+A, o4+C, o4+F,
  0, 0, 0,
  o3+A, o4+C, o4+F,
  
  o3+A, o4+C, o4+F,
  0, 0, 0,
  o3+A, o4+C, o4+F,
  0, 0, 0,

  
  0, 0, 0,
  0, 0, 0,
  o3+H, o4+D, o4+G,
  0, 0, 0,
  
  o3+H, o4+D, o4+G,
  o3+H, o4+D, o4+G,
  0, 0, 0,
  o3+H, o4+D, o4+G,
  
  0, 0, 0,
  o3+H, o4+D, o4+G,
  0, 0, 0,
  o3+H, o4+D, o4+G,
  
  o3+H, o4+D, o4+G,
  0, 0, 0,
  o3+H, o4+D, o4+G,
  0, 0, 0,

  
  0, 0, 0,
  0, 0, 0,
  o3+B, o4+D, o4+F,
  0, 0, 0,
  
  o3+B, o4+D, o4+F,
  o3+B, o4+D, o4+F,
  0, 0, 0,
  o3+G, o4+C, o4+E,
  
  0, 0, 0,
  o3+G, o4+C, o4+E,
  0, 0, 0,
  o3+G, o4+C, o4+E,
  
  o3+G, o4+C, o4+E,
  0, 0, 0,
  o3+G, o4+C, o4+E,
  0, 0, 0,
};

byte leadData[] = {
  o4+D, o4+D, o3+D, o3+D, o3+D, o3+D, o3+D, 0,
  0,    0,    0,    0,    o4+C, o3+A, o3+A, 0,    
  o4+C, o4+C, o3+A, o3+A, o3+A, o3+A, o3+A, 0,
  0,    0,    0,    0,    0,    0,    0,    0,  
  0,    0,    0,    0,    o3+G, o3+G, o3+F, o3+F,    
  o3+G, o3+Gis,o3+G,o3+G,o3+F, o3+F, o3+D, o3+D,  
  o3+D, o3+D, o3+D, o3+D, 0,    0,    0,    0,    
  0,    0,    0,    0,    o3+A, o4+C, 0,    o4+F,    
  
  o4+D, o4+D, o3+D, o3+D, o3+D, o3+D, o3+D, 0,
  0,    0,    0,    0,    o4+C, o3+A, o3+A, 0,    
  o4+C, o4+C, o3+A, o3+A, o3+A, o3+A, o3+A, 0,
  0,    0,    0,    0,    0,    0,    0,    0,  
  0,    0,    0,    0,    o3+G, o3+G, o3+F, o3+F,    
  o3+G, o3+Gis,o3+G,o3+G,o3+F, o3+F, o4+D, o4+D,  
  o4+D, o4+D, o4+D, o4+D, o4+D, o4+D, o4+D, o4+D,  
  o4+D, o4+D, o4+D, o4+D, 0,    0,    0,    0,    
};

void ICACHE_RAM_ATTR onTimerISR() {
  //val = max(pos, abs(32767 - filter1) * 2) >> 6;
  //analogWrite(5, val);
  //pos += 512;
  timer1_write(((state ? pos : (255 - pos)) / 4) + 10);
  digitalWrite(soundPin, state);
  state = !state;
  //filter1++;
  if(micros() - lastSoundUpdate > 20){
    lastSoundUpdate += 20;
    _pos = 0;
    for(byte i = 0;i < 2;i++){
      drumsOscs[i].pos += (drumsOscs[i].add * drumsOscs[i].filter) / 0x7FFF;
      _pos += (constrain(i == 0 ? (((abs(drumsOscs[i].pos * 2) - 0x7FFF) + drumsOscs[i].pos) / 2) : drumsOscs[i].pos, -drumsOscs[i].filter, drumsOscs[i].filter) * drumsOscs[i].vol) / 0x7FFFFF;
      if(drumsOscs[i].filter > (i == 0 ? 0x4FFF : 0x57FF)){
        drumsOscs[i].filter -= i == 0 ? 6 : 32;
      }
      else{
        drumsOscs[i].filter = 0;
      }
    }
    for(byte i = 0;i < 5;i++){
      melodyOscs[i].pos += melodyOscs[i].add;
      _pos += (constrain(melodyOscs[i].pos, -melodyOscs[i].filter, melodyOscs[i].filter) * melodyOscs[i].vol) / 0x7FFFFF;
      if(melodyOscs[i].filter > (melodyOscs[i].released ? 2 : (melodyOscs[i].sustain + 8))){
        melodyOscs[i].filter -= melodyOscs[i].released ? 2 : 8;
      }
    }
    pos = _pos + 128;
  }
}
uint16_t getAdd(uint16_t freq){
  return ((256UL * freq) << 8) / 50000;
}
uint16_t getFreq(uint8_t note){
  float freq[] = {65.4, 69.3, 73.4, 77.7, 82.4, 87.3, 92.5, 98.0, 103.8, 110.0, 116.5, 123.4};
  return freq[note%12] * (1 << uint8_t(note / 12))*min(1, note);
}
void setup() {
  Serial.begin(1000000);
  pinMode(soundPin, OUTPUT);
  for(byte i = 0;i < 10;i++){
    digitalWrite(soundPin, i & 1);
    delay(10);
  }
  timer1_attachInterrupt(onTimerISR);
  timer1_enable(TIM_DIV16, TIM_EDGE, TIM_SINGLE);
  timer1_write(1);
  drumsOscs[0].vol = 0x47FF;
  drumsOscs[1].vol = 0x2AFF;

  melodyOscs[0].vol = 0x2AFF;
  
  melodyOscs[1].vol = 0x18FF;
  melodyOscs[2].vol = 0x18FF;
  melodyOscs[3].vol = 0x18FF;
  
  melodyOscs[4].vol = 0x2AFF;
  melodyOscs[4].sustain = 0x5FFF;
}
void loop() {
  //for(uint16_t i = 0;i < 1000;i++){
  if(millis() - lastSoundLoopControl > 125){
    if(drumsData[musicPos % 32] != 0){
      drumsOscs[0].add = getAdd(drumsFreq[drumsData[musicPos % 32] - 1] * 10);
      drumsOscs[0].filter = 0x7FFF;
    }
    drumsOscs[1].add = getAdd(3000);
    drumsOscs[1].filter = 0x7FFF;
    if(musicPos >= 32){
      byte note = bassData[musicPos % 32];
      melodyOscs[0].released = note == 0;
      if(note != 0){
        melodyOscs[0].add = getAdd(getFreq(note - 1));
        if(bassData[(musicPos + 15) % 32] != note){
          melodyOscs[0].filter = 0x7FFF;
        }
      }
    }
    if(musicPos >= 96){
      for(byte i = 0;i < 3;i++){
        byte note = chordsData[(((musicPos - 96) % 64) * 3) + i];
        melodyOscs[i + 1].released = note == 0;
        if(note != 0){
          melodyOscs[i + 1].add = getAdd(getFreq(note - 1));
          melodyOscs[i + 1].filter = 0x5FFF;
        }
      }
    }
    if(musicPos >= 224){
      byte note = leadData[(musicPos - 224) % 128];
      melodyOscs[4].released = note == 0;
      if(note != 0){
        melodyOscs[4].add = getAdd(getFreq(note - 1));
        if(leadData[((musicPos - 224) + 127) % 128] != note){
          melodyOscs[4].filter = 0x7FFF;
        }
      }
    }
    musicPos++;
    lastSoundLoopControl = millis();
  }
  /*Serial.print(_pos >> 2);
  Serial.write('\t');
  //Serial.print((osc1 / 256) / 3);
  //Serial.write('\t');
  Serial.print(-40);
  Serial.write('\t');
  Serial.println(40);*/
  
  Serial.print(musicPos % 32);
  Serial.write('\t');
  Serial.print(0);
  Serial.write('\t');
  Serial.println(40);
  //}
  //delay(500);
  //delayMicroseconds(5);
}

Die Musik ist in 1/8-Sekundenteile gegliedert.
Mein Problem ist: Nach dem 50Hz-Brummen, welches im Setup erzeugt wird und den Anfang des ganzen Kladeradatschs darstelt, komt erstmal eine Pause für 15/8 Sekunden, dann ertönt eine der höheren Drums zusammen mit Hi-Hat, dann kommt nochmal die Hi-hat und dann hängt sich alles für zwei, drei Sekunden auf. Danach geht es so, wie es eigentlich soll, bei Takt 3, also Einheit 17 weiter mit der Bass Drum und dann normal weiter. Das Problem ist also, dass die ersten zwei Takte nicht so rüberkommen, wie sie sollen. Wenn ich die 1/8s-Einheiten auf 1/4s verringere, passiert alles genauso, nur dauert es länger. Und ich verstehe und verstehe nicht, warum diese ersten 16 Einheiten unterschlagen werden. Sonst funktioniert’s ja perfekt. Braucht ihr mehr Infos?

Gruß
HTML-Fan

Hi

Reden wir hier von 'musicPos' 0...15 klappt, dann Hänger, dann ab 16 weiter?
Was sagt Serial.print zur Musik-Position, wohin verzweigt der geneigte Rechenknecht und warum?
Da Du mit Timern spielst - änderst Du nach dem 17.ten Takt irgendwas am Timer?

MfG

postmaster-ino:
Reden wir hier von 'musicPos' 0...15 klappt, dann Hänger, dann ab 16 weiter?

Fast, bis 16 geht, dann kommt der Hänger, dann geht's weiter, aber "witziger"weise kommt nach dem Hänger noch die Bass Drum von 16.

postmaster-ino:
Was sagt Serial.print zur Musik-Position, wohin verzweigt der geneigte Rechenknecht und warum?

Was genau meinst du?

postmaster-ino:
Da Du mit Timern spielst - änderst Du nach dem 17.ten Takt irgendwas am Timer?

Nicht, dass ich wüsste.

Hi

Also Deine Musik spielt bis Takt 16 (ohne die Bass Drum), dann Hänger, dann kommt die Bass-Drum von 16 und Es geht fröhlich weiter?
Dann scheint irgend etwas zwischen 'vor der Bass Drum' und 'nach der Bass Drum' faul zu sein.

Hier könnten Dir Serial.print("Ich bin jetzt hier"); helfen, die Stellen im Sketch anzuzeigen, wo der Arduino gerade hin und her springt - wenn sich Das davon unterscheidet, Wo Er springen soll, kannst Du genau dort anfangen mit Buddeln - Der macht nämlich genau Das, was Du Dem gesagt hast - ist halt die Frage, ob Du genau genug dabei warst :slight_smile:
(ok, die Frage ist's nicht, sonst hätten wir keinen Fehler)

MfG

So. Jetzt bin ich verwirrt. Das Programm:

#define soundPin 5

#define  octave  12

#define  o1      1
#define  o2      1 + octave
#define  o3      1 + (octave * 2)
#define  o4      1 + (octave * 3)
#define  o5      1 + (octave * 4)
  
#define  C       0
#define  Cis     1
#define  D       2
#define  Dis     3
#define  E       4
#define  F       5
#define  Fis     6
#define  G       7
#define  Gis     8
#define  A       9
#define  B       10
#define  H       11

#define min(a, b) (a < b ? a : b)
#define max(a, b) (a > b ? a : b)
#define constrain(a, b, c) min(max(a, b), c)


#define OSC_DRUMS   0
#define OSC_HIHAT   1


#define OSC_BASS1    0
#define OSC_BASS2    1

#define OSC_CHORDS1  2
#define OSC_CHORDS2  3
#define OSC_CHORDS3  4

#define OSC_LEAD     5


int8_t _pos = 0;
uint8_t pos = 0;
bool state = false;

struct basicOsc{
  int16_t pos = 0;
  uint16_t add = 0;
  uint16_t filter = 0;
  uint16_t vol = 0;
};
struct melodyOsc : basicOsc{
  uint16_t sustain = 0x3FFF;
  bool released = true;
};
basicOsc drumsOscs[2];
melodyOsc melodyOscs[6];

uint64_t lastSoundUpdate = 0;
uint64_t lastSoundLoopControl = 0;

uint16_t musicPos = 0;
byte drumsData[] = {
  1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 2,
  1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 6, 5, 4, 3,
};
byte drumsFreq[] = {
  17, 37, 25, 40, 47, 55
};

byte bassData[] = {
  o1+D, o1+D, o2+D, o1+D, o2+C, o2+D, o1+D, o1+A, o2+C, o1+G, o1+A, o2+C, o1+D, o1+Gis, o1+G, o1+F,
  o1+D, o1+D, o2+D, o1+D, o2+C, o2+D, o1+D, o2+D, o2+F, o2+D, o2+E, o2+C, o2+D, o1+A, o2+C, o1+A,
};

byte chordsData[] = {
  0, 0, 0,
  0, 0, 0,
  o4+C, o4+D, o4+F,
  0, 0, 0,
  
  o4+C, o4+D, o4+F,
  o4+C, o4+D, o4+F,
  0, 0, 0,
  o4+C, o4+D, o4+F,
  
  0, 0, 0,
  o4+C, o4+D, o4+F,
  0, 0, 0,
  o4+C, o4+D, o4+F,
  
  o4+C, o4+D, o4+F,
  0, 0, 0,
  o4+C, o4+D, o4+F,
  0, 0, 0,

  
  0, 0, 0,
  0, 0, 0,
  o3+A, o4+C, o4+F,
  0, 0, 0,
  
  o3+A, o4+C, o4+F,
  o3+A, o4+C, o4+F,
  0, 0, 0,
  o3+A, o4+C, o4+F,
  
  0, 0, 0,
  o3+A, o4+C, o4+F,
  0, 0, 0,
  o3+A, o4+C, o4+F,
  
  o3+A, o4+C, o4+F,
  0, 0, 0,
  o3+A, o4+C, o4+F,
  0, 0, 0,

  
  0, 0, 0,
  0, 0, 0,
  o3+H, o4+D, o4+G,
  0, 0, 0,
  
  o3+H, o4+D, o4+G,
  o3+H, o4+D, o4+G,
  0, 0, 0,
  o3+H, o4+D, o4+G,
  
  0, 0, 0,
  o3+H, o4+D, o4+G,
  0, 0, 0,
  o3+H, o4+D, o4+G,
  
  o3+H, o4+D, o4+G,
  0, 0, 0,
  o3+H, o4+D, o4+G,
  0, 0, 0,

  
  0, 0, 0,
  0, 0, 0,
  o3+B, o4+D, o4+F,
  0, 0, 0,
  
  o3+B, o4+D, o4+F,
  o3+B, o4+D, o4+F,
  0, 0, 0,
  o3+G, o4+C, o4+E,
  
  0, 0, 0,
  o3+G, o4+C, o4+E,
  0, 0, 0,
  o3+G, o4+C, o4+E,
  
  o3+G, o4+C, o4+E,
  0, 0, 0,
  o3+G, o4+C, o4+E,
  0, 0, 0,
};

byte leadData[] = {
  o4+D, o4+D, o3+D, o3+D, o3+D, o3+D, o3+D, 0,
  0,    0,    0,    0,    o4+C, o3+A, o3+A, 0,    
  o4+C, o4+C, o3+A, o3+A, o3+A, o3+A, o3+A, 0,
  0,    0,    0,    0,    0,    0,    0,    0,  
  0,    0,    0,    0,    o3+G, o3+G, o3+F, o3+F,    
  o3+G, o3+Gis,o3+G,o3+G,o3+F, o3+F, o3+D, o3+D,  
  o3+D, o3+D, o3+D, o3+D, 0,    0,    0,    0,    
  0,    0,    0,    0,    o3+A, o4+C, 0,    o4+F,    
  
  o4+D, o4+D, o3+D, o3+D, o3+D, o3+D, o3+D, 0,
  0,    0,    0,    0,    o4+C, o3+A, o3+A, 0,    
  o4+C, o4+C, o3+A, o3+A, o3+A, o3+A, o3+A, 0,
  0,    0,    0,    0,    0,    0,    0,    0,  
  0,    0,    0,    0,    o3+G, o3+G, o3+F, o3+F,    
  o3+G, o3+Gis,o3+G,o3+G,o3+F, o3+F, o4+D, o4+D,  
  o4+D, o4+D, o4+D, o4+D, o4+D, o4+D, o4+D, o4+D,  
  o4+D, o4+D, o4+D, o4+D, 0,    0,    0,    0,    
};

void ICACHE_RAM_ATTR onTimerISR() {
  //val = max(pos, abs(32767 - filter1) * 2) >> 6;
  //analogWrite(5, val);
  //pos += 512;
  timer1_write(((state ? pos : (255 - pos)) / 4) + 10);
  digitalWrite(soundPin, state);
  state = !state;
  //filter1++;
  if(micros() - lastSoundUpdate > 20){
    lastSoundUpdate += 20;
    _pos = 0;
    for(byte i = 0;i < 2;i++){
      drumsOscs[i].pos += (drumsOscs[i].add * drumsOscs[i].filter) / 0x7FFF;
      _pos += (constrain(i == 0 ? (((abs(drumsOscs[i].pos * 2) - 0x7FFF) + drumsOscs[i].pos) / 2) : drumsOscs[i].pos, -drumsOscs[i].filter, drumsOscs[i].filter) * drumsOscs[i].vol) / 0x7FFFFF;
      if(drumsOscs[i].filter > (i == 0 ? 0x4FFF : 0x57FF)){
        drumsOscs[i].filter -= i == 0 ? 6 : 32;
      }
      else{
        drumsOscs[i].filter = 0;
      }
    }
    for(byte i = 0;i < 6;i++){
      melodyOscs[i].pos += melodyOscs[i].add;
      _pos += (constrain(i == OSC_BASS2 ? (abs(melodyOscs[i].pos * 2) - 0x7FFF) : melodyOscs[i].pos, -melodyOscs[i].filter, melodyOscs[i].filter) * melodyOscs[i].vol) / 0x7FFFFF;
      if(melodyOscs[i].filter > (melodyOscs[i].released ? 2 : (melodyOscs[i].sustain + 8))){
        melodyOscs[i].filter -= melodyOscs[i].released ? 2 : 8;
      }
    }
    pos = _pos + 128;
  }
}
uint16_t getAdd(uint16_t freq){
  return ((256UL * freq) << 8) / 50000;
}
uint16_t getFreq(uint8_t note){
  float freq[] = {65.4, 69.3, 73.4, 77.7, 82.4, 87.3, 92.5, 98.0, 103.8, 110.0, 116.5, 123.4};
  return freq[note%12] * (1 << uint8_t(note / 12))*min(1, note);
}
void setup() {
  Serial.begin(1000000);
  pinMode(soundPin, OUTPUT);
  for(byte i = 0;i < 10;i++){
    digitalWrite(soundPin, i & 1);
    delay(10);
  }
  timer1_attachInterrupt(onTimerISR);
  timer1_enable(TIM_DIV16, TIM_EDGE, TIM_SINGLE);
  timer1_write(1);
  
  drumsOscs[OSC_DRUMS].vol = 0x33FF;
  drumsOscs[OSC_HIHAT].vol = 0x1FFF;

  melodyOscs[OSC_BASS1].vol = 0x1AFF;
  melodyOscs[OSC_BASS1].sustain = 0x5FFF;
  melodyOscs[OSC_BASS2].vol = 0x2FFF;
  melodyOscs[OSC_BASS2].sustain = 0x1FFF;
  melodyOscs[OSC_BASS2].pos = 0x7FFF;
  
  melodyOscs[OSC_CHORDS1].vol = 0x13FF;
  melodyOscs[OSC_CHORDS2].vol = 0x13FF;
  melodyOscs[OSC_CHORDS3].vol = 0x13FF;
  
  melodyOscs[OSC_LEAD].vol = 0x1FFF;
  melodyOscs[OSC_LEAD].sustain = 0x5FFF;
}
void loop() {
  //for(uint16_t i = 0;i < 1000;i++){
  Serial.println("Position: Loop-Start");
  if(millis() - lastSoundLoopControl > 125){
    Serial.println("Position: Neue Toene - Start");
    if(drumsData[musicPos % 32] != 0){
      drumsOscs[OSC_DRUMS].add = getAdd(drumsFreq[drumsData[musicPos % 32] - 1] * 10);
      drumsOscs[OSC_DRUMS].filter = 0x7FFF;
    }
    Serial.println("Position: Neue Toene - 1");
    drumsOscs[OSC_HIHAT].add = getAdd(3000);
    drumsOscs[OSC_HIHAT].filter = 0x7FFF;
    if(musicPos >= 32){
      byte note = bassData[musicPos % 32];
      melodyOscs[OSC_BASS1].released = note == 0;
      if(note != 0){
        melodyOscs[OSC_BASS1].add = getAdd(getFreq(note - 1));
        if(bassData[(musicPos + 31) % 32] != note){
          melodyOscs[OSC_BASS1].filter = 0x7FFF;
        }
      }
      if(musicPos >= 64){
        melodyOscs[OSC_BASS2].released = note == 0;
        if(note != 0){
          melodyOscs[OSC_BASS2].add = (getAdd(getFreq(note - 1)) / 1) + 1;
          if(bassData[(musicPos + 31) % 32] != note){
            melodyOscs[OSC_BASS2].filter = 0x7FFF;
          }
        }
      }
    }
    Serial.println("Position: Neue Toene - 2");
    if(musicPos >= 96){
      for(byte i = 0;i < 3;i++){
        byte note = chordsData[(((musicPos - 96) % 64) * 3) + i];
        melodyOscs[i + OSC_CHORDS1].released = note == 0;
        if(note != 0){
          melodyOscs[i + OSC_CHORDS1].add = getAdd(getFreq(note - 1));
          melodyOscs[i + OSC_CHORDS1].filter = 0x5FFF;
        }
      }
    }
    Serial.println("Position: Neue Toene - 3");
    if(musicPos >= 224){
      byte note = leadData[(musicPos - 224) % 128];
      melodyOscs[OSC_LEAD].released = note == 0;
      if(note != 0){
        melodyOscs[OSC_LEAD].add = getAdd(getFreq(note - 1));
        if(leadData[((musicPos - 224) + 127) % 128] != note){
          melodyOscs[OSC_LEAD].filter = 0x7FFF;
        }
      }
    }
    musicPos++;
    lastSoundLoopControl = millis();
    Serial.println("Position: Fertig mit neuen Toenen");
  }
  /*Serial.print(_pos / 4);
  Serial.write('\t');
  //Serial.print((osc1 / 256) / 3);
  //Serial.write('\t');
  Serial.print(-40);
  Serial.write('\t');
  Serial.println(40);*/
  Serial.print("musicPos % 32: ");
  Serial.println(musicPos % 32);
  /*Serial.write('\t');
  Serial.print(0);
  Serial.write('\t');
  Serial.println(40);*/
  delay(25);
  Serial.println("Position: Fertig mit loop\n");
  //}
  //delay(500);
  //delayMicroseconds(5);
}

Ups, Zeichenlänge überschritten.

Die Ausgabe:

20:29:07.164 -> Position: Neue Toene - Start
20:29:07.164 -> Position: Neue Toene - 1
20:29:07.164 -> Position: Neue Toene - 2
20:29:07.164 -> Position: Neue Toene - 3
20:29:07.164 -> Position: Fertig mit neuen Toenen
20:29:07.164 -> musicPos % 32: 1
20:29:07.164 -> Position: Fertig mit loop
20:29:07.164 -> 
20:29:07.164 -> Position: Loop-Start
20:29:07.164 -> musicPos % 32: 1
20:29:07.204 -> Position: Fertig mit loop
20:29:07.204 -> 
20:29:07.204 -> Position: Loop-Start
20:29:07.204 -> musicPos % 32: 1
20:29:07.244 -> Position: Fertig mit loop
20:29:07.244 -> 
20:29:07.244 -> Position: Loop-Start
20:29:07.244 -> musicPos % 32: 1
20:29:07.244 -> Position: Fertig mit loop
20:29:07.244 -> 
20:29:07.244 -> Position: Loop-Start
20:29:07.244 -> musicPos % 32: 1
20:29:07.284 -> Position: Fertig mit loop
20:29:07.284 -> 
20:29:07.284 -> Position: Loop-Start
20:29:07.284 -> Position: Neue Toene - Start
20:29:07.284 -> Position: Neue Toene - 1
20:29:07.284 -> Position: Neue Toene - 2
20:29:07.284 -> Position: Neue Toene - 3
20:29:07.284 -> Position: Fertig mit neuen Toenen
20:29:07.284 -> musicPos % 32: 2
20:29:07.324 -> Position: Fertig mit loop
20:29:07.324 -> 
20:29:07.324 -> Position: Loop-Start
20:29:07.324 -> musicPos % 32: 2
20:29:07.324 -> Position: Fertig mit loop
20:29:07.324 -> 
20:29:07.324 -> Position: Loop-Start
20:29:07.324 -> musicPos % 32: 2
20:29:07.364 -> Position: Fertig mit loop
20:29:07.364 -> 
20:29:07.364 -> Position: Loop-Start
20:29:07.364 -> musicPos % 32: 2
20:29:07.364 -> Position: Fertig mit loop
20:29:07.364 -> 
20:29:07.364 -> Position: Loop-Start
20:29:07.364 -> musicPos % 32: 2
20:29:07.404 -> Position: Fertig mit loop
20:29:07.404 -> 
20:29:07.404 -> Position: Loop-Start
20:29:07.404 -> Position: Neue Toene - Start
20:29:07.404 -> Position: Neue Toene - 1
20:29:07.404 -> Position: Neue Toene - 2
20:29:07.404 -> Position: Neue Toene - 3
20:29:07.404 -> Position: Fertig mit neuen Toenen
20:29:07.404 -> musicPos % 32: 3
20:29:07.444 -> Position: Fertig mit loop

[...]

20:29:08.924 -> Position: Loop-Start
20:29:08.924 -> Position: Neue Toene - Start
20:29:08.924 -> Position: Neue Toene - 1
20:29:08.924 -> Position: Neue Toene - 2
20:29:08.924 -> Position: Neue Toene - 3
20:29:08.924 -> Position: Fertig mit neuen Toenen
20:29:08.924 -> musicPos % 32: 15
20:29:08.964 -> Position: Fertig mit loop
20:29:08.964 -> 
20:29:08.964 -> Position: Loop-Start
20:29:08.964 -> musicPos % 32: 15
20:29:08.964 -> Position: Fertig mit loop
20:29:08.964 -> 
20:29:08.964 -> Position: Loop-Start
20:29:08.964 -> musicPos % 32: 15
20:29:09.004 -> Position: Fertig mit loop
20:29:09.004 -> 
20:29:09.004 -> Position: Loop-Start
20:29:09.004 -> musicPos % 32: 15
20:29:09.044 -> Position: Fertig mit loop
20:29:09.044 -> 
20:29:09.044 -> Position: Loop-Start
20:29:09.044 -> musicPos % 32: 15
20:29:09.044 -> Position: Fertig mit loop
20:29:09.044 -> 
20:29:09.044 -> Position: Loop-Start
20:29:09.044 -> Position: Neue Toene - Start
20:29:09.044 -> Position: Neue Toene - 1
20:29:09.044 -> Position: Neue Toene - 2
20:29:09.044 -> Position: Neue Toene - 3
20:29:09.044 -> Position: Fertig mit neuen Toenen
20:29:09.044 -> musicPos % 32: 16
20:29:09.084 -> Position: Fertig mit loop
20:29:09.084 -> 
20:29:09.084 -> Position: Loop-Start
20:29:09.084 -> musicPos % 32: 16
20:29:12.764 -> Position: Fertig mit loop
20:29:12.764 -> 
20:29:12.764 -> Position: Loop-Start
20:29:12.764 -> Position: Neue Toene - Start
20:29:12.764 -> Position: Neue Toene - 1
20:29:12.764 -> Position: Neue Toene - 2
20:29:12.764 -> Position: Neue Toene - 3
20:29:12.764 -> Position: Fertig mit neuen Toenen
20:29:12.804 -> musicPos % 32: 17
20:29:12.804 -> Position: Fertig mit loop
20:29:12.804 -> 
20:29:12.804 -> Position: Loop-Start
20:29:12.804 -> musicPos % 32: 17
20:29:12.844 -> Position: Fertig mit loop
20:29:12.844 -> 
20:29:12.844 -> Position: Loop-Start
20:29:12.844 -> musicPos % 32: 17
20:29:12.844 -> Position: Fertig mit loop
20:29:12.844 -> 
20:29:12.844 -> Position: Loop-Start
20:29:12.844 -> musicPos % 32: 17
20:29:12.884 -> Position: Fertig mit loop
20:29:12.884 -> 
20:29:12.884 -> Position: Loop-Start
20:29:12.884 -> musicPos % 32: 17
20:29:12.924 -> Position: Fertig mit loop
20:29:12.924 -> 
20:29:12.924 -> Position: Loop-Start
20:29:12.924 -> Position: Neue Toene - Start
20:29:12.924 -> Position: Neue Toene - 1
20:29:12.924 -> Position: Neue Toene - 2
20:29:12.924 -> Position: Neue Toene - 3
20:29:12.924 -> Position: Fertig mit neuen Toenen
20:29:12.924 -> musicPos % 32: 18
20:29:12.924 -> Position: Fertig mit loop
20:29:12.924 -> 
20:29:12.924 -> Position: Loop-Start
20:29:12.924 -> musicPos % 32: 18
20:29:12.964 -> Position: Fertig mit loop
20:29:12.964 -> 
20:29:12.964 -> Position: Loop-Start
20:29:12.964 -> musicPos % 32: 18
20:29:13.004 -> Position: Fertig mit loop
20:29:13.004 -> 
20:29:13.004 -> Position: Loop-Start
20:29:13.004 -> musicPos % 32: 18
20:29:13.004 -> Position: Fertig mit loop

[...]

Es scheint sich tatsächlich an einem Delay festzusetzen! Wie ist das möglich?

Hi

Da die Zeilen nahezu DIREKT hintereinander stehen - kA.
Einzig das delay(25); steht dazwischen - Das sollte aber bei jedem anderen Aufruf auch so dort gestanden haben.

Ergibt keinen Sinn

MfG

Hmmm. Könnte es sein, dass sich das Programm durch die Timergeschichte irgendwo festsetzt und einfach in dem Moment zufälligerweise das unschuldige Delay bearbeitet wird. Könnte das sein? Aber am Timer ändere ich nichts, und dann würde es sich ja auch bei dem ersten Mal, bei dem 16 als musicPos angezeigt wird, aufhängen.

Was mich auch sehr wundert, ist, dass das ganze "Schlagzeug" vor 16 weggeschnitten ist. Es macht nur gaqnz leise Knack-Geräusche, die aber nicht mal im Plotter, den ich zum Graph umfunktioniert habe, angezeigt werden.

...versuch mal ein paar yield(); an diversen Stellen einzufügen. (mal nach yield(); googeln!)

Wird yield(); nicht bei jedem delay und nach jedem loop eingefügt?

Hast du es probiert?

Delay ist immer ein Problem. Besonders bei einem ESP8266 wegen dem WDT

Nein, habe ich nicht probiert, aber normalerweise habe ich da garkein Delay. Ich wollte nur nicht mit Meldungen überflutet werden.

Ich hab's jetzt mal ausprobiert, hat nix gebracht.

Jetzt habe ich das Delay gestrichen. Es scheint sich vollkommen unabhängig davon zu diesem einen Zeitpunkt aufzuhängen.

11:25:04.311 -> Position: Loop-Start
11:25:04.311 -> musicPos % 32: 16
11:25:04.311 -> 	0	40
11:25:04.311 -> Position: Fertig mit loop
11:25:04.311 -> 
11:25:04.311 -> Position: Loop-Start
11:25:04.311 -> musicPos % 32: 16
11:25:04.311 -> 	0	40
11:25:04.311 -> Position: Fertig mit loop
11:25:04.311 -> 
11:25:04.311 -> Position: Loop-Start
11:25:04.311 -> musicPos % 32: 16
11:25:04.311 -> 	0	40
11:25:04.311 -> Position: Fertig mit loop
11:25:04.311 -> 
11:25:04.311 -> Position: Loop-Start
11:25:04.311 -> musicPos % 32: 16
11:25:04.311 -> 	0	40
11:25:04.311 -> Position: Fertig mit loop
11:25:04.311 -> 
11:25:07.991 -> Position: Loop-Start
11:25:07.991 -> Position: Neue Toene - Start
11:25:07.991 -> Position: Neue Toene - 1
11:25:07.991 -> Position: Neue Toene - 2
11:25:07.991 -> Position: Neue Toene - 3
11:25:07.991 -> Position: Fertig mit neuen Toenen
11:25:07.991 -> musicPos % 32: 17
11:25:07.991 -> 	0	40
11:25:07.991 -> Position: Fertig mit loop
11:25:07.991 -> 
11:25:07.991 -> Position: Loop-Start
11:25:07.991 -> musicPos % 32: 17
11:25:07.991 -> 	0	40
11:25:07.991 -> Position: Fertig mit loop
11:25:07.991 -> 
11:25:07.991 -> Position: Loop-Start
11:25:07.991 -> musicPos % 32: 17
11:25:07.991 -> 	0	40
11:25:07.991 -> Position: Fertig mit loop

Jetzt kapiere ich nix mehr. Das Programm kann ich hier nicht mehr hochladen, es sind mehr als die großen 9000 Zeichen.

Das wesentliche, was ich getan habe, ist, dass ich

timer1_write(((state ? pos : (255 - pos)) / 4) + 10);

zu

timer1_write(((state ? pos : (255 - pos)) / 2) + 10);

abgeändert habe.
Das Problem könnt ihr im Anhang hören: Bis, keine Ahnung, vielleicht so musicPos 75 ist alles ein ganzes Stück höher. Irgendwie verliere ich immer mehr den Durchblick. Weswegel läuft das so überhaupt nicht, wie es soll?

Zip.zip (773 KB)

Ach ja, ganz vergessen:
Ich habe mir mal mit dem Plotter den Wert von drumsOscs[OSC_DRUMS].filter ausgeben lassen: Vor musicPos 16 liegt der Wert konstant bei dem Höhstwert. Woraus ich schließe, was durch andere Versuche ebenfalls bestätigt haben, das Interrupt vor 16 warum auch immer nicht funktioniert. Warum? ist jetzt die große Preisfrage.

Hi

Bis darauf, daß 16 die erste 5-Bit-Zahl ist, fällt mir Nichts auf - ist halt eine 2er Potenz, Die beim µC durchaus irgendwas bewirken kann, was 'davor' eben nicht aktiv ist.

Nur was und wie - oder gar wieso ... nix weiß.

MfG

Jetzt fühle ich mich vollkommen reingelegt! Bei diesem Programm wird ein Piepgeräusch produziert, obwohl pos immer gleich 0 sein sollte. Außerdem hängt sich der Loop auf. Eigentlich sollte ein Ton in der Höhe des über A0 eingespeisten Ton produziert werden.

#define soundPin 5
#define max(a, b) (a > b ? a : b)
#define SAMPLE_RATE 50000
#define BUF_MS 25
const int bufLen = SAMPLE_RATE * BUF_MS / 1000;
int8_t buf[bufLen];
uint16_t bufPos = 0;
uint16_t pitch = 0;
int16_t soundPos = 0;
uint64_t lastSoundUpdate = 0;
bool state = false;
int8_t _pos = 0;
uint8_t pos = 0;
byte change = 0;

uint16_t getAdd(uint16_t freq){
  return ((256UL * freq) << 8) / 50000;
}

void ICACHE_RAM_ATTR onTimerISR() {
  timer1_write(((state ? pos : (255 - pos)) / 4) + 25);
  digitalWrite(soundPin, state);
  state = !state;
  change++;//= true;
  //filter1++;
  if(micros() - lastSoundUpdate > 20){
    Serial.println(change);
    lastSoundUpdate += 20;
    buf[bufPos++] = (analogRead(0) - 512) / 4;
    bufPos %= bufLen;
    _pos = 0;
    //soundPos += 0;//getAdd(pitch);
    //_pos += soundPos >> 8;
    pos = _pos + 128;
  }
}

void setup() {
  Serial.begin(1000000);
  Serial.println(bufLen);
  pinMode(5, OUTPUT);
  delay(1000);
  timer1_attachInterrupt(onTimerISR);
  timer1_enable(TIM_DIV16, TIM_EDGE, TIM_SINGLE);
  timer1_write(1);
}

void loop() {
  int8_t highest = -128;
  int8_t lowest = 127;
  for(uint16_t i = 0;i < bufLen;i++){
    if(buf[i] > highest){
      highest = buf[i];
    }
    if(buf[i] < lowest){
      lowest = buf[i];
    }
  }

  uint16_t pos0 = 0;
  uint16_t pos1 = 0;
  if(highest - lowest > 10){
    int8_t posNum = 0;
    int8_t high = map(75, 0, 100, lowest, highest);
    int8_t low = map(25, 0, 100, lowest, highest);
    
    for(uint16_t i = 0;i < bufLen;i++){
      int8_t val = buf[(i + bufPos) % bufLen];
      if(posNum == 0 && val >= high){
        posNum = 1;
      }
      if(posNum == 1 && val <= low){
        posNum = 2;
        pos0 = i;
      }
      if(posNum == 2 && val >= high){
        posNum = 3;
      }
      if(posNum == 3 && val <= low){
        pos1 = i;
        break;
      }
    }
    pitch = SAMPLE_RATE / (pos1 - pos0);
  }
  else{
    pitch = 0;
  }
  Serial.println(change);//max(pos1 - pos0, 0));
}

Irgendwie verdoppelt sich meine Motivation bei jedem Beitrag.