Part Number:LAUNCHXL-CC26X2R1Other Parts Discussed in Thread:CC3200, , CC2564C
想实现一个从sd卡读取音频数据后播放的功能
方案:
用Launchxl-cc26x2r1+cc3200 audio booster pack的方式实现音频播放,用一个自制的sd卡板作为音频文件的存储,以spi信号连接。
使用example里面的i2secho和fatsd的例子,在I2secho里面加入了fatsd里面sd卡读取部分的代码。
期望实现的是在i2secho流程的基础上,替换i2s的read过来的数据,就是在treatment那里,读取音频文件数据并替换相应的字节。
主要的代码实现:
;例子里面的i2s,spi,ti3254初始化,这里不再重复
/* Get the filesize of the source file */
fseek(src, 0, SEEK_END);
filesize = ftell(src);
rewind(src);
uint32_t file_index = 0;
/* Treatment */
while(1){
/* Wait for transaction ready for treatment */
retc = sem_wait(&semDataReadyForTreatment);
if (retc == -1) {
while (1);
}
I2S_Transaction* transactionToTreat = (I2S_Transaction*) List_head(&treatmentList);
if(transactionToTreat != NULL){
/*
* Treatment:
* The higher the sampling frequency,
* the less time we have to process the data
*/
#if SAMPLE_RATE > 16000
int16_t *buf = transactionToTreat->bufPtr;
/* bufSize is expressed in bytes but samples to consider are 16 bits long */
uint16_t numOfbytes = transactionToTreat->bufSize;
if(file_index+numOfbytes<=filesize)
{
bytesRead = fread((uint8_t*)buf, 1, numOfbytes, src);
file_index += bytesRead;
if(file_index>=filesize)
{
file_index = 0;
rewind(src);
}
}
else
{
bytesRead = fread((uint8_t*)buf, 1, filesize-file_index, src);
rewind(src);
bytesRead = fread((uint8_t*)(buf+filesize-file_index), 1, numOfbytes+file_index-filesize, src);
file_index = bytesRead;
}
#elif SAMPLE_RATE > 8000
/* Data processing */
int16_t *buf = transactionToTreat->bufPtr;
/* bufSize is expressed in bytes but samples to consider are 16 bits long */
uint16_t numOfSamples = transactionToTreat->bufSize / sizeof(uint16_t);
uint16_t n;
for(n=0; n<numOfSamples-3; n=n+2) {
buf[n] = (buf[n] + buf[n+2]) / 2;
buf[n+1] = (buf[n+1] + buf[n+3]) / 2;
}
#else
#endif
/* Place in the write-list the transaction we just treated */
List_remove(&treatmentList, (List_Elem*)transactionToTreat);
List_put(&i2sWriteList, (List_Elem*)transactionToTreat);
}
}
这里SAMPLE_RATE 选的是44100
问题:
一旦在循环中使用fread进行文件读取,不管是将数据读取到buf中,还是读取到一个单独开出来的缓存中(即不去替换buf中的内容),都会造成程序不再进while的循环,
i2s的readCallbackFxn也不会再有数据。
在fread处打断点时,可以看到成功读到数据,确定sd卡功能正常,但是连续运行后,整个while循环都不会再进,此时暂停程序,似乎是进入到了deepsleep
不知道问题出在哪里。或者具体应该以什么方式实现这样的功能。
其实刚开始是想在我们原有的一个基于simple_peripheral的程序里面添加一个类似的功能的,当时是创建了两个task,一个task里面有一部分是初始化sd卡的以及一些其他功能,一个task和i2secho类似,初始化i2s,ti3254,然后在while循环里等待特定的event,出现了类似的问题。所以才用上述方式进行实验,发现还是同样的现象。
Kevin Qiu1:
播放音乐看起来使用经典蓝牙会是更好的选择
这里有一个audio插件,里面提供了一些示例,你也可以参考一下:https://www.ti2k.com/wp-content/uploads/ti2k/DeyiSupport_otherwireless_node
,
Yu Kang:
感谢回复,我参考下例子试试,有结果了会及时发出来。
关于在cc26x2方案上做音频播放的方案,整体上我打算做两个尝试:
一个是音频流从sd卡直接输出到audio codec芯片(就是现在正在试的功能),BLE通道只是进行控制指令的发送。
另一个就是您提到的,我打算也用音频流走BLE通道进行。目前看cc26x2的BLE5.0的速度还是可以的,实测能到30KB左右,传音频流的基础码率条件感觉还是具备的。只是只能做自定义的数据流了。
期待TI什么时候能发布LE Audio的支持
,
Kevin Qiu1:
你可以先用插件的程序试一下,TI目前还有支持LE audio
传输音频也可以使用双模蓝牙CC2564C
,
Yu Kang:
首先对于我们计划做的功能,需要不少GPIO和其他对外访问端口,目前已经在CC2642上完成了主体功能,因为近期想加一个音频播放的功能,本着硬件成本的考虑,想先尝下能否在当前基础上只做少量的硬件修改,在软件上花点精力评估下。
接着说下插件的尝试结果,在插件中示例audiohal_echo的基础上,也同样加上了sd卡访问的部分,流程和提问时的方案一样,也是在原有的事件触发的接收,发送数据流程中插入读取SD卡上面的音频数据文件,替换当前的数据流。
尝试的结果:
首先,功能上可以正常执行,不会像之前那样跑飞。
出现的新问题:
能听出来是sd上的所保存的音乐,但是有非常多的杂音。我保存的音乐数据是用ffmpeg转换出来的PCM数据(16KHz, stere 16-bit little-endian),并且用audacity验证了PCM数据的音乐是正确的。示例里面设置的SAMPLE_RATE同样也是16KHz。不清楚是哪里的问题导致的杂音。
另外,插件目前是否只能配合simplelink_cc13x2_26x2_sdk_3_30_00_03使用,更高的sdk版本下如何兼容使用(我们的主体程序是在simplelink_cc13x2_26x2_sdk_4_40_04_04下实现的)。
使用插件进行本问题测试的主体部分代码:
int16_t audioIn[NUM_CHAN][FRAME_SIZE];int16_t buf[FRAME_SIZE][NUM_CHAN];
;SD访问初始化以及打开PCM文件
;示例中的AudioHal的初始化和打开
while(1) { events = Event_pend((Event_Object *)loopbackEvent, Event_Id_NONE, AUDIO_FRAME_EVENT + AUDIO_EVENT, BIOS_WAIT_FOREVER);
if(events) { if(events & AUDIO_FRAME_EVENT) { /* Get a frame from the input buffers */ AudioHAL_readBufGet(tlv320Handle, (void *)audioIn); bytesRead = fread((uint8_t*)buf, 2, bufsize, src); int i,j; if(bytesRead) { for (i=0;i<NUM_CHAN;i++) { for(j=0;j<FRAME_SIZE;j++) {
audioIn[i][j] = buf[j][i]; } } } /* Do application specific processing here */
/* Place decoded buffer in the output */ AudioHAL_writeBufPut(tlv320Handle, (void *)audioIn); } }
}
,
Yu Kang:
音乐测试正常了,双声道时,替换缓存数据时弄错了。
,
Kevin Qiu1:
插件是基于旧版本SDK,新SDK需要自己移植一下
,
Yu Kang:
好的,感谢
,
Kevin Qiu1:
不客气,如有其他问题,请重开一个新帖