// PageAudioOutSettings.cpp : implementation file // #include "stdafx.h" #include "mgrnve.h" #include "ConnectionManager.h" #include "PageAudioOutSettings.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CPageAudioOutSettings dialog CPageAudioOutSettings::CPageAudioOutSettings(CWnd* pParent, CMgrNVE* pMgrCM, CConnectionManager *pConnMgr) : CParamDlg(CPageAudioOutSettings::IDD, pParent, pMgrCM, pConnMgr) { //{{AFX_DATA_INIT(CPageAudioOutSettings) m_bAudEnable = FALSE; m_uAudioGain = 0; //}}AFX_DATA_INIT m_pNet5Api = NULL; m_pCod5Api = NULL; m_pMediaSettings = NULL; m_pMsgMgr = NULL; m_pMediaSettings = NULL; m_bRunning = FALSE; m_uBufferSize = 0; ZeroMemory(m_pInData, sizeof(m_pInData)); } void CPageAudioOutSettings::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CPageAudioOutSettings) DDX_Control(pDX, IDC_CHECK_MIC, m_chkMic); DDX_Control(pDX, IDC_CB_AUDIO_OUT_CODEC, m_cbAudioCodec); DDX_Control(pDX, IDC_CB_AUD_OUT_SAMPLE_RATE, m_cbSampleRate); DDX_Check(pDX, IDC_CHK_AUD_OUT_ENABLE, m_bAudEnable); DDX_Slider(pDX, IDC_SLD_AUDIO_OUT_GAIN, m_uAudioGain); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CPageAudioOutSettings, CDialog) //{{AFX_MSG_MAP(CPageAudioOutSettings) ON_BN_CLICKED(IDC_BTN_RESET, OnBtnReset) ON_NOTIFY(NM_RELEASEDCAPTURE, IDC_SLD_AUDIO_OUT_GAIN, OnReleasedcaptureSldAudioOutGain) ON_BN_CLICKED(IDC_CHK_AUD_OUT_ENABLE, OnChkAudOutEnable) ON_WM_DESTROY() ON_BN_CLICKED(IDC_BTN_AOUT_APPLY, OnBtnAoutApply) ON_BN_CLICKED(IDC_BTN_BROWSE, OnBtnBrowse) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CPageAudioOutSettings message handlers BOOL CPageAudioOutSettings::SaveSetting() { UpdateData(TRUE); char szType[NVE_SHORT_STR_LENGTH]; char szCmd[NVE_SHORT_EXT_CMD_LENGTH]; switch(m_cbAudioCodec.GetCurSel()) { case 0: strcpy(szType, "pcm"); m_pMediaSettings->AudioOutSettings.uAudioCodec = COD5_ACT_PCM; m_pMediaSettings->AudioOutSettings.Wfx.wBitsPerSample = 16; break; case 1: strcpy(szType, "pcm"); m_pMediaSettings->AudioOutSettings.uAudioCodec = COD5_ACT_PCM; m_pMediaSettings->AudioOutSettings.Wfx.wBitsPerSample = 8; break; case 2: strcpy(szType, "ulaw"); m_pMediaSettings->AudioOutSettings.uAudioCodec = COD5_ACT_ULAW; m_pMediaSettings->AudioOutSettings.Wfx.wBitsPerSample = 8; break; case 3: strcpy(szType, "alaw"); m_pMediaSettings->AudioOutSettings.uAudioCodec = COD5_ACT_ALAW; m_pMediaSettings->AudioOutSettings.Wfx.wBitsPerSample = 8; break; } if (m_cbSampleRate.GetCurSel() == 0) { m_pMediaSettings->AudioOutSettings.Wfx.nSamplesPerSec = 8000; } else if (m_cbSampleRate.GetCurSel() == 1) { m_pMediaSettings->AudioOutSettings.Wfx.nSamplesPerSec = 16000; } m_pMediaSettings->AudioOutSettings.Wfx.nBlockAlign = (WORD)(m_pMediaSettings->AudioOutSettings.Wfx.wBitsPerSample/8); m_pMediaSettings->AudioOutSettings.Wfx.nAvgBytesPerSec = m_pMediaSettings->AudioOutSettings.Wfx.nSamplesPerSec*m_pMediaSettings->AudioOutSettings.Wfx.nBlockAlign; _snprintf(szCmd, sizeof(szCmd), "EXT_SUBSESSION_CMD %s/track6 RTSP/1.0\r\n" "CSeq: 1\r\n" "CmdCount: 1\r\n" "SET AUDIO_OUT enable=%d, stream_type=\"%s\", sample_rate=%d, data_bits=%d, channels=1, gain=%d\r\n\r\n", m_pConnection->GetServerAddr(), m_bAudEnable, szType, m_pMediaSettings->AudioOutSettings.Wfx.nSamplesPerSec, m_pMediaSettings->AudioOutSettings.Wfx.wBitsPerSample, m_uAudioGain); CHECK_AND_RETURN_FALSE(m_pNet5Api->Net5Command(NET5_NC_SEND_RTSP_REQUEST, (ULONG*)szCmd, NULL, NULL, NULL), "Cannot set audio out properties"); CHECK_AND_RETURN_FALSE(m_pNet5Api->Net5Command(NET5_NC_RECV_RTSP_RESPONSE, (ULONG*)szCmd, NULL, NULL, NULL), "Cannot receive response(audio out)"); return TRUE; } BOOL CPageAudioOutSettings::ResetSetting() { m_pMediaSettings->AudioOutSettings.bEnable = m_bAudEnable = 0; m_cbAudioCodec.SetCurSel(0); m_pMediaSettings->AudioOutSettings.uAudioCodec = COD5_ACT_PCM; m_cbSampleRate.SetCurSel(1); m_pMediaSettings->AudioOutSettings.Wfx.wFormatTag = WAVE_FORMAT_PCM; m_pMediaSettings->AudioOutSettings.Wfx.nChannels = 1; m_pMediaSettings->AudioOutSettings.Wfx.nSamplesPerSec = 16000; m_pMediaSettings->AudioOutSettings.Wfx.wBitsPerSample = 16; m_pMediaSettings->AudioOutSettings.Wfx.nBlockAlign = (WORD)(m_pMediaSettings->AudioOutSettings.Wfx.wBitsPerSample*m_pMediaSettings->AudioOutSettings.Wfx.nChannels/8); m_pMediaSettings->AudioOutSettings.Wfx.nAvgBytesPerSec = m_pMediaSettings->AudioOutSettings.Wfx.nSamplesPerSec*m_pMediaSettings->AudioOutSettings.Wfx.nBlockAlign; m_pMediaSettings->AudioOutSettings.Wfx.cbSize = 0; UpdateData(FALSE); if (m_ThreadAudOut.GetState() == TS_RUN) { m_ThreadAudOut.StopThread(0); } SetControlProperty(IDC_SLD_AUDIO_OUT_GAIN, 128); SetAudioGain(128); return TRUE; } BOOL CPageAudioOutSettings::UpdateSetting() { return TRUE; } BOOL CPageAudioOutSettings::OnInitDialog() { CDialog::OnInitDialog(); // TODO: Add extra initialization here ULONG uCh = m_local_param.channel; char text[64]; if(uCh==0xFF){ sprintf(text,"All Channels"); uCh=0; }else{ sprintf(text,"Channel:%d", uCh); } SetDlgItemText(IDC_STATIC_AUDIO_OUT_CH,text); m_pMediaSettings = m_pConnection->GetMediaSettings(uCh); m_pCod5Api = m_pConnection->GetCod5Api(); m_pNet5Api = m_pConnection->GetNet5Api(); m_pMsgMgr = m_pMgrNVE->GetMsgManager(); char szCmd[NVE_SHORT_EXT_CMD_LENGTH]; _snprintf(szCmd, sizeof(szCmd), "EXT_SUBSESSION_CMD %s/track6 RTSP/1.0\r\n" "CSeq: 1\r\n" "CmdCount: 1\r\n" "GET AUDIO_OUT\r\n\r\n", m_pConnection->GetServerAddr()); CHECK_AND_RETURN_FALSE(m_pNet5Api->Net5Command(NET5_NC_SEND_RTSP_REQUEST, (ULONG*)szCmd, NULL, NULL, NULL), "Cannot set audio out properties"); CHECK_AND_RETURN_FALSE(m_pNet5Api->Net5Command(NET5_NC_RECV_RTSP_RESPONSE, (ULONG*)szCmd, NULL, NULL, NULL), "Cannot receive response(audio out)"); ParseRTSPResponse(szCmd, m_RtspValue, NVE_MAX_RTSP_VALUE); FindRTSPValue(m_RtspValue, "enable", &m_bAudEnable, NVE_RTSP_VALUE_INT); m_pMediaSettings->AudioOutSettings.bEnable = m_bAudEnable; char szCodec[NVE_SHORT_STR_LENGTH]; FindRTSPValue(m_RtspValue, "stream_type", szCodec, NVE_RTSP_VALUE_STR); m_cbAudioCodec.AddString("PCM(16bit)"); m_cbAudioCodec.AddString("PCM(8bit)"); m_cbAudioCodec.AddString("uLaw(8bit)"); m_cbAudioCodec.AddString("aLaw(8bit)"); if (strcmp(szCodec, "pcm") == 0) { m_pMediaSettings->AudioOutSettings.uAudioCodec = COD5_ACT_PCM; } else if (strcmp(szCodec, "ulaw") == 0) { m_pMediaSettings->AudioOutSettings.uAudioCodec = COD5_ACT_ULAW; } else if (strcmp(szCodec, "alaw") == 0) { m_pMediaSettings->AudioOutSettings.uAudioCodec = COD5_ACT_ALAW; } m_pMediaSettings->AudioOutSettings.Wfx.wFormatTag = WAVE_FORMAT_PCM; int nBits=16; FindRTSPValue(m_RtspValue, "data_bits", &nBits, NVE_RTSP_VALUE_INT); m_pMediaSettings->AudioOutSettings.Wfx.wBitsPerSample = (WORD)nBits; switch(m_pMediaSettings->AudioOutSettings.uAudioCodec) { case COD5_ACT_ULAW: m_cbAudioCodec.SetCurSel(2); break; case COD5_ACT_ALAW: m_cbAudioCodec.SetCurSel(3); break; default: case COD5_ACT_PCM: if(nBits==8) { m_cbAudioCodec.SetCurSel(1); } else { m_cbAudioCodec.SetCurSel(0); } break; } m_cbSampleRate.AddString("8K"); // 0 m_cbSampleRate.AddString("16K"); // 1 FindRTSPValue(m_RtspValue, "sample_rate", &m_pMediaSettings->AudioOutSettings.Wfx.nSamplesPerSec, NVE_RTSP_VALUE_INT); switch(m_pMediaSettings->AudioOutSettings.Wfx.nSamplesPerSec) { case 8000: m_cbSampleRate.SetCurSel(0); break; default: case 16000: m_cbSampleRate.SetCurSel(1); break; } m_pMediaSettings->AudioOutSettings.Wfx.nBlockAlign = (WORD)(m_pMediaSettings->AudioOutSettings.Wfx.wBitsPerSample/8); m_pMediaSettings->AudioOutSettings.Wfx.nChannels = 1; m_pMediaSettings->AudioOutSettings.Wfx.nAvgBytesPerSec = m_pMediaSettings->AudioOutSettings.Wfx.nBlockAlign* m_pMediaSettings->AudioOutSettings.Wfx.nSamplesPerSec*m_pMediaSettings->AudioOutSettings.Wfx.nChannels; m_pMediaSettings->AudioOutSettings.Wfx.cbSize = 0; FindRTSPValue(m_RtspValue, "gain", &m_uAudioGain, NVE_RTSP_VALUE_INT); SetControlProperty(IDC_SLD_AUDIO_OUT_GAIN, m_uAudioGain); m_pMediaSettings->AudioOutSettings.uGain = m_uAudioGain; UpdateData(FALSE); return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE } BOOL CPageAudioOutSettings::SetControlProperty(UINT ctrl_slider, int value) { CSliderCtrl* ctrl=(CSliderCtrl* )GetDlgItem(ctrl_slider); ctrl->SetRangeMin(0,TRUE); ctrl->SetRangeMax(255,TRUE); ctrl->SetPos(value); ctrl->SetTicFreq(16); return TRUE; } void CPageAudioOutSettings::OnBtnReset() { // TODO: Add your control notification handler code here SetControlProperty(IDC_SLD_AUDIO_OUT_GAIN, 128); SetAudioGain(128); } void CPageAudioOutSettings::OnReleasedcaptureSldAudioOutGain(NMHDR* pNMHDR, LRESULT* pResult) { // TODO: Add your control notification handler code here UpdateData(TRUE); SetAudioGain(m_uAudioGain); *pResult = 0; } BOOL CPageAudioOutSettings::SetAudioGain(ULONG uValue) { char szCmd[NVE_SHORT_EXT_CMD_LENGTH]; _snprintf(szCmd, sizeof(szCmd), "EXT_SUBSESSION_CMD %s/track6 RTSP/1.0\r\n" "CSeq: 1\r\n" "CmdCount: 1\r\n" "SET AUDIO_OUT gain=%d\r\n\r\n", m_pConnection->GetServerAddr(), uValue); CHECK_AND_RETURN_FALSE(m_pNet5Api->Net5Command(NET5_NC_SEND_RTSP_REQUEST, (ULONG*)szCmd, NULL, NULL, NULL), "Cannot set audio out gain"); CHECK_AND_RETURN_FALSE(m_pNet5Api->Net5Command(NET5_NC_RECV_RTSP_RESPONSE, (ULONG*)szCmd, NULL, NULL, NULL), "Cannot receive response(audio out gain)"); return TRUE; } void CPageAudioOutSettings::OnChkAudOutEnable() { // TODO: Add your control notification handler code here CButton *pBtn = (CButton*)GetDlgItem(IDC_CHK_AUD_OUT_ENABLE); if (pBtn) { if (pBtn->GetCheck()) { m_chkMic.EnableWindow(FALSE); m_cbAudioCodec.EnableWindow(FALSE); m_cbSampleRate.EnableWindow(FALSE); } else { m_chkMic.EnableWindow(TRUE); m_cbAudioCodec.EnableWindow(TRUE); m_cbSampleRate.EnableWindow(TRUE); } } } DWORD WINAPI CPageAudioOutSettings::ThreadAudioOutStub(LPVOID lpParam) { THREAD_PARAM_SET *pParam = (THREAD_PARAM_SET*)lpParam; CPageAudioOutSettings *pAudOut = (CPageAudioOutSettings*)pParam->pParam2; return static_cast(pAudOut)->ThreadAudioOut(lpParam); } #define BIAS 0x84 // the add-in bias for 16 bit samples #define CLIP 32635 #pragma warning( disable : 4244 ) static unsigned char uLawFrom16BitLinear(short sample) { static int exp_lut[256] = {0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3, 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7}; unsigned char sign = (unsigned char)((sample >> 8) & 0x80); if (sign != 0) sample = -sample; // get the magnitude if (sample > CLIP) sample = CLIP; // clip the magnitude sample += BIAS; unsigned char exponent = exp_lut[(sample>>7) & 0xFF]; unsigned char mantissa = (sample >> (exponent+3)) & 0x0F; unsigned char result = ~(sign | (exponent << 4) | mantissa); if (result == 0 ) result = 0x02; // CCITT trap return result; } #define SIGN_BIT (0x80) /* Sign bit for a A-law byte. */ #define QUANT_MASK (0xf) /* Quantization field mask. */ #define NSEGS (8) /* Number of A-law segments. */ #define SEG_SHIFT (4) /* Left shift for segment number. */ #define SEG_MASK (0x70) /* Segment field mask. */ static short seg_aend[8] = {0x1F, 0x3F, 0x7F, 0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF}; static short search(short val, short *table, short size) { short i; for (i = 0; i < size; i++) { if (val <= *table++) return (i); } return (size); } unsigned char linear2alaw(short pcm_val) /* 2's complement (16-bit range) */ { short mask; short seg; unsigned char aval; pcm_val = pcm_val >> 3; if (pcm_val >= 0) { mask = 0xD5; /* sign (7th) bit = 1 */ } else { mask = 0x55; /* sign bit = 0 */ pcm_val = -pcm_val - 1; } /* Convert the scaled magnitude to segment number. */ seg = search(pcm_val, seg_aend, 8); /* Combine the sign, segment, and quantization bits. */ if (seg >= 8) /* out of range, return maximum value. */ return (unsigned char) (0x7F ^ mask); else { aval = (unsigned char) seg << SEG_SHIFT; if (seg < 2) aval |= (pcm_val >> 1) & QUANT_MASK; else aval |= (pcm_val >> seg) & QUANT_MASK; return (aval ^ mask); } } #pragma warning( default : 4244 ) unsigned char g_Converted_sample[1024*1024]; int ConvertPCMuLaw(short *pPCM, int insize, unsigned char *pDST, int bHalf) { for(int i=0,j=0;i>8); if(bHalf) i++; } return j; } int ConvertPCMDown(short *pPCM, int insize, short *pDST) { for(int i=0,j=0;i ms // INFO: time bug // TRACE("tm h[%u] l[%u]\n",ftime.dwHighDateTime, ftime.dwLowDateTime); ULARGE_INTEGER t; t.LowPart = ftime.dwLowDateTime; t.HighPart = ftime.dwHighDateTime; return t.QuadPart/10000; // return ms //return r*10000+l; } DWORD WINAPI CPageAudioOutSettings::ThreadAudioOut(LPVOID lpParam) { THREAD_PARAM_SET *pParam = (THREAD_PARAM_SET*)lpParam; CUserThread *pThread = (CUserThread*)pParam->pParam1; BOOL bRun = TRUE; COD5_DATA_INFO_EX Info; HANDLE hKill = pThread->GetKillHandle(); ULONG uSubCmd, uCh = 0, uStatus = 0; char szCmd[NVE_MAX_EXT_CMD_LENGTH]; char stream_type[16]; int data_bits=16; int sample_rate=16000; unsigned char *pSrcPCM16K16bits; int uSrcTotalSize; unsigned char *pTxData; int uTotalSize; CString strPath; FILE *pAudioFile = NULL; ULONG uAudioLen = 0; unsigned char *pAudioData = NULL; GetDlgItemText(IDC_EDIT_AUDIO_FILE, strPath); if (strPath.Compare("") != 0) { pAudioFile = fopen(strPath, "rb"); if (!pAudioFile) { m_pMsgMgr->PushErrorCodeF("Cannot open audio file[%s]", strPath); m_pMsgMgr->Show(TRUE); return 0; } fseek(pAudioFile, 0, SEEK_END); uAudioLen = ftell(pAudioFile); fseek(pAudioFile, 0, SEEK_SET); pAudioData = new unsigned char[uAudioLen]; if (!pAudioData) { m_pMsgMgr->PushErrorCodeF("Cannot read audio data"); m_pMsgMgr->Show(TRUE); fclose(pAudioFile); return 0; } fread(pAudioData, uAudioLen, 1, pAudioFile); pSrcPCM16K16bits = pAudioData+44; uSrcTotalSize = uAudioLen-44; pTxData = pSrcPCM16K16bits; uTotalSize = uSrcTotalSize; fclose(pAudioFile); } else { pSrcPCM16K16bits=g_wav_sample+44; uSrcTotalSize = sizeof(g_wav_sample)-44; pTxData=pSrcPCM16K16bits; uTotalSize = uSrcTotalSize; } int uIndex = 0; ULONGLONG msStartTime=0,msCurTime=0; ULONG PlayBytesPerSec = (2*16*1000); ULONGLONG TansferBytes = 0; ULONGLONG msQTime; int msWaitTime = 0; int cXnsTransferPacketSize = (8*1024); // #define XNS_MAX_AUDIO_OUT_PACKET_SIZE (1000*8) //int msWaitTime = 1000 * XNS_MAX_AUDIO_OUT_PACKET_SIZE / BytesPerSec ; //int msWaitTime = 1000 / (BytesPerSec / XNS_MAX_AUDIO_OUT_PACKET_SIZE); //msWait = msWait*5/10; // Á¶±Ý ª°Ô sample_rate = (m_cbSampleRate.GetCurSel()==0)?8000:16000; int bDown = (m_cbSampleRate.GetCurSel()==0)?1:0; // 0:8K, 1:16K if(m_cbAudioCodec.GetCurSel()==0) { // pcm 16bit if(bDown) { uTotalSize = ConvertPCMDown((short*)pSrcPCM16K16bits, uSrcTotalSize, (short*)g_Converted_sample); pTxData = g_Converted_sample; // } else { pTxData = pSrcPCM16K16bits; // uTotalSize = uSrcTotalSize; } strcpy(stream_type, "pcm"); data_bits = 16; } else if(m_cbAudioCodec.GetCurSel()==1) { // pcm 8bit uTotalSize = ConvertPCM16bits_8bits((short*)pSrcPCM16K16bits, uSrcTotalSize, g_Converted_sample, bDown); strcpy(stream_type, "pcm"); data_bits = 8; pTxData = g_Converted_sample; // } else if(m_cbAudioCodec.GetCurSel()==2) { // uLaw 8bit uTotalSize = ConvertPCMuLaw((short*)pSrcPCM16K16bits, uSrcTotalSize, g_Converted_sample, bDown); strcpy(stream_type, "ulaw"); data_bits = 8; pTxData = g_Converted_sample; } else if(m_cbAudioCodec.GetCurSel()==3) { // aLaw 8bit uTotalSize = ConvertPCMaLaw((short*)pSrcPCM16K16bits, uSrcTotalSize, g_Converted_sample, bDown); strcpy(stream_type, "ulaw"); data_bits = 8; pTxData = g_Converted_sample; } PlayBytesPerSec = (data_bits/8)*sample_rate; msStartTime = GetMsecTime(); // ½ÃÀÛ ½Ã°£À» »¡¸®Çϸé óÀ½ ²ö±è Çö»óÀ» ÁÙÀϼö ÀÖ´Ù. uSubCmd = NET5_ATL_GET_STATUS; m_pNet5Api->Net5Command(NET5_NC_AUDIO_TX_LOCK, &uSubCmd, &uCh, &uStatus, 0); if (uStatus) { uSubCmd = NET5_ATL_FORCED_LOCK; } else { uSubCmd = NET5_ATL_LOCK; } m_pNet5Api->Net5Command(NET5_NC_AUDIO_TX_LOCK, &uSubCmd, &uCh, 0, 0); _snprintf(szCmd, sizeof(szCmd), "EXT_SUBSESSION_CMD %s/track6 RTSP/1.0\r\n" "CSeq: 1\r\n" "CmdCount: 1\r\n" "SET AUDIO_OUT enable=1\r\n\r\n", m_pConnection->GetServerAddr()); if (!m_pNet5Api->Net5Command(NET5_NC_SEND_RTSP_REQUEST, (ULONG*)szCmd, NULL, NULL, NULL)) { m_pMsgMgr->PushErrorCodeF("Cannot set audio out properties"); m_pMsgMgr->Show(TRUE); if (pAudioData) { delete[] pAudioData; } return 0; } if (!m_pNet5Api->Net5Command(NET5_NC_RECV_RTSP_RESPONSE, (ULONG*)szCmd, NULL, NULL, NULL)) { m_pMsgMgr->PushErrorCodeF("Cannot receive response(audio out)"); m_pMsgMgr->Show(TRUE); if (pAudioData) { delete[] pAudioData; } return 0; } TRACE("[%s] [%d]hz [%d]bits\n",stream_type, sample_rate, data_bits); while (bRun) { if (WaitForSingleObject(hKill, msWaitTime) == WAIT_OBJECT_0) { // if (WaitForSingleObject(hKill, 190) == WAIT_OBJECT_0) { bRun = FALSE; break; } if(uIndex+cXnsTransferPacketSize > uTotalSize) { uIndex = 0; //break; } // send audio data Info.pDataBuffer = pTxData + uIndex; Info.uDataType = CMN5_DT_COD_EX; Info.uDataSize = cXnsTransferPacketSize; Info.uFrameType = COD5_FT_PCM_AUDIO; m_pCod5Api->Cod5SetEventData(CMN5_DT_COD_EX, &Info); uIndex += cXnsTransferPacketSize; TansferBytes += cXnsTransferPacketSize; msQTime = 1000 * TansferBytes / PlayBytesPerSec; msCurTime = GetMsecTime(); msWaitTime = (int)(msQTime - (msCurTime - msStartTime) - 500); // 0.5ÃÊ ¹Ì¸® ¹öÆÛ¸µ ÇÑ´Ù´Â °³³ä. óÀ½ ²ö±â´Â Çö»ó ¸·±â À§Çؼ­. if(msWaitTime<0) msWaitTime = 0; #if 0 // test ULARGE_INTEGER t,t2; t.QuadPart = msCurTime; t2.QuadPart = msQTime; TRACE("tm[%10d] q[%8d] w[%8d] i[%8d/%d]\n",t.LowPart, t2.LowPart, msWaitTime, uIndex, uTotalSize); #endif } if (pAudioData) { delete[] pAudioData; } _snprintf(szCmd, sizeof(szCmd), "EXT_SUBSESSION_CMD %s/track6 RTSP/1.0\r\n" "CSeq: 1\r\n" "CmdCount: 1\r\n" "SET AUDIO_OUT enable=0\r\n\r\n", m_pConnection->GetServerAddr()); CHECK_AND_RETURN_FALSE(m_pNet5Api->Net5Command(NET5_NC_SEND_RTSP_REQUEST, (ULONG*)szCmd, NULL, NULL, NULL), "Cannot set audio out properties"); CHECK_AND_RETURN_FALSE(m_pNet5Api->Net5Command(NET5_NC_RECV_RTSP_RESPONSE, (ULONG*)szCmd, NULL, NULL, NULL), "Cannot receive response(audio out)"); uSubCmd = NET5_ATL_UNLOCK; m_pNet5Api->Net5Command(NET5_NC_AUDIO_TX_LOCK, &uSubCmd, &uCh, 0, 0); return 0; } void CPageAudioOutSettings::StopAudioOut() { if (m_chkMic.GetCheck()) { AudioOutMicStop(); } else { if (m_ThreadAudOut.GetState() == TS_RUN) { m_ThreadAudOut.StopThread(0); } } } void CPageAudioOutSettings::OnDestroy() { CDialog::OnDestroy(); // TODO: Add your message handler code here StopAudioOut(); } void CPageAudioOutSettings::OnBtnAoutApply() { // TODO: Add your control notification handler code here m_pConnection->ApplyProc(this); CButton *pBtn = (CButton*)GetDlgItem(IDC_CHK_AUD_OUT_ENABLE); if (pBtn) { if (pBtn->GetCheck()) { if (m_chkMic.GetCheck()) { AudioOutMicStart(); } else { m_ThreadAudOut.StartThread(ThreadAudioOutStub, this, 0, 0); } } else { if (m_chkMic.GetCheck()) { AudioOutMicStop(); } else { if (m_ThreadAudOut.GetState() == TS_RUN) { m_ThreadAudOut.StopThread(0); } } } m_pMediaSettings->AudioOutSettings.bEnable = pBtn->GetCheck(); } } void CPageAudioOutSettings::OnBtnBrowse() { // TODO: Add your control notification handler code here CFileDialog Dlg(TRUE); CString strPath; if (Dlg.DoModal() == IDOK) { strPath = Dlg.GetPathName(); SetDlgItemText(IDC_EDIT_AUDIO_FILE, strPath); } } LARGE_INTEGER GetTimeTag() { SYSTEMTIME SystemTime; FILETIME FileTime; LARGE_INTEGER liSystemTime; GetSystemTime(&SystemTime); SystemTimeToFileTime(&SystemTime, &FileTime); liSystemTime.LowPart = FileTime.dwLowDateTime; liSystemTime.HighPart = FileTime.dwHighDateTime; return liSystemTime; } BOOL CPageAudioOutSettings::MakeAudioOutData(WAVEHDR* pWaveHdr, COD5_DATA_INFO_EX* pData) { pData->uDataType = CMN5_DT_COD_EX; pData->uStructSize = sizeof(COD5_DATA_INFO_EX); pData->uErrCode = CMN5_EC_NO_ERROR; pData->uBoardNum = 0; pData->uChannelNum = 0; pData->uHasNextData = TRUE; pData->pDataBuffer = (UCHAR*)pWaveHdr->lpData; pData->TimeTag = GetTimeTag(); pData->uDataSize = pWaveHdr->dwBytesRecorded; pData->uFrameType = COD5_FT_PCM_AUDIO; return TRUE; } void CALLBACK CPageAudioOutSettings::WaveInProcStub(HWAVEIN hwi, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2) { CPageAudioOutSettings *pInstance = (CPageAudioOutSettings*)dwInstance; static_cast(pInstance)->WaveInProc(hwi, uMsg, dwParam1, dwParam2); } void CPageAudioOutSettings::WaveInProc(HWAVEIN hwi, UINT uMsg, DWORD dwParam1, DWORD dwParam2) { if (!m_pMediaSettings->AudioOutSettings.bEnable) { return; } EnterCriticalSection(&m_CritAudioOut); if (uMsg == WIM_DATA) { WAVEHDR *pInHdr = (WAVEHDR*)dwParam1; COD5_DATA_INFO_EX Data = { 0, }; MakeAudioOutData(pInHdr, &Data); SendAudioOutData(&Data); waveInUnprepareHeader(hwi, pInHdr, sizeof(WAVEHDR)); pInHdr->dwBufferLength = m_uBufferSize; memset((void*)pInHdr->lpData, 0, m_uBufferSize); pInHdr->dwFlags = 0; pInHdr->dwLoops = 0; waveInPrepareHeader(hwi, pInHdr, sizeof(WAVEHDR)); waveInAddBuffer(hwi, pInHdr, sizeof(WAVEHDR)); } LeaveCriticalSection(&m_CritAudioOut); } BOOL CPageAudioOutSettings::AudioOutMicStart() { char szCmd[NVE_SHORT_EXT_CMD_LENGTH]; ULONG uSubCmd = NET5_ATL_FORCED_LOCK; ULONG uChannel = 0; ULONG uStatus = 0; ULONG i; if (m_pMediaSettings->AudioOutSettings.bEnable) { return TRUE; } InitializeCriticalSection(&m_CritAudioOut); m_pNet5Api->Net5Command(NET5_NC_AUDIO_TX_LOCK, (ULONG*)&uSubCmd, (ULONG*)&uChannel, (ULONG*)&uStatus, NULL); _snprintf(szCmd, sizeof(szCmd), "EXT_SUBSESSION_CMD %s/track6 RTSP/1.0\r\n" "CSeq: 1\r\n" "CmdCount: 1\r\n" "SET AUDIO_OUT enable=1\r\n\r\n", m_pConnection->GetServerAddr()); CHECK_AND_RETURN_FALSE(m_pNet5Api->Net5Command(NET5_NC_SEND_RTSP_REQUEST, (ULONG*)szCmd, NULL, NULL, NULL), ""); CHECK_AND_RETURN_FALSE(m_pNet5Api->Net5Command(NET5_NC_RECV_RTSP_RESPONSE, (ULONG*)szCmd, NULL, NULL, NULL), ""); m_pMediaSettings->AudioOutSettings.bEnable = TRUE; m_uBufferSize = AUDIO_OUT_BUFFER_SIZE; WAVEFORMATEX Wfx; Wfx.wFormatTag = WAVE_FORMAT_PCM; Wfx.nChannels = m_pMediaSettings->AudioOutSettings.Wfx.nChannels; Wfx.wBitsPerSample = m_pMediaSettings->AudioOutSettings.Wfx.wBitsPerSample; if (m_pMediaSettings->AudioOutSettings.uAudioCodec == COD5_ACT_ULAW || m_pMediaSettings->AudioOutSettings.uAudioCodec == COD5_ACT_ALAW) { Wfx.wBitsPerSample = 16; m_uBufferSize *= 2; } Wfx.nSamplesPerSec = m_pMediaSettings->AudioOutSettings.Wfx.nSamplesPerSec; Wfx.nBlockAlign = (WORD)(Wfx.wBitsPerSample/8); Wfx.nAvgBytesPerSec = Wfx.nChannels*Wfx.nSamplesPerSec*Wfx.nBlockAlign; Wfx.cbSize = 0; waveInOpen((LPHWAVEIN)&m_hWaveIn, WAVE_MAPPER, (LPWAVEFORMATEX)&Wfx, (DWORD)WaveInProcStub, (DWORD)this, CALLBACK_FUNCTION); for (i=0; iAudioOutSettings.bEnable) { return TRUE; } _snprintf(szCmd, sizeof(szCmd), "EXT_SUBSESSION_CMD %s/track6 RTSP/1.0\r\n" "CSeq: 1\r\n" "CmdCount: 1\r\n" "SET AUDIO_OUT enable=0\r\n\r\n", m_pConnection->GetServerAddr()); CHECK_AND_RETURN_FALSE(m_pNet5Api->Net5Command(NET5_NC_SEND_RTSP_REQUEST, (ULONG*)szCmd, NULL, NULL, NULL), ""); CHECK_AND_RETURN_FALSE(m_pNet5Api->Net5Command(NET5_NC_RECV_RTSP_RESPONSE, (ULONG*)szCmd, NULL, NULL, NULL), ""); m_pNet5Api->Net5Command(NET5_NC_AUDIO_TX_LOCK, (ULONG*)&uSubCmd, (ULONG*)&uChannel, NULL, NULL); m_pMediaSettings->AudioOutSettings.bEnable = FALSE; EnterCriticalSection(&m_CritAudioOut); waveInStop(m_hWaveIn); waveInReset(m_hWaveIn); for (i=0; iAudioOutSettings.uAudioCodec; ULONG uDataBits = m_pMediaSettings->AudioOutSettings.Wfx.wBitsPerSample; //TRACE("Audio frame type : %d, frame size : %d\n", pData->uFrameType, pData->uDataSize); if(uAudioCodec == COD5_ACT_PCM && uDataBits == 8) { // pcm 8bit for (ULONG i=0; iuDataSize; i++) { pData->pDataBuffer[i] = (BYTE)(pData->pDataBuffer[i]-128); } } else if(uAudioCodec == COD5_ACT_ULAW) { // uLaw 8bit uTotalSize = ConvertPCMuLaw((short*)pData->pDataBuffer, pData->uDataSize, g_Converted_sample, FALSE); pData->pDataBuffer = g_Converted_sample; pData->uDataSize = uTotalSize; } else if(uAudioCodec == COD5_ACT_ALAW) { // aLaw 8bit uTotalSize = ConvertPCMaLaw((short*)pData->pDataBuffer, pData->uDataSize, g_Converted_sample, FALSE); pData->pDataBuffer = g_Converted_sample; pData->uDataSize = uTotalSize; } m_pCod5Api->Cod5SetEventData(CMN5_DT_COD_EX, pData); return TRUE; }