Brauche kurz Hilfe bei MP3-Player

OP #4194996
Lesenswert?
• ▲
▼
Hallo

angeregt durch einen anderen Thread, den ich hier mal gelesen habe, 
wollte ich auch einen eigenen MP3-Player bauen. Um zu testen, ob alles 
funktioniert, benutze ich das STM32F4 Discovery Board. Dort habe ich 
einen SD-Kartensockel angelötet. In meiner Software ist FATFS von 
ElmChan drin, sowie der Helix-Decoder.

Zuerst habe ich, um den Decoder zu testen, einfach eine kleine MP3-Datei 
als Array in den Flash des STM geladen und dann jeweils Stück für Stück 
in den RAM kopiert. Damit hat das Abspielen eines MP3 wunderbar 
geklappt, ohne Aussetzer oder so, selbst bei 48 kHz und 320 kBuit/s. 
Jetzt will ich das MP3-File allerdings von der SD-Karte lesen! Da ich 
später noch ein GUI implementieren will, habe ich mir gedacht, die SW 
als kleinen Zustandsautomaten zu implementierren. Hier mein main-Code:
1
__attribute__((noreturn)) void main(void)
2
{
3
   state_t state = init_play_mp3;
4
  int ind = 0;
5
  int remain_bytes;
6
  int free_samples;
7
  int bytes_to_read;
8

9
  int br;
10
  int filesize;
11
  memset(buf, 0, sizeof(buf));
12
  memset(sdbuf, 0, sizeof(sdbuf));
13

14

15
  init_hardware();
16

17
  mci_media_init();
18

19

20
  f_mount(&fs, "0:", 1);
21

22

23

24

25

26
  while(1)
27
  {
28

29

30

31
    switch(state)
32
    {
33
      case init_play_mp3:
34
      {
35
        init_mp3(buf, NUMOF_ELEMENTS(buf));
36
        state = preload_mp3_buffer;
37

38
        f_open(&fl, "0:/eminence_front.mp3", FA_READ);
39
          f_stat("0:/eminence_front.mp3", &fileinfo);
40
          filesize = fileinfo.fsize;
41

42
          ind = 0;
43

44
        break;
45
      }
46

47
      case preload_mp3_buffer:
48
      {
49
        int decoded_bytes;
50

51
        bytes_to_read = (filesize - ind) > BUFSZ ? BUFSZ : (filesize - ind);
52

53
        f_lseek(&fl, ind);
54
        f_read(&fl, sdbuf, bytes_to_read, &br);
55

56

57
        remain_bytes = decode_mp3(sdbuf, bytes_to_read);
58
        decoded_bytes = bytes_to_read - remain_bytes;
59

60
        ind = ind + decoded_bytes;
61

62
        free_samples = get_free_samps();
63

64

65
        if(free_samples < 4608)
66
        {
67
          start_playback();
68
          state = play_mp3;
69
        }
70

71
        break;
72
      }
73

74
      case play_mp3:
75
      {
76

77
        int prev_remain_bytes = 0;
78
        int decoded_bytes;
79

80
        free_samples = get_free_samps();
81
        if(free_samples > 2304*1)
82
        {
83

84

85

86
          GPIOC_BSRR = BIT_05;
87
          prev_remain_bytes = remain_bytes;
88

89
          remain_bytes = decode_mp3(&sdbuf[sizeof(sdbuf)-remain_bytes], remain_bytes);
90
          decoded_bytes = prev_remain_bytes - remain_bytes;
91
          ind = ind + decoded_bytes;
92

93
          GPIOC_BSRR = BIT_21;
94
        }
95

96

97
        if((remain_bytes < 512) || (decoded_bytes == 0))
98
        {
99

100
          GPIOD_BSRR = BIT_12;
101
          bytes_to_read = (filesize - ind) > BUFSZ ? BUFSZ : (filesize - ind);
102

103
          if(bytes_to_read < 100)
104
          {
105
            stop_playback();
106
            state = stop_mp3;
107
            break;
108
          }
109
          f_lseek(&fl, ind);
110
          f_read(&fl, sdbuf, bytes_to_read, &br);
111

112
          remain_bytes = bytes_to_read;
113

114
          GPIOD_BSRR = BIT_28;
115
        }
116

117

118

119
        break;
120
      }
121

122
      case stop_mp3:
123
      {
124
        free_mp3();
125
        state = init_play_mp3;
126
        ind = 0;
127
        break;
128
      }
129
    }
130
  }
131
}


Jetzt stelle ich allerdings fest, dass es gelegentlich zu kleinen 
Aussetzern kommt. Da alles funktioniert, wenn ich die Datei per memcpy() 
aus dem Flash kopiere und so decodieren, muss das Problem am 
Buffer-Management zusammen mit dem Lesen der SD-Karte zusammenhängen. 
Leider sehe ich gerade nicht, wo man was optimieren müsste. Wäre es 
möglich dass die Profis hier mal kurz auf meinen Code schauen? :-)

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.