Forum: Mikrocontroller und Digitale Elektronik STM32F429 WM8789 MP3


von Peter (Gast)


Lesenswert?

Hallo,
ich versuche grade das Beispiel von ST zum laufen zu bekommen um MP3 von 
SD-Card Abzuspielen, es wird zwar die MP3 abgespielt aber extrem langsam 
und total verzerrt.
vielleicht kann mir einer weiterhelfen.
mfg
1
/* Private define ------------------------------------------------------------*/
2
#define READBUF_SIZE  (5 * 1024)       /* Value must min be 2xMAINBUF_SIZE = 2x1940 = 3880bytes */
3
#define BUFF_SIZE 4608
4
typedef struct buffs
5
{
6
  short BufData[BUFF_SIZE];
7
  struct buffs * Next;
8
}BuffDef;
9
BuffDef Buff[2];
10
BuffDef* BuffP = &Buff[0];
11
/* Private variables ---------------------------------------------------------*/
12
AUDIO_PlaybackBuffer_Status BufferStatus; /* Status of buffer */
13
s16 AudioBuffer[4608];          /* Playback buffer - Value must be 4608 to hold 2xMp3decoded frames */
14
MP3FrameInfo mp3FrameInfo;      /* Content is the output from MP3GetLastFrameInfo, 
15
                                   we only read this once, and conclude it will be the same in all frames
16
                                   Maybe this needs to be changed, for different requirements */
17
static HMP3Decoder hMP3Decoder; /* Content is the pointers to all buffers and information for the MP3 Library */
18
volatile uint32_t bytesLeft;    /* Saves how many bytes left in readbuf  */
19
volatile uint32_t outOfData;    /* Used to set when out of data to quit playback */
20
volatile AUDIO_PlaybackBuffer_Status  audio_buffer_fill ; 
21
volatile int Audio_buffer_index = 0;
22
volatile uint16_t Audio_buffer_size = 0;
23
volatile s16 Audio_buffer_local[LOCAL_BUFFER_SIZE];       /* working buffer for MONO mode management */
24
AUDIO_Playback_status_enum AUDIO_Playback_status ;
25
AUDIO_Format_enum AUDIO_Format ;
26
AUDIO_Length_enum AUDIO_Length ;
27
AUDIO_PlaybackBuffer_Status bufferstatus_local;
28
s8  *Audio_buffer;
29
int Audio_buffer_local_size = LOCAL_BUFFER_SIZE;
30
uint8_t readBuf[READBUF_SIZE];       /* Read buffer where data from SD card is read to */ 
31
uint8_t *readPtr;                    /* Pointer to the next new data */
32
uint32_t MP3Size;                  
33
uint32_t MP3_Data_Index;            
34
uint16_t AUDIO_Frequency ;
35
uint32_t n_Read;                     /* File R/W count */
36
37
FIL fsra;      // file objects
38
UINT ba;         /* File read/write count */
39
40
41
42
43
44
45
46
/*******************************************************************************
47
* Function Name  : AUDIO_PlaybackBuffer_Status
48
* Description    : Gets the status of Playback buffer
49
* Input          : - value: 0 = get the current status, else reset the flag
50
*                           passed in parameter
51
* Output         : None
52
* Return         : FULL=0, LOW_EMPTY=1, HIGH_EMPTY=2
53
* Attention     : None
54
*******************************************************************************/
55
AUDIO_PlaybackBuffer_Status AUDIO_PlaybackBuffer_GetStatus(AUDIO_PlaybackBuffer_Status value)
56
{
57
    if ( value )
58
        audio_buffer_fill &= ~value;
59
    return audio_buffer_fill; 
60
}
61
62
/*******************************************************************************
63
* Function Name  : AUDIO_Playback_Stop
64
* Description    : Stop the playback by stopping the DMA transfer
65
* Input          : None
66
* Output         : None
67
* Return         : None
68
* Attention     : None
69
*******************************************************************************/
70
void AUDIO_Playback_Stop(void)
71
{
72
  /* Enable the SAI DMA Stream*/
73
  DMA_Cmd(AUDIO_MAL_DMA_STREAM, DISABLE);
74
75
   AUDIO_Playback_status = NO_SOUND;       
76
   /* Shutdwon codec in order to avoid non expected voices */
77
   //codec_send( ACTIVE_CONTROL | INACTIVE );
78
}
79
80
81
/*******************************************************************************
82
* Function Name  : MP3_GetStrResult
83
* Description    : Convert file access error number in string
84
* Input          : None
85
* Output         : None
86
* Return         : None
87
* Attention     : None
88
*******************************************************************************/
89
const char* MP3_GetStrResult(int err)
90
{
91
    switch(err) {
92
        case ERR_MP3_NONE :                   return "ERR_MP3_NONE";
93
        case ERR_MP3_INDATA_UNDERFLOW :       return "ERR_MP3_INDATA_UNDERFLOW";
94
        case ERR_MP3_MAINDATA_UNDERFLOW :     return "ERR_MP3_MAINDATA_UNDERFLOW";
95
        case ERR_MP3_FREE_BITRATE_SYNC :      return "ERR_MP3_FREE_BITRATE_SYNC";
96
        case ERR_MP3_OUT_OF_MEMORY :          return "ERR_MP3_OUT_OF_MEMORY";
97
        case ERR_MP3_NULL_POINTER :           return "ERR_MP3_NULL_POINTER";
98
        case ERR_MP3_INVALID_FRAMEHEADER :    return "ERR_MP3_INVALID_FRAMEHEADER";   
99
        case ERR_MP3_INVALID_SIDEINFO :       return "ERR_MP3_INVALID_SIDEINFO"; 
100
        case ERR_MP3_INVALID_SCALEFACT :      return "ERR_MP3_INVALID_SCALEFACT";
101
        case ERR_MP3_INVALID_HUFFCODES :      return "ERR_MP3_INVALID_HUFFCODES";
102
        case ERR_MP3_INVALID_DEQUANTIZE :     return "ERR_MP3_INVALID_DEQUANTIZE";
103
        case ERR_MP3_INVALID_IMDCT :          return "ERR_MP3_INVALID_IMDCT";
104
        case ERR_MP3_INVALID_SUBBAND :        return "ERR_MP3_INVALID_SUBBAND";
105
        case ERR_UNKNOWN :                    return "ERR_UNKNOWN";  
106
        default :                             return "?";
107
    }  
108
}
109
110
/*******************************************************************************
111
* Function Name  : DMA_Configuration
112
* Description    : DMA1 channel5 configuration
113
* Input          : None
114
* Output         : None
115
* Return         : None
116
* Attention     : None
117
*******************************************************************************/
118
void DMA_Configuration( s8 * addr, int size)
119
{
120
  DMA_InitTypeDef DMA_InitStructure;
121
122
  /* Enable the SAI  */
123
  //SAI_Cmd(CODEC_SAI, DISABLE);
124
  
125
  /* Enable the DMA clock */
126
  RCC_AHB1PeriphClockCmd(AUDIO_MAL_DMA_CLOCK, ENABLE); 
127
128
    /* Configure the DMA Stream */
129
  DMA_Cmd(AUDIO_MAL_DMA_STREAM, DISABLE);
130
  DMA_DeInit(AUDIO_MAL_DMA_STREAM);
131
  
132
    if(AUDIO_Format == STEREO)
133
    {
134
       /* Uses the original buffer  */            
135
     DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t) addr; /* Set the buffer */
136
     DMA_InitStructure.DMA_BufferSize = size;             /* Set the size */
137
    }
138
    else
139
    {
140
       /* Uses the local buffer */
141
       if ( AUDIO_Length == LG_16_BITS )   size *= 2;   
142
       Audio_buffer = addr;                         /* Copy the pointer to real databuffer/source */
143
       Audio_buffer_index = 0;                      /* Copy the pointer to real databuffer/source */
144
       Audio_buffer_size = size;                    /* Size to the real databuffer/source */
145
     DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)Audio_buffer_local;   /* Set the buffer */
146
     DMA_InitStructure.DMA_BufferSize = ((Audio_buffer_local_size)/2);;    /* Set the size */
147
    }
148
149
  /* Set the parameters to be configured */
150
  DMA_InitStructure.DMA_Channel = AUDIO_MAL_DMA_CHANNEL;  
151
  DMA_InitStructure.DMA_PeripheralBaseAddr = CODEC_SAI_ADDRESS;
152
  DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
153
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
154
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
155
  DMA_InitStructure.DMA_PeripheralDataSize = AUDIO_MAL_DMA_PERIPH_DATA_SIZE;
156
  DMA_InitStructure.DMA_MemoryDataSize = AUDIO_MAL_DMA_MEM_DATA_SIZE; 
157
#ifdef AUDIO_MAL_MODE_NORMAL
158
  DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
159
#elif defined(AUDIO_MAL_MODE_CIRCULAR)
160
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
161
#else
162
  #error "AUDIO_MAL_MODE_NORMAL or AUDIO_MAL_MODE_CIRCULAR should be selected !!"
163
#endif /* AUDIO_MAL_MODE_NORMAL */  
164
  DMA_InitStructure.DMA_Priority = DMA_Priority_High;
165
  DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;         
166
  DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
167
  DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
168
  DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;  
169
  DMA_Init(AUDIO_MAL_DMA_STREAM, &DMA_InitStructure);  
170
171
  /* Enable the selected DMA interrupts (selected in "stm32_eval_audio_codec.h" defines) */
172
#ifdef AUDIO_MAL_DMA_IT_TC_EN
173
  DMA_ITConfig(AUDIO_MAL_DMA_STREAM, DMA_IT_TC, ENABLE);
174
#endif /* AUDIO_MAL_DMA_IT_TC_EN */
175
#ifdef AUDIO_MAL_DMA_IT_HT_EN
176
  DMA_ITConfig(AUDIO_MAL_DMA_STREAM, DMA_IT_HT, ENABLE);
177
#endif /* AUDIO_MAL_DMA_IT_HT_EN */
178
#ifdef AUDIO_MAL_DMA_IT_TE_EN
179
  DMA_ITConfig(AUDIO_MAL_DMA_STREAM, DMA_IT_TE | DMA_IT_FE | DMA_IT_DME, ENABLE);
180
#endif /* AUDIO_MAL_DMA_IT_TE_EN */
181
  
182
  /* Enable the SAI DMA request */
183
  SAI_DMACmd(CODEC_SAI, ENABLE);
184
  /* Enable the SAI DMA Stream*/
185
  DMA_Cmd(AUDIO_MAL_DMA_STREAM, ENABLE);
186
187
  
188
  /* If the SAI peripheral is still not enabled, enable it */
189
  if (SAI_GetCmdStatus(CODEC_SAI) == DISABLE)
190
  {
191
    SAI_Cmd(CODEC_SAI, ENABLE);
192
  }  
193
}
194
195
196
/*******************************************************************************
197
* Function Name  : PlayAudioFile
198
* Description    : None
199
* Input          : None
200
* Output         : None
201
* Return         : None
202
* Attention     : None
203
*******************************************************************************/
204
void PlayAudioFile(void)
205
{
206
  Buff[0].Next = &Buff[1];
207
  Buff[1].Next = &Buff[0];
208
  
209
  static UINT br; 
210
  s32 offset;                                  // Used to save the offset to the next frame    
211
  int errs = 0;                                   // Return value from MP3decoder
212
  FRESULT res;
213
  FILINFO finfo;
214
  DIR dirs;  
215
   /* Reset counters */
216
   bytesLeft = 0;   
217
   outOfData = 0;   
218
 
219
  
220
  
221
   readPtr = readBuf;  
222
   hMP3Decoder = MP3InitDecoder();  
223
224
              //f_chdir("/MP3");
225
/**/
226
    if (f_opendir(&dirs, "") == FR_OK)         //Ŀ¼´ò¿ª³É¹¦ 
227
    {
228
      while (f_readdir(&dirs, &finfo) == FR_OK)      //Ŀ¼ÏÂÊÇ·ñÓÐÎļþ
229
      {
230
        if (finfo.fattrib & AM_ARC) 
231
        {
232
          if(!finfo.fname[0]) break;
233
          
234
          //Usart_Puts("\r\n Now Playing:[");
235
          //Usart_Puts(finfo.fname);
236
          //Usart_Puts("]\r\n");
237
238
           DrawString(200,350,finfo.fname,&Arial_16x25,Orange,BLACK);
239
          res = f_open(&fsra, finfo.fname, FA_OPEN_EXISTING | FA_READ);
240
          //res = f_open(&fsra, "FR", FA_READ);
241
          // Reset counters //
242
              
243
244
          res = f_read(&fsra,readBuf,READBUF_SIZE,&br);
245
          bytesLeft += br;
246
          
247
          //if( (res) ||(br == 0)) break;
248
249
          while(1)
250
          {
251
            
252
            
253
            // find start of next MP3 frame - assume EOF if no sync found //
254
            offset = MP3FindSyncWord(readPtr, bytesLeft);
255
            if (offset < 0) 
256
            {
257
                    outOfData = 1;
258
                    break;
259
            }
260
            else
261
            {
262
              readPtr += offset;                         //data start point
263
              bytesLeft -= offset;                 //in buffer
264
              errs = MP3Decode(hMP3Decoder, &readPtr, (int *)&bytesLeft, (short *)AudioBuffer, 0); 
265
266
              if (bytesLeft < READBUF_SIZE)
267
              {
268
                memmove(readBuf,readPtr,bytesLeft);
269
                res = f_read(&fsra, readBuf + bytesLeft, READBUF_SIZE - bytesLeft, &br);
270
                if( (res) ||(br == 0)) break;
271
                
272
                if (br < READBUF_SIZE - bytesLeft)
273
                memset(readBuf + bytesLeft + br, 0, READBUF_SIZE - bytesLeft - br);
274
                bytesLeft=READBUF_SIZE;
275
                readPtr=readBuf;                
276
              }
277
278
              MP3GetLastFrameInfo(hMP3Decoder, &mp3FrameInfo);
279
              
280
   // Select the correct samplerate and Mono/Stereo //
281
            AUDIO_Init_audio_mode( ( AUDIO_Length_enum )mp3FrameInfo.bitsPerSample,  \
282
            ((MP3DecInfo *)hMP3Decoder)->samprate,  \
283
            (((MP3DecInfo *)hMP3Decoder)->nChans==2) ? MONO : STEREO);
284
            }
285
          }
286
          f_close(&fsra);
287
288
289
        
290
        }
291
      }
292
      //break;
293
    }
294
    //OSTimeDly(10);
295
296
                  
297
   MP3GetLastFrameInfo(hMP3Decoder, &mp3FrameInfo); 
298
  
299
   /* Select the correct samplerate and Mono/Stereo */
300
   AUDIO_Init_audio_mode( ( AUDIO_Length_enum )mp3FrameInfo.bitsPerSample,  \
301
            ((MP3DecInfo *)hMP3Decoder)->samprate,  \
302
            (((MP3DecInfo *)hMP3Decoder)->nChans==1) ? MONO : STEREO);
303
304
}
305
306
void DMA2_Stream5_IRQHandler(void)
307
{   
308
  /* Transfer complete interrupt */
309
  if (DMA_GetFlagStatus(AUDIO_MAL_DMA_STREAM, AUDIO_MAL_DMA_FLAG_TC) != RESET)  /* DMA1 ͨµÀ5 ´«ÊäÍê³ÉÖÐ¶Ï */
310
  {           
311
    /* Clear the Interrupt flag */
312
    DMA_ClearFlag(AUDIO_MAL_DMA_STREAM, AUDIO_MAL_DMA_FLAG_TC);
313
      bufferstatus_local |= HIGH_EMPTY;
314
      if(AUDIO_Format == MONO)
315
      {
316
         AUDIO_Cpy_Mono();
317
      }
318
      else
319
      {
320
         audio_buffer_fill |= HIGH_EMPTY;
321
      }
322
  }
323
324
  if (DMA_GetFlagStatus(AUDIO_MAL_DMA_STREAM, AUDIO_MAL_DMA_FLAG_HT) != RESET)
325
  {      
326
    /* Clear the Interrupt flag */
327
    DMA_ClearFlag(AUDIO_MAL_DMA_STREAM, AUDIO_MAL_DMA_FLAG_HT); 
328
     bufferstatus_local |= LOW_EMPTY;
329
     if(AUDIO_Format == MONO)
330
     {
331
        AUDIO_Cpy_Mono();
332
     }
333
     else 
334
     {
335
        audio_buffer_fill |= LOW_EMPTY;
336
     }    
337
  }
338
}
339
340
341
/*******************************************************************************
342
* Function Name  : AUDIO_Cpy_Mono
343
* Description    : Copy Mono data to small buffer, set both Left+Right Channel 
344
*                  to samme value
345
* Input          : None
346
* Output         : None
347
* Return         : None
348
* Attention     : None
349
*******************************************************************************/
350
void AUDIO_Cpy_Mono(void)
351
{
352
    volatile uint16_t i;
353
    s16  temp;
354
    
355
    /* Stop if end of original buffer */
356
    if ( Audio_buffer_index > Audio_buffer_size )
357
        AUDIO_Playback_Stop();
358
    
359
    /* End of the first half working buffer  */
360
    if(bufferstatus_local & LOW_EMPTY)
361
    {
362
        if (AUDIO_Length == LG_16_BITS)
363
        {
364
            for( i=0 ; i < ((Audio_buffer_local_size / 4) - 1) ; i = i + 2 )
365
            {
366
                temp = *(s16*)(Audio_buffer+Audio_buffer_index);
367
                Audio_buffer_local[i+1] = Audio_buffer_local[i] = temp;
368
                Audio_buffer_index += 2;   /* 16 bit */
369
            }
370
        }
371
        else
372
        {
373
            for(i=0; i < ((Audio_buffer_local_size / 4)-1); i=i+2)
374
            {
375
                temp = ((s16)((*(Audio_buffer+Audio_buffer_index)^0x80)))<<8;
376
                Audio_buffer_local[i+1] = Audio_buffer_local[i] = temp;
377
                Audio_buffer_index++;      /* 8 bit */     
378
            }
379
        }
380
        bufferstatus_local &= ~LOW_EMPTY;
381
    }
382
383
    /* End of the second half working buffer */
384
    if(bufferstatus_local & HIGH_EMPTY)
385
    {
386
        if (AUDIO_Length == LG_16_BITS)
387
        {
388
            for( i = (Audio_buffer_local_size / 4) ; i < (Audio_buffer_local_size / 2 ); i = i + 2 )
389
            {
390
                temp = *(s16*)(Audio_buffer+Audio_buffer_index);
391
                Audio_buffer_local[i+1] = Audio_buffer_local[i] = temp;
392
                Audio_buffer_index += 2; /* 16 bit */
393
            }
394
        }
395
        else
396
        {
397
            for(i = (Audio_buffer_local_size / 4); i < ((Audio_buffer_local_size) / 2)-1; i=i+2)
398
            {
399
                temp = ((s16)((*(Audio_buffer+Audio_buffer_index)^0x80)))<<8;
400
                Audio_buffer_local[i+1] = Audio_buffer_local[i] = temp;
401
                Audio_buffer_index++;    /* 8 bit */     
402
            }
403
        }
404
        bufferstatus_local &= ~HIGH_EMPTY;
405
    }
406
    
407
    if ( Audio_buffer_index == (Audio_buffer_size/2) )
408
    {
409
        audio_buffer_fill |= LOW_EMPTY;
410
        if ( audio_buffer_fill & HIGH_EMPTY )         
411
        {
412
            AUDIO_Playback_Stop();
413
        }
414
    }
415
    if ( Audio_buffer_index >= Audio_buffer_size )
416
    {
417
        audio_buffer_fill |= HIGH_EMPTY;
418
        Audio_buffer_index = 0;
419
        if ( audio_buffer_fill & LOW_EMPTY )         
420
        {
421
            AUDIO_Playback_Stop();
422
        }
423
    }
424
}
425
426
427
/*******************************************************************************
428
* Function Name  : AUDIO_Init_audio_mode
429
* Description    : Initialization for Audio Mode use of the WM8731 codec.set WM8731
430
*                  to Audio Mode via I2C. enable STM32 I2S communication to send
431
*                  audio samples (SPI2/I2S2 port) in DMA mode
432
* Input          : - length: 8 bits or 16 bits length sample
433
*           - frequency:  8 KHz, 16 KHz, 22 KHz, 44 KHz, 48 KHz sample
434
*           - format: mono, stereo
435
* Output         : None
436
* Return         : None
437
* Attention     : None
438
*******************************************************************************/
439
void AUDIO_Init_audio_mode(AUDIO_Length_enum length, uint16_t frequency, AUDIO_Format_enum format)
440
{
441
   /* The MONO mode uses working buffer to dupplicate datas on the two channels
442
      and switch buffer half by half => uses DMA in circular mode */
443
  
444
   NVIC_InitTypeDef NVIC_InitStructure;
445
446
   StartPlay(frequency);
447
   /* DMA IRQ Channel configuration */
448
#if defined(AUDIO_MAL_DMA_IT_TC_EN) || defined(AUDIO_MAL_DMA_IT_HT_EN) || defined(AUDIO_MAL_DMA_IT_TE_EN)
449
  /* SAI DMA IRQ Channel configuration */
450
  NVIC_InitStructure.NVIC_IRQChannel = AUDIO_MAL_DMA_IRQ;
451
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = EVAL_AUDIO_IRQ_PREPRIO;
452
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = EVAL_AUDIO_IRQ_SUBRIO;
453
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
454
  NVIC_Init(&NVIC_InitStructure);
455
#endif 
456
  
457
   Audio_buffer_index = 0;
458
   AUDIO_Playback_status = NO_SOUND;
459
   AUDIO_Length = length;    
460
   AUDIO_Frequency = frequency;
461
   AUDIO_Format = format;
462
463
   /* Buffers are supposed to be empty here  */
464
   audio_buffer_fill = (AUDIO_PlaybackBuffer_Status) (LOW_EMPTY | HIGH_EMPTY );
465
   bufferstatus_local =  (AUDIO_PlaybackBuffer_Status) (LOW_EMPTY | HIGH_EMPTY );
466
   
467
   DMA_Configuration((s8 *)AudioBuffer,(mp3FrameInfo.outputSamps*2)); 
468
469
   printf( "-- MP3 file header information \r\n");
470
   printf( "-------------------------------- \r\n");
471
   printf( "-- MP3 bitrate        = %d\r\n", mp3FrameInfo.bitrate);     /* ±ÈÌØÂÊ */
472
   printf( "-- MP3 bitsPerSample  = %d\r\n", AUDIO_Length);
473
   printf( "-- MP3 samprate       = %d\r\n", AUDIO_Frequency);  
474
   printf( "-- MP3 nChans         = %d\r\n", AUDIO_Format);  
475
   printf( "-- MP3 nGranSamps     = %d\r\n", ((MP3DecInfo *)hMP3Decoder)->nGranSamps);
476
   /* Êý¾ÝÖ¡´óС FrameSize = (((MpegVersion == MPEG1 ? 144 : 72) * Bitrate) / SamplingRate) + PaddingBit */
477
   printf( "-- MP3 outputSamps    = %d\r\n", mp3FrameInfo.outputSamps);  
478
   printf( "-- MP3 layer          = %d\r\n", mp3FrameInfo.layer);
479
   printf( "-- MP3 version        = %d\r\n", mp3FrameInfo.version);
480
}

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

Sourcen kann man auch als Datei anhängen statt als Wall Of Text im 
Thread.

Ansonsten word wohl der Systemtakt zu gering sein.

von Peter (Gast)


Lesenswert?

Mw E. schrieb:
> Sourcen kann man auch als Datei anhängen statt als Wall Of Text im
> Thread.
>
Ja Richtuig sorry.

> Ansonsten word wohl der Systemtakt zu gering sein.

Der STM läuft mit 168MHz

von holger (Gast)


Lesenswert?

>Der STM läuft mit 168MHz

Hast du das gemessen oder glaubst du das?

Auch mal Optimierung beim Compiler aktivieren.

von Peter (Gast)


Lesenswert?

holger schrieb:
>>Der STM läuft mit 168MHz
>
> Hast du das gemessen oder glaubst du das?
> ja sonst würde der USB Teil nicht gehen


> Auch mal Optimierung beim Compiler aktivieren.
Hab ich

von Peter (Gast)


Lesenswert?

wo gibt es denn Beispiele für den
stm32f429 und WM8789

von Peter (Gast)


Angehängte Dateien:

Lesenswert?

Ich habs jetzt nochmal etwas umgeändert, es hört sich füchterlich an.

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

USB?
Ich denk das spielt von SD Karte?

Guck doch mal mit einem Oszi ob die LRCK zum DAC auch der Samplerate der 
MP3 entspricht.

von Peter (Gast)


Lesenswert?

Mw E. schrieb:
> USB?
> Ich denk das spielt von SD Karte?
>
Die MP3 wird von der sd Card gelesen, USB brauch ich nur um die Daten 
zwischen PC und STM auszutauschen.

> Guck doch mal mit einem Oszi ob die LRCK zum DAC auch der Samplerate der
> MP3 entspricht.
ein OZZI hab ich leider nicht

von Peter (Gast)


Angehängte Dateien:

Lesenswert?

wenn ich das example  von st nehme wo die mp3 als Array vorliegt dan 
wird das auch korrekt abgespielt siehe anhang

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

Dann kommen wohl die Daten zu langsam von der SD Karte.
Wie siehts denn aus wenn ersteinmal nur ein Array mit den MP3 Daten von 
der SD Karte füllst und dieses wie im Originalbeispiel abspielst?

Kannste mir mal noch in Worten erklären wie dein Code die Daten von der 
SD Karte ließt und dem MP3 decoder übergibt?

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Angehängte Dateien:

Lesenswert?

ich glaub ich seh dein Problem:
MP3FindSyncWord gibt nicht zurück wie lang der MP3 Frame ist und die 
Decode Funktion ließt dann wohl über den Buffer hinaus.
Zudem kann diese Funktion wohl auch mal "falsch feuern".

Also du musst die Datei von der SD Karte Byteweise einlesen bis der 
Header kommt und dann gucken wie lang der Frame ist und diesen ind en 
BUffer kopieren.

Das Problem hatte ich bei nem Uni Projekt auch mal, daher eiskalt diesen 
Headerfinder selber geschrieben.
Siehe Anhang.
1
char filebuff[0x400*1024];     //Framebuffer
2
unsigned int my_frame_size = 0;  //Ausgabe von headerfind
3
4
//auf MP3 Header syncen (<2 sagt ungültig; > filebuff ist eindeutig zu groß als Header -> Decodefehler)
5
my_frame_size = 0;
6
while ((my_frame_size < 2) || (my_frame_size > sizeof(filebuff)-10)){ 
7
    //jaja, Billig FIFO
8
  filebuff[0] = filebuff[1];
9
  filebuff[1] = filebuff[2];
10
  filebuff[2] = filebuff[3];   
11
  filebuff[3] = fgetc(file_fd);
12
  my_frame_size = mp3decode_findheader(filebuff);
13
}
14
15
//restlichen Frame nachladen (Offset von 4, den Header haben wir ja schon)
16
fread ((void*)&filebuff[4], sizeof(char), my_frame_size - 4, file_fd);
17
18
//In den Decoder kippen

: Bearbeitet durch User
von Peter (Gast)


Angehängte Dateien:

Lesenswert?

Hallo
ihren Tipp den bekomme ich nicht so einfach umgesetzt dazu fehlt mir 
vielleicht auch die Erfahrung.

Wenn ich nun die Textausgabe Weglasse dann wir das mp3 zu schnell 
ausgegeben .
zum zweiten ist immer so ein knacken drin

1
void AUDIO_Init_audio_mode(AUDIO_Length_enum length, uint16_t frequency, AUDIO_Format_enum format)
2
{
3
   /* The MONO mode uses working buffer to dupplicate datas on the two channels
4
      and switch buffer half by half => uses DMA in circular mode */
5
  
6
   NVIC_InitTypeDef NVIC_InitStructure;
7
8
   StartPlay(frequency);
9
   /* DMA IRQ Channel configuration */
10
#if defined(AUDIO_MAL_DMA_IT_TC_EN) || defined(AUDIO_MAL_DMA_IT_HT_EN) || defined(AUDIO_MAL_DMA_IT_TE_EN)
11
  /* SAI DMA IRQ Channel configuration */
12
  NVIC_InitStructure.NVIC_IRQChannel = AUDIO_MAL_DMA_IRQ;
13
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = EVAL_AUDIO_IRQ_PREPRIO;
14
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = EVAL_AUDIO_IRQ_SUBRIO;
15
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
16
  NVIC_Init(&NVIC_InitStructure);
17
#endif 
18
19
   Audio_buffer_index = 0;
20
   AUDIO_Playback_status = NO_SOUND;
21
   AUDIO_Length = length;    
22
   AUDIO_Frequency = frequency;
23
   AUDIO_Format = format;
24
25
   /* Buffers are supposed to be empty here*/   
26
   audio_buffer_fill = (AUDIO_PlaybackBuffer_Status) (LOW_EMPTY | HIGH_EMPTY );
27
   bufferstatus_local =  (AUDIO_PlaybackBuffer_Status) (LOW_EMPTY | HIGH_EMPTY );
28
   
29
   DMA_Configuration((s8 *)AudioBuffer,(mp3FrameInfo.outputSamps*2)); 
30
31
   DrawString(200,200,"-- MP3 file header information ",&Arial_16x25,Orange,BLACK);
32
33
   sprintf(read_write_buffer,"MP3 bitrate  %d",mp3FrameInfo.bitrate);
34
   DrawString(200,225,read_write_buffer,&Arial_16x25,Orange,BLACK);
35
   /*
36
   sprintf(read_write_buffer,"MP3 bitsPerSample %d",AUDIO_Length);
37
   DrawString(200,250,read_write_buffer,&Arial_16x25,Orange,BLACK);   
38
   
39
   sprintf(read_write_buffer,"MP3 samprate  %d",AUDIO_Frequency);
40
   DrawString(200,275,read_write_buffer,&Arial_16x25,Orange,BLACK);
41
42
   sprintf(read_write_buffer,"MP3 nChans  %d",AUDIO_Format);
43
   DrawString(200,300,read_write_buffer,&Arial_16x25,Orange,BLACK);
44
45
//   sprintf(read_write_buffer,"MP3 nGranSamps %d",(MP3DecInfo *)hMP3Decoder)->nGranSamps);
46
//   DrawString(200,300,read_write_buffer,&Arial_16x25,Orange,BLACK);
47
   
48
   sprintf(read_write_buffer,"MP3 outputSamps  %d",mp3FrameInfo.outputSamps);
49
   DrawString(200,325,read_write_buffer,&Arial_16x25,Orange,BLACK);   
50
   
51
   sprintf(read_write_buffer,"MP3 layer  %d",mp3FrameInfo.layer);
52
   DrawString(200,350,read_write_buffer,&Arial_16x25,Orange,BLACK);      
53
   
54
   sprintf(read_write_buffer,"MP3 version  %d",mp3FrameInfo.version);
55
   DrawString(200,375,read_write_buffer,&Arial_16x25,Orange,BLACK);   
56
  */
57
  
58
}

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

Also wenn dir etwas "Bytes in Buffer kopieren" schon zu viel ist, dann 
kann ich dir leider auch nicht wirklich weiterhelfen.

Ansonsten ist bei deinem Umbau wohl komplett die Synchronisation kaputt 
gegangen zwischen DMA zum I2S Anschluss und dem Buffer der Audioframes.

Wenn der DMA aus dem einen Audioframebuffer ließt, dann einen MP3 Frame 
dekodieren und in einen zweiten Audioframebuffer kippen.
Ist der DMA mit einem der AUdiobuffer fertig, dann umschalten und den 
nächstren MP3 Frame in den anderen Audioframebuffer kopieren.

: Bearbeitet durch User
von Peter (Gast)


Lesenswert?

Hallo,

Mw E. schrieb:
> Also wenn dir etwas "Bytes in Buffer kopieren" schon zu viel ist,
> dann
> kann ich dir leider auch nicht wirklich weiterhelfen.

nein das ist mir nicht zu viel,
meine Frage ist nur wie wird das in zwei buffer eingelesen und wie gross 
müssen die buffer sein




>
> Ansonsten ist bei deinem Umbau wohl komplett die Synchronisation kaputt
> gegangen zwischen DMA zum I2S Anschluss und dem Buffer der Audioframes.
>
> Wenn der DMA aus dem einen Audioframebuffer ließt, dann einen MP3 Frame
> dekodieren und in einen zweiten Audioframebuffer kippen.
> Ist der DMA mit einem der AUdiobuffer fertig, dann umschalten und den
> nächstren MP3 Frame in den anderen Audioframebuffer kopieren.

Gibt es denn irgendwo ein Beispiel, denn für meinen DAC hab ich nirgends 
ein Beispiel gefunden wie das gemacht wird.
mfg

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

Das funktionierende Beispiel haste doch schon? (mp3_audio_array.c)

Musst doch "nur" das Beispiel mit dem Abspielen aus dem Array so 
umbauen, dass der MP3Decoder die Daten von der SD Karte dekodiert.
Dazu habe ich dir sogar schon Code gegeben um die MP3 Frames und dessen 
Länge zu finden.

Du musst jetzt gucken wie dieses Beispiel die synchronisation mit dem 
DMA hinbekommt. ALso diesen Code mal selber reverse engineeren.
Es hilft übrigens ungemein dabei die gewonnen Kenntnisse 
nierderzuschreiben.
Dann merkt man ob man sich gedanklich verrant hat oder sich etwas 
widerspricht.
Sei es in Form von ausaführlichen KOmmentaren im Code oder hier im Forum 
als Beitrag.

von Peter (Gast)


Lesenswert?

Hallo,
so nun läufts einwandfrei.
in der Ruhe liegt die Kraft.

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

Woran lags denn?
Das dürfte zukünftige Leser hier interessieren.

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.