Forum: Mikrocontroller und Digitale Elektronik STM32F4Discovery Audio "Störgeräusche"


von Mario S. (masp)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

ich nutze eine STM32F4Discovery als Audioplayer und den Code von 
Benjamins Robotics 
(http://vedder.se/2012/12/stm32f4-discovery-usb-host-and-mp3-player/) 
als Basis. Anschluss erfolgt über den Headphone-Ausgang an einen 
externen Verstärker.

Der Code spielt mp3 per DMA vom USB-Stick aus. Das erfolgt mit 2 
Audio-Puffern entsprechend einer Application Note von ST. Das Abspielen 
eines mp3 kann per Taster unterbrochen werden (Sprung zum nächsten mp3).

Je MP3 wird der Audio-Codec vom aktuellen Code:

- Initialisiert (Code geändert, damit mit Lautstärke 0x00 initialisiert 
wird)
- DMA eingeschaltet (spielt die Audiodaten ab)
- Interrupt eingeschaltet (schaltet die Puffer um)
- Lautstärke (0x90)
- MP3 wird decoded und gespielt
- Lautstärke (0) (per fade-out)
- Interrupt ausgeschaltet
- DMA ausgeschaltet

Main.c versorgt die Puffer mit Audiodaten. Das alles klappt sehr gut und 
mit guter Audio-Qualität. Nun zum Problem:

Bei jedem Wechsel eines mp3 erzeugt der Audio Codec am Kopfhörerausgang 
Ein-Ausschalt-Störungen. Ein doch sehr lautes "Knacken" ist zu hören. 
Hat hierfür jemand eine Lösung?

Meine erste Idee ist, den Code so umzuschreiben, dass DMA und Interrupt 
weiterlaufen (Pointer auf Audio-Daten werden entsprechend auf "0"-Werte 
umgelegt). Zudem müsste der Code noch die "verbleibenden" Daten im 
Puffer mit 0-Werten füllen, um tatsächlich auch ein "Ende" zu hören, 
wenn das Abspielen eines mp3 unterbrochen wird. Wenn ich übrigens nur 
die Codec-Initialisierung "InitializeAudio(Audio44100HzSettings)" zu 
Beginn in main.c ausführe und aus play_mp3 lösche, ist kein Audio-Output 
zu hören. Den Grund hierfür hab per Debugger noch nicht auffinden 
können.

Ausschnitt main.c hier; Initialisierungsfunktionen, DMA, etc. in audio.c 
anbei.

static FRESULT play_mp3(char* filename) {

    ...
    ...
    ...

    // Play mp3
    hMP3Decoder = MP3InitDecoder();
    InitializeAudio(Audio44100HzSettings);
    PlayAudioWithCallback(AudioCallback, 0);
    SetAudioVolume(volume);

    for(;;) {

        Feedmp3Data();

        // Out of data or error or user button... Stop playback!
        if (br < btr || res != FR_OK) {

          // Re-initialize and set volume to avoid noise
          SetAudioVolume(0);
          StopAudio();
          InitializeAudio(Audio44100HzSettings);

          // Close currently open file
          f_close(&file);

          // Return to previous function
          break;

        }
      }

      // Stop Playing if Button is pressed!
      if (!startfadeout) {


        if ((newposition = ReadPosition())) {  // Get Keypress

          // Start Fadeout
          fadevolume = volume;
          startfadeout = 1;

        }

      } else {

        if (fadevolume > (MIN_VOLUME - 0x20)) {
          fadevolume -= 1;
          SetAudioVolume(fadevolume);
          Delay(3);
        } else {
          SetAudioVolume(0);
          StopAudio();
          InitializeAudio(Audio44100HzSettings);

          // Return to previous function
          break;
        }
      }

    }

    // Free Memory
    MP3FreeDecoder(hMP3Decoder);
  }

  return res;

}

Gruß
Mario

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Mario S. schrieb:
> Hat hierfür jemand eine Lösung?

Dann ruf doch vor dem Trackwechsel ein Audio Mute auf.
1
I2C_WriteByte(CODEC_I2C_ADRESS,0x04, 0xFF); // SPK off , HP off
Sobald der neue Track geladen ist, gibst du den Sound wieder frei.
1
I2C_WriteByte(CODEC_I2C_ADRESS,0x04, 0xAF); // Audio ummute
Wenn das knackt, kannst du immer noch die Lautstärke auf null setzen und 
dann wieder auf den vorherigen Wert.
> InitializeAudio(Audio44100HzSettings);
Das solltest du nicht immer wieder machen müssen - einmal sollte 
reichen. Erforsche mal, ob die Funktion auch noch an irgendwelchen 
Registern des Audiodekoders rumfummelt.

von Chris (Gast)


Lesenswert?

Hi,

manche Codecs haben dafür eine extra Unterdrückung die man einschalten 
kann.

Gruß

von Mario S. (masp)


Lesenswert?

Hallo Matthias,

ich habe die beiden Funktionen unten entsprechend eingebaut und es 
klappt perfekt.

void OutputOn() {
  WriteRegister(0x04, 0xaf); // SPK always off and HP always on.
}

void OutputtOff() {
  WriteRegister(0x04, 0xff); // SPK always off and HP always on.
}

Danke
Mario

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.