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);    }}




原创粉丝点击