調整通話中的音量可以從XX9712與XX1182來調整,由於在XX9712中更改有可能會更動到其他狀態下的設定值,且XX1182原本就可以在Runtime模式下,藉由UART傳送AT Command來達到動態調整的功能,因此由XX1182來調整,在實踐上應該會比較簡單!
##CONTINUE##
首先,必須先知道在通話模式時,調整聲音的音量是由哪個driver所控制,根據Roland的說法,通話時音量的控制是由audio_api.dll所控制,即platform\bluetooth\PCM_Audio_Control.cpp,在此程式中有四個function:SetAudioVolume、GetAudioVolume、SetAudioMicVolume及GetAudioMicVolume分別對應到speaker與microphone的音量大小,因此只要在此加入控制程式即可!
為了要能控制XX1182,所以必須在XX1182的IOControl中加入相對應的程式:
case IOCTL_FME_PCM_VOLLEVEL:
{
unsigned char FmInitStr[][7] ={
{0xFC, 0xF3, 0x3B, 0x1E,0x3D,dwLenOut,0x00},
{0xFC, 0xF3, 0x3B, 0x1E,0x3A,0x00,0x00}
};
for(i=0;i<2;i++) bresult =" WriteFile" val =" dwLenOut;" i="0;i<2;i++)" bresult =" WriteFile" val =" dwLenOut;" style="color: rgb(255, 255, 51);">PCM1SpkVol、PCM2SpkVol、PCM1MicVolPCM2MicVol用來儲存兩中模式下speaker與microphone的音量大小。
增加好控制碼後,在PCM_Audio_Control.cpp中就可以控制XX1182的輸出音量了:
DllExport void SetAudioVolume(AudioLevel audioLevel)
{
HANDLE g_hFM1182=NULL;
USHORT parm01=0;
DWORD dwRet;
g_hFM1182 = CreateFile(L"FME1:",0,0,NULL,OPEN_EXISTING,0,NULL);
if (INVALID_HANDLE_VALUE == g_hFM1182)
{
RETAILMSG(0, (TEXT("=====Error calling CreateFile on g_hFM1182\r\n")));
}
else
{
RETAILMSG(0, (TEXT("=====Calling CreateFile on g_hFM1182 Success!!\r\n")));
dwRet = DeviceIoControl(g_hFM1182,IOCTL_FME_PCM_SPKVOLLEVEL,
&parm01,sizeof(USHORT),NULL,(DWORD)audioLevel,NULL,NULL);
}
CloseHandle(g_hFM1182);
}
DllExport AudioLevel GetAudioVolume(void)
{
HKEY hkey;
LONG lResult;
DWORD dwType, dwSize;
unsigned short dvalue;
dwSize = 4;
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SOFTWARE"), 0, KEY_QUERY_VALUE, &hkey) != ERROR_SUCCESS)
return 0;
if(PIO_READ_INPUT(GPIO, GPIO_GROUP(3),GPIO_INDEX(20)))
{
lResult = RegQueryValueEx(hkey, _T("PCM2SpkVol"), NULL, &dwType, (LPBYTE)&dvalue, &dwSize); //query registry value
}
else
{
lResult = RegQueryValueEx(hkey, _T("PCM1SpkVol"), NULL, &dwType, (LPBYTE)&dvalue, &dwSize); //query registry value
}
RegCloseKey(hkey);
return dvalue;
}
DllExport void SetAudioMicVolume(AudioLevel audioLevel)
{
HANDLE g_hFM1182=NULL;
USHORT parm01=0;
DWORD dwRet;
g_hFM1182 = CreateFile(L"FME1:",0,0,NULL,OPEN_EXISTING,0,NULL);
if (INVALID_HANDLE_VALUE == g_hFM1182)
{
RETAILMSG(0, (TEXT("=====Error calling CreateFile on g_hFM1182\r\n")));
}
else
{
RETAILMSG(0, (TEXT("=====Calling CreateFile on g_hFM1182 Success!!\r\n")));
dwRet = DeviceIoControl(g_hFM1182,IOCTL_FME_PCM_VOLLEVEL,
&parm01,sizeof(USHORT),NULL,(DWORD)audioLevel,NULL,NULL);
}
CloseHandle(g_hFM1182);
}
DllExport AudioLevel GetAudioMicVolume(void)
{
HKEY hkey;
LONG lResult;
DWORD dwType, dwSize;
unsigned short dvalue;
dwSize = 4;
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SOFTWARE"), 0, KEY_QUERY_VALUE, &hkey) != ERROR_SUCCESS)
return 0;
if(PIO_READ_INPUT(GPIO, GPIO_GROUP(3),GPIO_INDEX(20)))
{
lResult = RegQueryValueEx(hkey, _T("PCM2MicVol"), NULL, &dwType, (LPBYTE)&dvalue, &dwSize); //query registry value
}
else
{
lResult = RegQueryValueEx(hkey, _T("PCM1MicVol"), NULL, &dwType, (LPBYTE)&dvalue, &dwSize); //query registry value
}
RegCloseKey(hkey);
return dvalue;
}
目前,通話中的音量可以動態的控制(若想讓聲音靜音,只需將gain值設為即可),不過當通話結束後,gain值的大小會再回復為預設值,不會儲存通話時的調整值!
2007年4月5日
讓通話中能調整聲音與麥克風的音量
標籤: Audio, WinCE Driver
2007年4月2日
讓調整參數更方便
由於聲音的調整經常需要不斷的調整與測試,如果在整機的狀態下,又不能跳線,那從修改參數,compile code,build image以及download image,光是修改一次參數的時間可能就要光掉5分鐘的時間了,效率上蠻差的!
##CONTINUE##
在Roland的建議以及幫助下,為了改參數能更快更方便,同時,希望能在讓客戶自行調整參數又不需要更動到driver的情形下,把參數的設定值儲存到一個文字檔上,再由driver來讀檔以及設定值!
1.
因為在此案中,Audio Path共有6種,所以必須準備6個檔分別對應至這6種情形,然後在Windows CE的 Registry下加入6個參數,儲存這四個檔的放置位置與檔名 :在Platform.reg中加入6個參數
[HKEY_LOCAL_MACHINE\SOFTWARE]
"File1"="\\Windows\\Bypass1.txt"
"File2"="\\Windows\\Bypass2.txt"
"File3"="\\Windows\\Bypass3.txt"
"File4"="\\Windows\\Bypass4.txt"
"File5"="\\Windows\\pcm01.txt"
"File6"="\\Windows\\pcm02.txt"
2.
在driver裡加入讀取Registry值與讀取檔案內值的function:傳入要讀取Registry的值並讀取相對應的檔案,再透過UART將值傳送至XX1182中。
int XX1182Write(HKEY key, TCHAR *subkey, TCHAR *name, HANDLE hComPort)
{
HKEY hkey;
LONG lResult;
TCHAR str[MAX_PATH], *pStr;
DWORD dwType, dwSize;
FILE *file;
unsigned char pData[7];
int i, nResult;
if (RegOpenKeyEx(key, subkey, 0, KEY_QUERY_VALUE, &hkey) != ERROR_SUCCESS)
return 0;
dwSize = sizeof(str);
lResult = RegQueryValueEx(hkey, name, NULL, &dwType, (LPBYTE)str, &dwSize); //query registry value
RegCloseKey(hkey);
if (lResult != ERROR_SUCCESS || dwType != REG_SZ)
return 0;
file = _tfopen(str, _T("rt"));
if (file == NULL) //open file failed
return 0;
nResult = 0;
while (_fgetts(str, MAX_PATH, file))
{
pStr = _tcsstr(str, _T("//"));
if (pStr) //there is comment
*pStr = _T('\0'); //remove comment
pStr = str;
for (i = 0; i < pstr =" _tcsstr(pStr,">= _T('0') && *pStr <= _T('9')) pData[i] = (pData[i] <<>= _T('A') && *pStr <= _T('F')) pData[i] = (pData[i] <<>= _T('a') && *pStr <= _T('f')) pData[i] = (pData[i] << i ="="">misc.iEchoStatus == 0)
{
nLine = XX1182Write(HKEY_LOCAL_MACHINE, _T("SOFTWARE"), _T("File1"), hFile);
CloseHandle(hFile);
}
else if(v_pDriverGlobals->misc.iEchoStatus == 1)
{
nLine = XX1182Write(HKEY_LOCAL_MACHINE, _T("SOFTWARE"), _T("File2"), hFile);
CloseHandle(hFile);
}
else if(v_pDriverGlobals->misc.iEchoStatus == 2)
{
nLine = XX1182Write(HKEY_LOCAL_MACHINE, _T("SOFTWARE"), _T("File3"), hFile);
CloseHandle(hFile);
}
else
{
nLine = XX1182Write(HKEY_LOCAL_MACHINE, _T("SOFTWARE"), _T("File4"), hFile);
CloseHandle(hFile);
}
break;
case IOCTL_FME_PCM_MESSAGE:
//PCM spk -> out2 echo cancellation on
nLine = XX1182Write(HKEY_LOCAL_MACHINE, _T("SOFTWARE"), _T("File6"), hFile);
CloseHandle(hFile);
break;
case IOCTL_FME_PCM_MESSAGE2:
//PCM spk -> out2 echo cancellation on
nLine = XX1182Write(HKEY_LOCAL_MACHINE, _T("SOFTWARE"), _T("File5"), hFile);
CloseHandle(hFile);
break;
藉由此方式,確實可讓調整參數更快也更方便,可直接在Windows CE直接更改相對應的文字檔來調整,driver的不份則不需再更動,不過,缺點則是執行時間會變長。
張貼者:
Joseph
於
09:19
標籤: Audio, WinCE Driver
2007年3月28日
XX1182設定方式
XX1182在此案子主要用來echo cancellation and noise suppression,包括錄音與與藍芽連接時PCM的聲音處理。
此Chip的參數設定方式透過UART傳入Commond的方式來更改,透過修改不同Memory Address位址,可以設定聲音傳送的路徑、設定microphone與speaker的pgagain值大小等。
##CONTINUE##
Command的格式是以FCF3為開頭作為sync word,例如:
寫值:
FC F3 3B 1E 34 00 55 代表 write memory 1E34 with 0055
讀值:
FC F3 37 1E 34 代表 read memory contents of 1E34
因此,在driver中,我們可以利用一個Array來儲存要修改的參數:
unsigned char FmInitStr[][7] ={
{0xFC, 0xF3, 0x3B, 0x1E, 0x30, 0x02, 0x21},
{0xFC, 0xF3, 0x3B, 0x1E, 0x34, 0x00, 0x0F},
{0xFC, 0xF3, 0x3B, 0x1E, 0x3D, 0x0A, 0x00},
{0xFC, 0xF3, 0x3B, 0x1E, 0x41, 0x00, 0x01},
{0xFC, 0xF3, 0x3B, 0x1E, 0x44, 0x00, 0x01},
{0xFC, 0xF3, 0x3B, 0x1E, 0x45, 0x00, 0xDE},
{0xFC, 0xF3, 0x3B, 0x1E, 0x46, 0x00, 0x10},
{0xFC, 0xF3, 0x3B, 0x1E, 0x36, 0x00, 0x1F},
{0xFC, 0xF3, 0x3B, 0x0F, 0xA9, 0x00, 0x80},
{0xFC, 0xF3, 0x3B, 0x1E, 0x70, 0x07, 0xC0},
{0xFC, 0xF3, 0x3B, 0x1E, 0x52, 0x00, 0x07},
{0xFC, 0xF3, 0x3B, 0x1E, 0x51, 0xC0, 0x00},
{0xFC, 0xF3, 0x3B, 0x1E, 0x3A, 0x00, 0x00}
};
然後再利用一個迴圈依序將Commond透過UART傳入即可!
for(i=0;i<13;i++) bresult =" WriteFile" style="color: rgb(255, 255, 51);">IE65的值,若是正常狀況下,讀取的值會不斷的增加,反之,則為0。
標籤: Audio, WinCE Driver