mmlyy2012 发表于 2024-4-2 13:49:55

STemWin提高篇实验_WAV,MP3软解播放器,带类似千千静听频谱(FreeRTOS)

硬汉老师好:

       我正在看你的《STemWin提高篇实验_WAV,MP3软解播放器,带类似千千静听频谱(FreeRTOS)》。有几点没看明白,请指导一下:
1、点击左上角的图标后进入到App_MusicList();程序中,在窗口中会列出目录下的歌曲名等信息。选择歌曲后点击确定按键。        WM_SendMessageNoPara(hWinMusic, MSG_MusicStart);
会给父窗体发送消息。父窗体收到消息后:
                /*开始执行音乐播放 */
                case MSG_MusicStart:
                        hItem = WM_GetDialogItem(hWinMusicList, GUI_ID_LISTVIEW0);
                        MusicPlayNum = LISTVIEW_GetSel(hItem);
                        LISTVIEW_GetItemText(hItem, 0, MusicPlayNum, buf, MusicPathSzie);
                        _cbMusicButton(pMsg, MusicPlayNum, buf);                                       
                        break;
然后调用_cbMusicButton(pMsg, MusicPlayNum, buf);子程序发送消息       


        /* 发消息,播放新歌 */

        if(xQueueSend(xQueue,
                                   (void *)&pMusicMsg,
                                   (TickType_t)portMAX_DELAY) == pdPASS)
        {
                /* 根据按钮按下或者播放的状态发送消息 */
                if(s_ucPlayStatus == 1)
                {
                        xEventGroupSetBits(xCreatedEventGroup, MusicTaskAudioPlay_5);                                       
                }
                else
                {
                        xEventGroupSetBits(xCreatedEventGroup, MusicTaskAudioStart_8);                               
                }
给main中的void vTaskMusic(void *pvParameters)任务,

        /* 接受数据,播放MP3文件或者WAV文件 */
                xResult = xQueueReceive(xQueue,                  /* 消息队列句柄 */
                                        (void *)&pMsg,                   /* 这里获取的是结构体的地址 */
                                        (TickType_t)portMAX_DELAY);/* 设置阻塞时间 */
                if( xResult == pdPASS )            
                {
                        /* DMA禁止后要等到当前转换完毕才可以停止,所以这里需要清除相应标志 */
                        xEventGroupWaitBits(xCreatedEventGroup, /* 事件标志组句柄 */
                                                          MusicTaskWaitFlag,/* 等待MusicTaskWaitFlag某位被设置 */
                                                          pdTRUE,             /* 退出前MusicTaskWaitFlag被清除,这里是任意MusicTaskWaitFlag位被设置就“退出”*/
                                                          pdFALSE,            /* 设置为pdFALSE表示等待MusicTaskWaitFlag任意位被设置*/
                                                          0);                                /* 等待延迟时间 */               
                        if(pMsg->ucType == MusicType_WAV)
                        {
                                WavMusicPlay((const char *)pMsg->ucName);                                       
                        }
                        else if(pMsg->ucType == MusicType_MP3)
                        {
                                MP3MusicPlay((const char *)pMsg->ucName);               
                        }
                }       
    }

根据接收到的消息及事件标志组的某位被置为1然后去歌曲播放程序void WavMusicPlay(const char *filename)中进行相应的动作。
                /* 等待所有任务发来事件标志 */
                uxBits = xEventGroupWaitBits(xCreatedEventGroup, /* 事件标志组句柄 */
                                                                 0xFFFE,                      /* 等待0xFFFE某一位被设置 */
                                                                 pdTRUE,             /* 退出前0xFFFE位被清除,这里是任意0xFFFE位被设置就“退出”*/
                                                                 pdFALSE,            /* 设置为pdTRUE表示等待0xFFFE任意位被设置*/
                                                                 portMAX_DELAY);        /* 等待延迟时间 */



先执行:                        /* 开始播放 */
                        case MusicTaskAudioPlay_5:
然后在根据DMA中断程序void PLAY_DMA_IRQHandler(void)中的
                        xResult = xEventGroupSetBitsFromISR(xCreatedEventGroup, /* 事件标志组句柄 */
                                                                          0x0400,            /* 设置bit1 */
                                                                          &xHigherPriorityTaskWoken );
或者                        /* 当前使用的是缓存 0 */
                        xResult = xEventGroupSetBitsFromISR(xCreatedEventGroup, /* 事件标志组句柄 */
                                                                          0x0200,            /* 设置bit1 */
                                                                          &xHigherPriorityTaskWoken );
去置位相应的事件标志组的相应位。然后在void WavMusicPlay(const char *filename)执行:

                        /* 当前使用的是缓冲0,填充缓冲1 */
                        case MusicTaskAudioFillBuffer1_9:

或者
                        /* 当前使用的是缓冲1,填充缓冲0 */
                        case MusicTaskAudioFillBuffer0_10:

进行歌曲播放。
我移植了你的程序,现在是可以进行到void WavMusicPlay(const char *filename)的
case MusicTaskAudioPlay_5:或者case MusicTaskAudioStart_8:去运行。DMA中断程序void PLAY_DMA_IRQHandler(void)中的
                        xResult = xEventGroupSetBitsFromISR(xCreatedEventGroup, /* 事件标志组句柄 */
                                                                          0x0400,            /* 设置bit1 */
                                                                          &xHigherPriorityTaskWoken );
或者                        /* 当前使用的是缓存 0 */
                        xResult = xEventGroupSetBitsFromISR(xCreatedEventGroup, /* 事件标志组句柄 */
                                                                          0x0200,            /* 设置bit1 */
                                                                          &xHigherPriorityTaskWoken );
标志位也进行了相应的置位。但是就是执行不到void WavMusicPlay(const char *filename)中:

                        /* 当前使用的是缓冲0,填充缓冲1 */
                        case MusicTaskAudioFillBuffer1_9:

或者

                        /* 当前使用的是缓冲1,填充缓冲0 */
                        case MusicTaskAudioFillBuffer0_10:

。我分析原因是因为虽然置位了MusicTaskAudioFillBuffer1_9:或者MusicTaskAudioFillBuffer0_10:
但是在main中的void vTaskMusic(void *pvParameters)任务

        /* 接受数据,播放MP3文件或者WAV文件 */
                xResult = xQueueReceive(xQueue,                  /* 消息队列句柄 */
                                        (void *)&pMsg,                   /* 这里获取的是结构体的地址 */
                                        (TickType_t)portMAX_DELAY);/* 设置阻塞时间 */

接收不到发送的消息了,所以就在这一直等信息了。

串口助手收到的消息为:

WM_NOTIFY_PARENT_ID_BUTTON_10
_cbMusicButton:0:/Music/1.3高峰候车.wav
s_ucPlayStatus = 0
MusicTaskAudioStart_8//已经进入WavMusicPlay
wavx->audioformat:1
wavx->nchannels:2
wavx->samplerate:44100
wavx->bitrate:1411200
wavx->blockalign:4
wavx->bps:16
wavx->datasize:2865308
wavx->datastart:44       //WAV歌曲信息
__HAL_DMA_CLEAR_FLAG //清DMA中断标志
AudioFillBuffer1         // 填充缓存 1
xResult is pdTURE       //消息被成功发出               
__HAL_DMA_CLEAR_FLAG//清DMA中断标志
AudioFillBuffer0         // 填充缓存 0
xResult is pdTURE      //消息被成功发出
__HAL_DMA_CLEAR_FLAG //清DMA中断标志
AudioFillBuffer1         // 填充缓存 1
xResult is pdTURE       //消息被成功发出               
__HAL_DMA_CLEAR_FLAG//清DMA中断标志
AudioFillBuffer0         // 填充缓存 0
xResult is pdTURE      //消息被成功发出
。。。。。。





请问我分析的过程是否有问题。如有问题,请帮忙指出。另外歌曲不能播放的错误请问怎么解决?已经困在这里好几天了。谢谢。




































eric2013 发表于 2024-4-2 14:43:10

估计是没有移植好。

mmlyy2012 发表于 2024-4-2 14:54:21

eric2013 发表于 2024-4-2 14:43
估计是没有移植好。

已经找到问题了,解决了。谢谢
页: [1]
查看完整版本: STemWin提高篇实验_WAV,MP3软解播放器,带类似千千静听频谱(FreeRTOS)