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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren