硬汉老师好:
我正在看你的《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 //消息被成功发出
。。。。。。
请问我分析的过程是否有问题。如有问题,请帮忙指出。另外歌曲不能播放的错误请问怎么解决?已经困在这里好几天了。谢谢。
|