TI—CC3200【2】通过UDP传输音频

    手上有一套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 char	RecordPlay;

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




猜你喜欢

转载自blog.csdn.net/fang_yang_wa/article/details/76087689