TI—CC3200【2】通过UDP传输音频
来源:互联网 发布:入侵网站修改数据 编辑:程序博客网 时间:2024/06/05 15:45
手上有一套TICC3200+TLV320AIC3254开发板,这个是TI官方出的一款评估板。
在官方给出的例程里面只有一个是关于音频的“wifi_audio_app”,这个例子使用两块开发板相互连接后相互传输音频并且播放的。
现在我手上只有一块开发板,而且对TI的片子还不是很熟悉,现在我想在这个例子上面做一个修改,修改为:用这个开发板采集音频,然后通过UDP上传至电脑,在电脑上使用网络助手接收开发板上传的音频。
这个程序的大概流程是:初始化(硬件初始化、引脚配置初始化、串口初始化、I2C接口初始化、创建接收和播放音频的缓冲区、初始化和配置音频芯片、初始化I2S、初始化DMA)、开始simplelink、创建网络任务、创建控制任务、创建录音任务、创建放音任务。
放音的任务暂时不用的,将其屏蔽。
【折腾了很长时间后才发现】在控制任务里面其实就是改变一些标志位,从而达到在实时的时间播放或者录音的目的,故而将这个任务也屏蔽掉。
在网络任务里面,首先是尝试自动连接网络,如果链接不上就使用智能配置链接网络。网络链接上之后是创建UDP服务器,然后执行“mDNS_Task();”任务。但是在测试的时候,程序在这个里面会报错,暂时不知道这个任务是干嘛用的,就直接注释掉了。注释掉之后发现每当链接网络成功并且创建UDP服务器成功之后,整个程序就停止了,后来又发现,这个网络任务必须要有个while(1)循环,否则整个程序会停止,然后将“mDNS_Task();”里面的代码修改成:
//*****************************************************************************////! mDNS_Task function//!//! \param None//!//! \return None//!//*****************************************************************************void mDNS_Task(){ int lRetValmDNS; unsigned int pAddr; unsigned long usPort; unsigned short ulTextLen = 200; char cText[201]; //UnRegister mDNS Service if done Previously lRetValmDNS = sl_NetAppMDNSUnRegisterService((signed char *)CC3200_MDNS_NAME, strlen(CC3200_MDNS_NAME)); while(1) { /* lRetValmDNS = 1; //Read mDNS service. while(lRetValmDNS) { ulTextLen = 200; lRetValmDNS = sl_NetAppDnsGetHostByService((signed char *) \ CC3200_MDNS_NAME, strlen((const char *)CC3200_MDNS_NAME), SL_AF_INET,(unsigned long *)&pAddr,&usPort, &ulTextLen,(signed char *)&cText[0]); UART_PRINT("mDNS service return : %d \n\r",lRetValmDNS); } if(lRetValmDNS == 0 && (pAddr!=INVALID_CLIENT_ADDRESS) && \ (pAddr!=g_uiIpAddress)) { //Speaker Detected - Add Client g_UdpSock.Client.sin_family = AF_INET; g_UdpSock.Client.sin_addr.s_addr = htonl(pAddr); g_UdpSock.Client.sin_port = htons(usPort); g_UdpSock.iClientLength = sizeof(g_UdpSock.Client); g_loopback = 0; } */ MAP_UtilsDelay(80*1000*100); } }即,在这个任务里面做一个空的while循环,只是延时,没有做其它的事情。
这样,网络这边算是解决了,接下来是录音那个任务。
在录音那个任务里面的基本流程是,在while循环里面一直判断几个标志位,一旦这个标志位置位后,就会将录得音频上传。但是在实际测试的时候发现,开机后立马就上传,当然上传UDP会报错,【这里折腾了很长时间】最后发现,UDP的socket是在网络任务中网络连接上之后建立的,但是录音是其它的一个任务,开机后一旦开始任务调度,这两个任务就同时开始运行了,是因为网络还没有连接上并且UDP还没有建立,但是录音的任务已经开始发送录音了,所以发送失败。那么解决办法是,在等着网络链接上并且UDP的socket建立之后再把录音的标志位置位,再开始上传音频,这样就成功了。
主函数代码:
//******************************************************************************// MAIN FUNCTION//******************************************************************************int main(){ long lRetVal = -1; unsigned charRecordPlay; BoardInit(); // // Pinmux Configuration // PinMuxConfig(); // // Initialising the UART terminal // InitTerm(); // // Initialising the I2C Interface // I2C接口初始化: lRetVal = I2C_IF_Open(1); if(lRetVal < 0) { ERR_PRINT(lRetVal); LOOP_FOREVER(); } RecordPlay = I2S_MODE_RX_TX; g_loopback = 0; UART_PRINT("Initialising the I2C Interface finish\n\r"); // // Create RX and TX Buffer // if(RecordPlay == I2S_MODE_RX_TX) {//创建录音缓冲区: pRecordBuffer = CreateCircularBuffer(RECORD_BUFFER_SIZE); if(pRecordBuffer == NULL) { UART_PRINT("Unable to Allocate Memory for Tx Buffer\n\r"); LOOP_FOREVER(); } } UART_PRINT("Create the Record Buffer finish\n\r"); /* Play */ if(RecordPlay & I2S_MODE_TX) {//创建放音缓冲区: pPlayBuffer = CreateCircularBuffer(PLAY_BUFFER_SIZE); if(pPlayBuffer == NULL) { UART_PRINT("Unable to Allocate Memory for Rx Buffer\n\r"); LOOP_FOREVER(); } } UART_PRINT("Create the Play Buffer finish\n\r"); //配置音频芯片的寄存器: // Configure Audio Codec // 配置音频芯片: AudioCodecReset(AUDIO_CODEC_TI_3254, NULL); AudioCodecConfig(AUDIO_CODEC_TI_3254, AUDIO_CODEC_16_BIT, 16000, AUDIO_CODEC_STEREO, AUDIO_CODEC_SPEAKER_ALL, AUDIO_CODEC_MIC_ALL); UART_PRINT("Configure Audio Codec finish\n\r"); //调整喇叭和耳机的放音音量: AudioCodecSpeakerVolCtrl(AUDIO_CODEC_TI_3254, AUDIO_CODEC_SPEAKER_ALL, 50); AudioCodecMicVolCtrl(AUDIO_CODEC_TI_3254, AUDIO_CODEC_SPEAKER_ALL, 50); GPIO_IF_LedConfigure(LED2|LED3); GPIO_IF_LedOff(MCU_RED_LED_GPIO); GPIO_IF_LedOff(MCU_GREEN_LED_GPIO); // // Configure PIN_01 for GPIOOutput // //MAP_PinTypeGPIO(PIN_01, PIN_MODE_0, false); // MAP_GPIODirModeSet(GPIOA1_BASE, 0x4, GPIO_DIR_MODE_OUT); // // Configure PIN_02 for GPIOOutput // //MAP_PinTypeGPIO(PIN_02, PIN_MODE_0, false); // MAP_GPIODirModeSet(GPIOA1_BASE, 0x8, GPIO_DIR_MODE_OUT); //Turning off Green,Orange LED after i2c writes completed - First Time GPIO_IF_LedOff(MCU_GREEN_LED_GPIO); GPIO_IF_LedOff(MCU_ORANGE_LED_GPIO); // // Initialize the Audio(I2S) Module // 初始化I2S AudioInit(); UART_PRINT("Initialize the Audio(I2S) Module finish\n\r"); // // Initialize the DMA Module // 初始化DMA UDMAInit(); if(RecordPlay & I2S_MODE_TX) { UDMAChannelSelect(UDMA_CH5_I2S_TX, NULL); SetupPingPongDMATransferRx(pPlayBuffer); } if(RecordPlay == I2S_MODE_RX_TX) { UDMAChannelSelect(UDMA_CH4_I2S_RX, NULL); SetupPingPongDMATransferTx(pRecordBuffer); } UART_PRINT("Initialize the DMA Module finish\n\r"); // // Setup the Audio In/Out // lRetVal = AudioSetupDMAMode(DMAPingPongCompleteAppCB_opt, \ CB_EVENT_CONFIG_SZ, RecordPlay); if(lRetVal < 0) { ERR_PRINT(lRetVal); LOOP_FOREVER(); } AudioCaptureRendererConfigure(AUDIO_CODEC_16_BIT, 16000, AUDIO_CODEC_STEREO, RecordPlay, 1); UART_PRINT("Setup the Audio In/Out finish\n\r"); // // Start Audio Tx/Rx // Audio_Start(RecordPlay); UART_PRINT("Start Audio Tx/Rx finish\n\r"); // // Start the simplelink thread // lRetVal = VStartSimpleLinkSpawnTask(9); if(lRetVal < 0) { ERR_PRINT(lRetVal); LOOP_FOREVER(); } UART_PRINT("Start the simplelink thread finish\n\r"); // // Start the Network Task // lRetVal = osi_TaskCreate( Network, (signed char*)"NetworkTask",\ OSI_STACK_SIZE, NULL, 1, &g_NetworkTask ); if(lRetVal < 0) { ERR_PRINT(lRetVal); LOOP_FOREVER(); } UART_PRINT("Start the Network Task finished .\n\r"); // // Start the Control Task // /* UART_PRINT("Start the Control Task .\n\r"); lRetVal = ControlTaskCreate(); if(lRetVal < 0) { ERR_PRINT(lRetVal); LOOP_FOREVER(); } UART_PRINT("Start the Control Task finish .\n\r");*/ // // Start the Microphone Task // UART_PRINT("Start the Microphone Task .\n\r"); lRetVal = osi_TaskCreate( Microphone,(signed char*)"MicroPhone", \ OSI_STACK_SIZE, NULL, 1, &g_MicTask ); if(lRetVal < 0) { ERR_PRINT(lRetVal); LOOP_FOREVER(); } // // Start the Speaker Task //// lRetVal = osi_TaskCreate( Speaker, (signed char*)"Speaker",OSI_STACK_SIZE, \ NULL, 1, &g_SpeakerTask );// if(lRetVal < 0)// {// ERR_PRINT(lRetVal);// LOOP_FOREVER();// } // // Start the task scheduler // osi_start(); }
网络任务的代码:
//*****************************************************************************////! Network Task//!//! \param pvParameters - Parameters to the task's entry function//!//! \return None//!//*****************************************************************************void Network( void *pvParameters ){ long lRetVal = -1; char Buffer_test[10]={1,2,3,4,5,6,7,8,9,0}; //Initialize Global Variable //初始化全局变量: InitializeAppVariables(); //Connect to Network //链接到网络: lRetVal = ConnectToNetwork(); if(lRetVal < 0) { UART_PRINT("Failed to establish connection w/ an AP \n\r"); LOOP_FOREVER(); } UART_PRINT("The device connect success .\n\r"); //程序自带的UDP链接,暂时将其屏蔽,使用TCP链接测试. UART_PRINT("Start create UDP Socket and Bind to Local IP Address :\n\r"); //Create UDP Socket and Bind to Local IP Address lRetVal = CreateUdpServer(&g_UdpSock); if(lRetVal < 0) { UART_PRINT("Failed to Create UDP Server \n\r"); LOOP_FOREVER(); } UART_PRINT("Create UDP Server finished .\n\r"); //自己添加 g_loopback = 1; /* //测试UDP链接是否可用的代码。 while(1) { lRetVal = sendto(g_UdpSock.iSockDesc, \ Buffer_test,10,\ 0,(struct sockaddr*)&(g_UdpSock.Client),\ sizeof(g_UdpSock.Client)); if(lRetVal < 0) { UART_PRINT("Unable to send data\n\r"); LOOP_FOREVER(); } } */ /* //创建TCP客户端: lRetVal = CreateTcpClient(PORT_NUM); if(lRetVal < 0) { UART_PRINT("TCP Client failed\n\r"); LOOP_FOREVER(); } */#ifdef MULTICAST //Add to Multicast Group lRetVal = ReceiveMulticastPacket(); if(lRetVal < 0) { UART_PRINT("Failed to Create UDP Server \n\r"); LOOP_FOREVER(); } //Delete the Networking Task as Service Discovery is not needed osi_TaskDelete(&g_NetworkTask);#else //Discover CC3200 Audio Devices UART_PRINT("Start discover CC3200 Audio Devices : \n\r"); mDNS_Task();#endif }
//*****************************************************************************////! Microphone Routine //!//! \param pvParameters Parameters to the task's entry function//!//! \return None////*****************************************************************************extern int iSockID;void Microphone( void *pvParameters ){ long lRetVal = -1; char Buffer_test[10]={1,2,3,4,5,6,7,8,9,0}; // int iStatus;#ifdef MULTICAST //Wait for Network Connection while((!IS_IP_ACQUIRED(g_ulStatus))) { }#endif //MULTICAST UART_PRINT("g_ucMicStartFlag value is : %d .\n\r",g_ucMicStartFlag);// UART_PRINT("sleeping...... .\n\r");// osi_Sleep(5000);// UART_PRINT("sleeping...... .\n\r");// osi_Sleep(5000);// UART_PRINT("sleeping...... .\n\r");// osi_Sleep(5000);// UART_PRINT("sleeping...... .\n\r");// osi_Sleep(5000);// UART_PRINT("sleeping...... .\n\r");// osi_Sleep(5000);// UART_PRINT("sleeping...... .\n\r"); while(1) { //UART_PRINT("g_ucMicStartFlag value is : %d .\n\r",g_ucMicStartFlag); //UART_PRINT("g_loopback value is : %d .\n\r",g_loopback); while(g_ucMicStartFlag || g_loopback) { int iBufferFilled = 0; iBufferFilled = GetBufferSize(pRecordBuffer); // UART_PRINT("iBufferFilled value is : %d .\n\r",iBufferFilled); if(iBufferFilled >= (2*PACKET_SIZE)) { UART_PRINT("iBufferFilled value is : %d .\n\r",iBufferFilled); UART_PRINT("g_loopback value is : %d .\n\r",g_loopback); // if(!g_loopback) // {#ifndef MULTICAST lRetVal = sendto(g_UdpSock.iSockDesc, \ (char*)(pRecordBuffer->pucReadPtr),PACKET_SIZE,\ 0,(struct sockaddr*)&(g_UdpSock.Client),\ sizeof(g_UdpSock.Client)); // lRetVal = sendto(g_UdpSock.iSockDesc, \ // Buffer_test,10,\ // 0,(struct sockaddr*)&(g_UdpSock.Client),\ // sizeof(g_UdpSock.Client)); if(lRetVal < 0) { UART_PRINT("Unable to send data\n\r"); LOOP_FOREVER(); } //通过TCP发送音频数据: //iStatus = sl_Send(iSockID, (char*)(pRecordBuffer->pucReadPtr), PACKET_SIZE, 0 ); //if( iStatus < 0 ) //{ // error // sl_Close(iSockID); //ASSERT_ON_ERROR(-0x7D0-6); // UART_PRINT("TCP send error . \n\r"); //} UART_PRINT("send voice data . \n\r");#else//MULTICAST lRetVal = SendMulticastPacket(); if(lRetVal < 0) { UART_PRINT("Unable to send data\n\r"); LOOP_FOREVER(); }#endif //MULTICAST // } // else // { // lRetVal = FillBuffer(pPlayBuffer,\ // (unsigned char*)(pRecordBuffer->pucReadPtr), \ // PACKET_SIZE); // if(lRetVal < 0) // { // UART_PRINT("Unable to fill buffer\n\r"); // } // g_iReceiveCount++; // } UpdateReadPtr(pRecordBuffer, PACKET_SIZE); g_iSentCount++; } } MAP_UtilsDelay(1000); }}
- TI—CC3200【2】通过UDP传输音频
- TI—CC3200【6】通过功放芯片的使能引脚消去POPO声
- TI—CC3200【3】TLV320AIC3254调节MIC录音增益
- TI—CC3200【7】引脚模式的配置
- CC3200 TI RTOS LPDS模式
- CC3200-UDP-Client
- TI CC3200 SDK开发详解——SDK目录结构详解
- TI CC3200 SDK开发详解——SDK目录结构详解
- TI—CC3200【1】独特的一步式WI-FI智能配置技术-SmartConfig测试
- TI—CC3200【4】MIC录音将立体声录音改为单声道录音
- TI—CC3200【5】关于TLV320AIC3254的hp和lo输出“沙沙”声的问题
- TI CC3200 IAR 开发环境搭建
- TI CC3200实现TCP/IP通信之一
- TI CC3200 IAR 开发环境搭建
- TI CC3200实现TCP/IP通信之一
- TI CC3200 IAR 开发环境搭建
- 黑马程序员——自学笔记15(网络传输2—UDP传输和TCP传输)
- 支付宝中当面付的通过音频传输数据的研究-实现部分(2)
- 获取gradle.properties中的值
- 一起学Java_面向对象(5)
- 极角排序详解
- centos下maven安装以及问题解决
- Kali下利用XAMPP搭建DVWA及使用command injection
- TI—CC3200【2】通过UDP传输音频
- HelloWorld
- mysql中什么数据类型可以存储路径
- 将数字转为中文金额的大写方式(C++版)
- mybatis的foreach
- static_cast, dynamic_cast, reinterpret_cast, const_cast区别比较
- java实现三个线程A B C,A线程打印A之后才能B线程打印B,然后接着C线程执行打印C,继而循环下去
- string的实现
- java文件上传下载