TI—CC3200【2】通過UDP傳輸音訊
手上有一套TICC3200+TLV320AIC3254開發板,這個是TI官方出的一款評估板。
在官方給出的例程裡面只有一個是關於音訊的“wifi_audio_app”,這個例子使用兩塊開發板相互連線後相互傳輸音訊並且播放的。
現在我手上只有一塊開發板,而且對TI的片子還不是很熟悉,現在我想在這個例子上面做一個修改,修改為:用這個開發板採集音訊,然後通過UDP上傳至電腦,在電腦上使用網路助手接收開發板上傳的音訊。
這個程式的大概流程是:初始化(硬體初始化、引腳配置初始化、串列埠初始化、I2C介面初始化、建立接收和播放音訊的緩衝區、初始化和配置音訊晶片、初始化I2S、初始化DMA)、開始simplelink、建立網路任務、建立控制任務、建立錄音任務、建立放音任務。
放音的任務暫時不用的,將其遮蔽。
【折騰了很長時間後才發現】在控制任務裡面其實就是改變一些標誌位,從而達到在實時的時間播放或者錄音的目的,故而將這個任務也遮蔽掉。
在網路任務裡面,首先是嘗試自動連線網路,如果連結不上就使用智慧配置連結網路。網路連結上之後是建立UDP伺服器,然後執行“mDNS_Task();”任務。但是在測試的時候,程式在這個裡面會報錯,暫時不知道這個任務是幹嘛用的,就直接註釋掉了。註釋掉之後發現每當連結網路成功並且建立UDP伺服器成功之後,整個程式就停止了,後來又發現,這個網路任務必須要有個while(1)迴圈,否則整個程式會停止,然後將“mDNS_Task();
即,在這個任務裡面做一個空的while迴圈,只是延時,沒有做其它的事情。//***************************************************************************** // //! 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迴圈裡面一直判斷幾個標誌位,一旦這個標誌位置位後,就會將錄得音訊上傳。但是在實際測試的時候發現,開機後立馬就上傳,當然上傳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);
}
}
相關推薦
TI—CC3200【2】通過UDP傳輸音訊
手上有一套TICC3200+TLV320AIC3254開發板,這個是TI官方出的一款評估板。 在官方給出的例程裡面只有一個是關於音訊的“wifi_audio_app”,這個例子使用兩塊開發板相互連線後相互傳輸音訊並且播放的。 現在我手上只有一塊開發板
Microsoft Azure Web Sites應用與實踐【2】—— 通過本地IIS 遠端管理Microsoft Azure Web Site
Microsoft Azure Web Sites應用與實踐 系列: 通過本地IIS 遠端管理Microsoft Azure Web Site 在上一篇博文中,我們介紹了Microsoft Azure Web Site的快速生成。假如您之前有接觸或使用過IIS ,相信您會記得它簡潔方便的管
TI—CC3200【5】關於TLV320AIC3254的hp和lo輸出“沙沙”聲的問題
使用ti官方的開發板CC3200+TLV32AIC3254錄放音,錄音是很正常的,但是在放音的時候喇叭有很大的“沙沙”聲音。 只要配置了aic3254的音訊輸出暫存器,喇叭和耳機就會有很大的“沙沙”的聲音,但是在播放的時候也是可以聽到播放的聲音的,只是“沙沙
innosetup教程【2】如何通過[code]欄位自定義安裝介面
目標要求: 1、 介面border去掉原本windows自帶的對話方塊格式,採取扁平化設計; 2、 簡化安裝流程,不要彈出那麼多安裝嚮導頁,不要讓使用者一直點“下一步”,簡潔人性化; 3、 安裝介面可載入漂亮的背景圖片;
【Spring-Security】【2】DelegatingFilterProxy
pat security clas 添加 chain let XML org mapping Spring Security 對我們應用的影響是通過一系列的 ServletRequest 過濾器實現的。 Spring Security 使用了 o.s.web.filter
【2】JVM-JAVA對象的訪問
lin oar XML nts java棧 article value new string Java中對象的訪問 JAVA是面向對象的語言,那麽在JAVA虛擬機中,存在非常多的對象,對象訪問是無處不在的。即時是最簡單的訪問,也會涉及到JAVA棧、JAVA堆、方法區
Android組件系列----ContentProvider內容提供者【2】
resolv blank lan int 復制 pad otto rtp wrap 二、代碼舉例: 終於全部project文件的文件夾結構例如以下: PersonDao是增刪改查數據庫的工具類,並在PersonContentProvider中得到調用。DBHe
quick-cocos2d-x遊戲開發【2】——項目結構分析、創建新場景
fileutil 遊戲 log world plain ack 設計 avi sca 創建完一個新項目之後,我們能夠簡單的看一看這個項目的文件組成,有這麽一個文件層次結構 幾個proj.*目錄就不用說了,是相應的平臺的解決方式,res專門存放我們的遊戲資源
Cocos2d-x v3.0正式版嘗鮮體驗【2】 Android平臺移植
生成 ble ack nts 做的 導入 eclipse so文件 腳本 今天沒事又嘗試了下3.0正式版關於Android平臺的移植,把新建的項目移植了下。過程僅用了十分鐘左右,什麽概念?!好吧,事實上我想說,這個版本號真的移植非常輕松啊,只是還沒加上其它東西,只是就眼
java持有對象【2】ArrayList容器續解
對象 符號 向上 ont 轉換 選擇 同時 是什麽 object 此為JDK API1.6.0對ArrayList的解釋。 ArrayList 使用java泛型創建類很復雜,但是應用預定義的泛型很簡單。例如,要想定義用來保存Apple對象的ArrayList,可以聲明
【Azure】通過Powershell,創建虛擬機鏡像
ima rsh 賬號 公司 order china 訂閱 部分 檢查 由於公司更換雲服務嘗試,有機會使用微軟公有雲服務,簡單了使用了一下,整理了一些文章,希望可以幫助同樣使用微軟公有雲的用戶。優點:· 用戶界面非常漂亮,而且流程升級比較清楚;· 服務非常多,無論充值多少
Fiddler抓包【2】_捕獲設置
from lang 請求 user src file ati 允許 iphone 1、Fiddler抓web網站請求 手動設置方法一:Tools--->WinINET Options--->連接--->局域網設置--->代理服務器勾選後“高級
【PHP】通過header發送自定義數據
example color 發送 uil ade field urn server font 發送header: 我們定義了三個參數,token、language、region,放入header發送過去 <?php $url = ‘http://www.exam
【轉】異步傳輸模式與同步傳輸模式的區別
傳輸 不返回 面向 等待 機會 間隔 統一 其他 就是 說到異步傳輸模式與同步傳輸模式的區別,首先簡單首先他們各自的意思。 同步傳輸模式中發送方和接收方的時鐘是統一的、字符與字符間的傳輸是同步無間隔的。 異步傳輸模式並不要
LeetCode數組類的題目提交記錄 【2】
targe result 有序 suppose middle size body some 遞歸 /***********************************************************************33. Search in Ro
DOM案例【2】註冊文本倒計時
元素 text disable als har www .org document www. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/h
MYSQL基礎入門學習【2】
保存 範圍 body 不同的 clas 排列 分類 入門 字節 1. 數據類型:指列、存儲過程參數、表達式和局部變量的數據特征,它決定了數據的存儲格式,代表了不同的信息類型 (1) 整型(按存儲範圍分類):TINYINT(1字節) SAMLLINT(2字節) MEDIUMI
【MySQL】通過Binary Log簡單實現數據回滾(一)
pre mage 用途 top IT cal 時間 excel var 一、前言 對,沒錯,我又水了好一陣子,深刻反思寄幾。前段時間,工作項目上出於對excel等批量操作可能出現誤操作的問題,要求提供一個能夠根據操作批次進行數據回滾的能力。在開發的過程中接觸到了MySQL的
HTML第一課——基礎知識普及【2】
成績 eqv apt awr .com UC S4B 搜索引擎 dib 關註公眾號:自動化測試實戰 img標簽 我們先看一下文檔結構: 這裏我們文件當前位置就是lesson.html,所以現在我們img屬性src給的值要進入imgs文件夾,所以我們可以用相
【2】信息的表示和處理
float 執行 單獨 因此 com alt 卡片 acl AC 1.現代計算機存儲和處理的信息都以二值信號表示。 2.機器為什麽要使用二進制進行存儲和處理? 答:二值信號能夠很容易的被表示、存儲、傳輸。例如: 可以表示為穿孔卡片上有洞和無洞、導線上的高壓和低壓,順逆