| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825 |
- #include "StdAfx.h"
- #include "SpanChannel.h"
- #include "DspChannel.h"
- #include "DevDsp.h"
- #include "PrdVirtualDevice.h"
- #include "MC.h"
- #include "../IVR/IvrSysInc.h"
- #include "TtsInterface.h"
- CDspChannel::CDspChannel(DEV_RES_CH_TYPE ChannelNo, DEV_RES_NO_TYPE NodeNo, DEV_RES_NO_TYPE BoardNo)
- : CChannelResource(DEV_RES_TYPE_DSP, NodeNo, BoardNo, DEVICE_RES_NO_ANY, ChannelNo),
- m_pMixer(NULL), m_Job(DEV_VOC_JOB_NONE), m_IsRecording(false)
- {
- }
- CDspChannel::~CDspChannel(void)
- {
- }
- /*****************************************************************
- **【函数名称】 __constructPlayStruct
- **【函数功能】 构造放音SDK所需结构体
- **【参数】
- **【返回值】
- ****************************************************************/
- bool CDspChannel::__constructPlayStruct( PlayVoiceContent* pContent )
- {
- PlayVoiceMode Mode = pContent->nModel;
- switch(Mode)
- {
- case PVM_PLAY_WAIT_DIGIT:
- m_Job = DEV_VOC_JOB_PLAY_DTMF;
- case PVM_PLAY_ONLY:
- {
- // 如果使用了TTS,进行TTS转换
- switch(pContent->nTts)
- {
- default:
- case PLAY_CONTENT_AUDIO: // 不使用TTS
- sprintf_s(m_AudioFilePlay, MAX_PATH, _T("%s\0"), pContent->szFileName);
- break;
- case PLAY_CONTENT_TTS_STR: // TTS文本
- {
- ITtsInterface::getInstance().setTTSParam(pContent->nTtsDigitMode, pContent->nTtsSpeed, pContent->nTtsVolume);
- if(!ITtsInterface::getInstance().string2Audio(pContent->szFileName, m_AudioFilePlay, MAX_PATH))
- {
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{DspCh}: 通道[%d-%d-%d]TTS文本转换失败"),
- m_Id.NodeNo, m_Id.BoardNo, m_Id.ChanNo);
- return false;
- }
- }
- break;
- case PLAY_CONTENT_TTS_FILE: // TTS文件
- {
- ITtsInterface::getInstance().setTTSParam(pContent->nTtsDigitMode, pContent->nTtsSpeed, pContent->nTtsVolume);
- if(!ITtsInterface::getInstance().file2Audio(pContent->szFileName, m_AudioFilePlay, MAX_PATH))
- {
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{DspCh}: 通道[%d-%d-%d]TTS文件转换失败, File = %s"),
- m_Id.NodeNo, m_Id.BoardNo, m_Id.ChanNo, pContent->szFileName);
- return false;
- }
- }
- break;
- }
- memset(&m_IottPlay[0], 0, sizeof(DX_IOTT));
- m_IottPlay[0].io_fhandle = CMC::GetInstance().allocPrd(m_Id.NodeNo).handle();
- m_IottPlay[0].io_bufp = m_AudioFilePlay;
- m_IottPlay[0].io_offset = 0;
- m_IottPlay[0].io_length = -1;
- m_IottPlay[0].io_type = IO_PRD_DEV | IO_EOT;
- memset(&m_XpbPlay, 0, sizeof(m_XpbPlay));
- m_XpbPlay.wFileFormat = FILE_FORMAT_WAVE; // WAV file.
- m_XpbPlay.wDataFormat = DATA_FORMAT_PCM; // PCM
- m_XpbPlay.wBitsPerSample = 16; // The number of bits per sample.
- m_XpbPlay.nSamplesPerSec = DRT_8KHZ; // Sampling rates
- }
- case PVM_WAIT_DIGIT:
- {
- int Idx = 0;
- bool Used = false;
- if(pContent->nDtmfCount > 0)
- {
- ISX_dx_clrtpt(&m_TptPlay[Idx], 1);
- m_TptPlay[Idx].tp_type = IO_EOT;
- m_TptPlay[Idx].tp_termno = DX_MAXDTMF;
- m_TptPlay[Idx].tp_length = pContent->nDtmfCount;
- m_TptPlay[Idx].tp_flags = TF_MAXDTMF;
- Idx++;
- Used = true;
- }
- if(pContent->cDtmfEnd > 0)
- {
- if(Used)
- {
- m_TptPlay[Idx - 1].tp_type &= ~IO_EOT;
- m_TptPlay[Idx - 1].tp_type = IO_CONT;
- }
- ISX_dx_clrtpt(&m_TptPlay[Idx], 1);
- m_TptPlay[Idx].tp_type = IO_EOT;
- m_TptPlay[Idx].tp_termno = DX_DIGMASK;
- switch(pContent->cDtmfEnd)
- {
- case '*':
- m_TptPlay[Idx].tp_length = DM_S;
- break;
- case '#':
- m_TptPlay[Idx].tp_length = DM_P;
- break;
- case '0':
- m_TptPlay[Idx].tp_length = DM_0;
- break;
- case '1':
- m_TptPlay[Idx].tp_length = DM_1;
- break;
- case '2':
- m_TptPlay[Idx].tp_length = DM_2;
- break;
- case '3':
- m_TptPlay[Idx].tp_length = DM_3;
- break;
- case '4':
- m_TptPlay[Idx].tp_length = DM_4;
- break;
- case '5':
- m_TptPlay[Idx].tp_length = DM_5;
- break;
- case '6':
- m_TptPlay[Idx].tp_length = DM_6;
- break;
- case '7':
- m_TptPlay[Idx].tp_length = DM_7;
- break;
- case '8':
- m_TptPlay[Idx].tp_length = DM_8;
- break;
- case '9':
- m_TptPlay[Idx].tp_length = DM_9;
- break;
- default:
- ASSERT(FALSE);
- break;
- }
- m_TptPlay[Idx].tp_flags = TF_DIGMASK;
- Idx++;
- Used = true;
- }
- // 只放音的模式下也允许被按键打断,所以要在此设置跳出条件
- if(Mode == PVM_PLAY_ONLY)
- {
- m_Job = DEV_VOC_JOB_PLAY_FILE;
- break;
- }
- if(pContent->nDtmfPeriod > 0)
- {
- if(Used)
- {
- m_TptPlay[Idx - 1].tp_type &= ~IO_EOT;
- m_TptPlay[Idx - 1].tp_type = IO_CONT;
- }
- ISX_dx_clrtpt(&m_TptPlay[Idx], 1);
- m_TptPlay[Idx].tp_type = IO_EOT;
- m_TptPlay[Idx].tp_termno = DX_IDDTIME;
- m_TptPlay[Idx].tp_length = pContent->nDtmfPeriod;
- m_TptPlay[Idx].tp_flags = TF_1000MS | TF_IDDTIME | TF_FIRST;
- }
- if(Mode == PVM_WAIT_DIGIT)
- m_Job = DEV_VOC_JOB_GET_DTMF;
- }
- break;
- }
- return true;
- }
- /*****************************************************************
- **【函数名称】 __construcRecStruct
- **【函数功能】 构造录音SDK所需结构体
- **【参数】
- **【返回值】
- ****************************************************************/
- void CDspChannel::__construcRecStruct( RecordContent* pContent )
- {
- memset(&m_IottRec, 0, sizeof(DX_IOTT));
- m_IottRec.io_fhandle = CMC::GetInstance().allocPrd(m_Id.NodeNo).handle();
- sprintf_s(m_AudioFileRec, MAX_PATH, _T("%s\0"), pContent->szFileName);
- m_IottRec.io_bufp = m_AudioFileRec;
- m_IottRec.io_offset = 0;
- m_IottRec.io_length = -1;
- m_IottRec.io_type = IO_PRD_DEV | IO_EOT;
- int Idx = 0;
- bool Used = false;
- if(pContent->cEnd > 0)
- {
- ISX_dx_clrtpt(&m_TptPlay[Idx], 1);
- m_TptRec[Idx].tp_type = IO_EOT;
- m_TptRec[Idx].tp_termno = DX_DIGMASK;
- switch(pContent->cEnd)
- {
- case '*':
- m_TptRec[Idx].tp_length = DM_S;
- break;
- case '#':
- m_TptRec[Idx].tp_length = DM_P;
- break;
- case '0':
- m_TptRec[Idx].tp_length = DM_0;
- break;
- case '1':
- m_TptRec[Idx].tp_length = DM_1;
- break;
- case '2':
- m_TptRec[Idx].tp_length = DM_2;
- break;
- case '3':
- m_TptRec[Idx].tp_length = DM_3;
- break;
- case '4':
- m_TptRec[Idx].tp_length = DM_4;
- break;
- case '5':
- m_TptRec[Idx].tp_length = DM_5;
- break;
- case '6':
- m_TptRec[Idx].tp_length = DM_6;
- break;
- case '7':
- m_TptRec[Idx].tp_length = DM_7;
- break;
- case '8':
- m_TptRec[Idx].tp_length = DM_8;
- break;
- case '9':
- m_TptRec[Idx].tp_length = DM_9;
- break;
- default:
- ASSERT(FALSE);
- break;
- }
- m_TptRec[Idx].tp_flags = TF_DIGMASK;
- Idx++;
- Used = true;
- }
- if(pContent->nPeriod > 0)
- {
- if(Used)
- {
- m_TptRec[Idx - 1].tp_type &= ~IO_EOT;
- m_TptRec[Idx - 1].tp_type = IO_CONT;
- }
- ISX_dx_clrtpt(&m_TptPlay[Idx], 1);
- m_TptRec[Idx].tp_type = IO_EOT;
- m_TptRec[Idx].tp_termno = DX_MAXTIME;
- m_TptRec[Idx].tp_length = pContent->nPeriod;
- m_TptRec[Idx].tp_flags = TF_1000MS | TF_MAXTIME;
- Used = true;
- }
- if(!Used)
- {
- ISX_dx_clrtpt(&m_TptRec[Idx], 1);
- m_TptRec[0].tp_type = IO_EOT;
- m_TptRec[0].tp_termno = DX_MAXTIME;
- m_TptRec[0].tp_length = 65535;
- m_TptRec[0].tp_flags = TF_MAXTIME;
- }
- memset(&m_XpbRec, 0, sizeof(m_XpbPlay));
- m_XpbRec.wFileFormat = FILE_FORMAT_WAVE; // WAV file.
- m_XpbRec.wDataFormat = DATA_FORMAT_ALAW; // ALAW
- m_XpbRec.wBitsPerSample = 16; // The number of bits per sample.
- m_XpbRec.nSamplesPerSec = DRT_8KHZ; // Sampling rates
- }
- /*****************************************************************
- **【函数名称】 __constructDtmfStruct
- **【函数功能】 构造收按键SDK所需结构体
- **【参数】
- **【返回值】
- ****************************************************************/
- void CDspChannel::__constructDtmfStruct( void )
- {
- int DtmfCount = 0;
- int DtmfPeriod = 0;
- int LastIdx = 0;
- for(int i = 0; i < 3; ++i)
- {
- DV_TPT* pDvtpt = &m_TptPlay[i];
- if(pDvtpt->tp_type == IO_CONT)
- ++LastIdx;
- if(pDvtpt->tp_termno == DX_MAXDTMF)
- DtmfCount = pDvtpt->tp_length;
- if(pDvtpt->tp_termno == DX_IDDTIME)
- DtmfPeriod = pDvtpt->tp_length;
- }
- if(DtmfCount > 0 && DtmfPeriod > 0)
- {
- m_TptPlay[LastIdx - 1].tp_type &= ~IO_EOT;
- m_TptPlay[LastIdx - 1].tp_type = IO_CONT;
- ISX_dx_clrtpt(&m_TptPlay[LastIdx], 1);
- m_TptPlay[LastIdx].tp_type = IO_EOT;
- m_TptPlay[LastIdx].tp_termno = DX_MAXTIME;
- m_TptPlay[LastIdx].tp_length = DtmfCount * DtmfPeriod;
- m_TptPlay[LastIdx].tp_flags = TF_1000MS | TF_MAXTIME;
- }
- }
- /*****************************************************************
- **【函数名称】 __replay
- **【函数功能】 继续播放上一声音
- **【参数】
- **【返回值】
- ****************************************************************/
- bool CDspChannel::__replay( void )
- {
- /* Clear the digits on this channel, avoid the digit to terminate the playback */
- ISX_dx_clrdigbuf(m_Handle);
- if(ISX_dx_playiottdata(m_Handle, m_IottPlay, m_TptPlay, &m_XpbPlay, EV_ASYNC) != 0)
- {
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_ERROR, _T("{DspCh}: 通道[%d-%d-%d]放音失败, file = %s, reason = %s"),
- m_Id.NodeNo, m_Id.BoardNo, m_Id.ChanNo, m_AudioFilePlay, ISX_ATDV_ERRMSGP(m_Handle));
- return false;
- }
- return true;
- }
- /*****************************************************************
- **【函数名称】 __redoGetDigit
- **【函数功能】 重新收号
- **【参数】
- **【返回值】
- ****************************************************************/
- bool CDspChannel::__redoGetDigit( void )
- {
- __constructDtmfStruct();
- memset(&m_DigitBuf, 0, sizeof(DV_DIGIT));
- if(ISX_dx_getdig(m_Handle, m_TptPlay, &m_DigitBuf, EV_ASYNC) != 0)
- {
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_ERROR, _T("{DspCh}: 通道[%d-%d-%d]收号失败, reason = %s"),
- m_Id.NodeNo, m_Id.BoardNo, m_Id.ChanNo, ISX_ATDV_ERRMSGP(m_Handle));
- return false;
- }
- return true;
- }
- /*****************************************************************
- **【函数名称】 onPlayStart
- **【函数功能】 放音开始
- **【参数】
- **【返回值】
- ****************************************************************/
- void CDspChannel::__onPlayStart( void )
- {
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{DspCh}: 通道[%d-%d-%d]开始放音, AudioFile = %s"),
- m_Id.NodeNo, m_Id.BoardNo, m_Id.ChanNo, m_AudioFilePlay);
- CMC::GetInstance().onDevResState(m_Id);
- }
- /*****************************************************************
- **【函数名称】 onPlayEnd
- **【函数功能】 放音结束
- **【参数】
- **【返回值】
- ****************************************************************/
- void CDspChannel::__onPlayEnd( void )
- {
- ULONG OperIndex = ISX_sr_getevtoperindex();
- if(m_Job == DEV_VOC_JOB_PLAY_DTMF)
- {
- // 获取结束原因
- long TermMask = ISX_ATDX_TERMMSK(m_Handle);
- if((TermMask & TM_USRSTOP) || (TermMask & TM_ERROR))
- {
- m_Job = DEV_VOC_JOB_NONE;
- if(m_pMixer != NULL)
- m_pMixer->onPlayEnd(NULL);
- }
- else
- __redoGetDigit();
- }
- else if(m_Job == DEV_VOC_JOB_PLAY_FILE)
- {
- m_Job = DEV_VOC_JOB_NONE;
- if(m_pMixer != NULL)
- m_pMixer->onPlayEnd(NULL);
- }
- else if(m_Job == DEV_VOC_JOB_PLAY_TONE)
- {
- m_Job = DEV_VOC_JOB_NONE;
- if(m_pMixer != NULL)
- m_pMixer->onToneEnd(OperIndex);
- }
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{DspCh}: 通道[%d-%d-%d]放音结束, AudioFile = %s"),
- m_Id.NodeNo, m_Id.BoardNo, m_Id.ChanNo, m_AudioFilePlay);
- CMC::GetInstance().onDevResState(m_Id);
- }
- /*****************************************************************
- **【函数名称】 __onRecordStart
- **【函数功能】 录音开始
- **【参数】
- **【返回值】
- ****************************************************************/
- void CDspChannel::__onRecordStart( void )
- {
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{DspCh}: 通道[%d-%d-%d]开始录音, AudioFile = %s"),
- m_Id.NodeNo, m_Id.BoardNo, m_Id.ChanNo, m_AudioFileRec);
- CMC::GetInstance().onDevResState(m_Id);
- }
- /*****************************************************************
- **【函数名称】 __onRecordEnd
- **【函数功能】 录音结束
- **【参数】
- **【返回值】
- ****************************************************************/
- void CDspChannel::__onRecordEnd( void )
- {
- ULONG OperIndex = ISX_sr_getevtoperindex();
- m_IsRecording = false;
- // 录音时忽略停止录音的原因,直接通知录音结束
- if(m_pMixer != NULL)
- m_pMixer->onRecEnd(OperIndex);
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{DspCh}: 通道[%d-%d-%d]录音结束, AudioFile = %s"),
- m_Id.NodeNo, m_Id.BoardNo, m_Id.ChanNo, m_AudioFileRec);
- CMC::GetInstance().onDevResState(m_Id);
- }
- /*****************************************************************
- **【函数名称】 __onGotDigit
- **【函数功能】 收按键结束
- **【参数】
- **【返回值】
- ****************************************************************/
- void CDspChannel::__onGotDigit( void )
- {
- m_Job = DEV_VOC_JOB_NONE;
- if(m_pMixer != NULL)
- m_pMixer->onPlayEnd(m_DigitBuf.dg_value);
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{DspCh}: 通道[%d-%d-%d]收号结束, DTMF = %s"),
- m_Id.NodeNo, m_Id.BoardNo, m_Id.ChanNo, m_DigitBuf.dg_value);
- CMC::GetInstance().onDevResState(m_Id);
- }
- /*****************************************************************
- **【函数名称】 __onError
- **【函数功能】 出错处理
- **【参数】
- **【返回值】
- ****************************************************************/
- void CDspChannel::__onError( void )
- {
- ULONG OperIndex = ISX_sr_getevtoperindex();
- int OperType = ISX_sr_getevtopertype();
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{DspCh}: 通道[%d-%d-%d]操作[%s]出错, Reason = %s, OperIndex = %u"),
- m_Id.NodeNo, m_Id.BoardNo, m_Id.ChanNo, ISX_sr_getopername(), ISX_ATDV_ERRMSGP(m_Handle), OperIndex);
- ASSERT(m_pMixer != NULL);
- if(OperType == OPER_PLAY)
- {
- DEV_VOICE_JOB_TYPE Job = m_Job;
- m_Job = DEV_VOC_JOB_NONE;
- if(Job == DEV_VOC_JOB_PLAY_TONE)
- {
- if(m_pMixer != NULL)
- m_pMixer->onToneEnd(OperIndex);
- }
- else
- {
- if(m_pMixer != NULL)
- m_pMixer->onPlayEnd(CONST_ERR_PLAY_AUDIO);
- }
- }
- else if(OperType == OPER_RECORD)
- {
- m_IsRecording = false;
- if(m_pMixer != NULL)
- m_pMixer->onRecEnd(OperIndex);
- }
- }
- /*****************************************************************
- **【函数名称】 open
- **【函数功能】 打开系统资源
- **【参数】
- **【返回值】 成功true,失败false
- ****************************************************************/
- bool CDspChannel::open( void )
- {
- ASSERT(m_Handle == DEV_HANDLE_INVALID);
- // 打开DTI channel
- m_Handle = ISX_dx_open(DT_DSP_CH, m_Id.NodeNo, m_Id.BoardNo, m_Id.ChanNo, this);
- if(m_Handle == -1)
- {
- m_Handle = DEV_HANDLE_INVALID;
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_ERROR, _T("{DSPCh}: 通道[%d-%d-%d]打开失败"), m_Id.NodeNo, m_Id.BoardNo, m_Id.ChanNo);
- return false;
- }
- //LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{DSPCh}: 通道[%d-%d-%d]打开成功"), m_Id.NodeNo, m_Id.BoardNo, m_Id.ChanNo);
- return true;
- }
- /*****************************************************************
- **【函数名称】 close
- **【函数功能】 关闭系统资源
- **【参数】
- **【返回值】
- ****************************************************************/
- void CDspChannel::close( void )
- {
- if(m_Handle != DEV_HANDLE_INVALID)
- {
- ISX_dx_close(m_Handle, 0);
- m_Handle = DEV_HANDLE_INVALID;
- //LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{DSPCh}: 通道[%d-%d-%d]关闭"), m_Id.NodeNo, m_Id.BoardNo, m_Id.ChanNo);
- }
- }
- /*****************************************************************
- **【函数名称】 reset
- **【函数功能】 重置通道
- **【参数】
- **【返回值】
- ****************************************************************/
- void CDspChannel::reset( void )
- {
- ASSERT(m_Handle != DEV_HANDLE_INVALID);
- /* Stop all the activity on this channel. */
- ISX_dx_stopch(m_Handle, EV_STOPALL|EV_ASYNC);
- m_Job = DEV_VOC_JOB_NONE;
- m_IsRecording = false;
- }
- /*****************************************************************
- **【函数名称】 playSound
- **【函数功能】 放音
- **【参数】
- **【返回值】
- ****************************************************************/
- bool CDspChannel::playSound( PlayVoiceContent* pContent )
- {
- ASSERT(pContent != NULL);
- if(pContent->nModel == PVM_STOP_PLAY)
- {
- m_Job = DEV_VOC_JOB_NONE;
- return ISX_dx_stopch(m_Handle, EV_STOPPLAY|EV_ASYNC) == 0;
- }
- else
- {
- if(!__constructPlayStruct(pContent))
- return false;
- /* Clear the digits on this channel, avoid the digit to terminate the playback */
- ISX_dx_clrdigbuf(m_Handle);
- if(pContent->nModel == PVM_WAIT_DIGIT)
- {
- memset(&m_DigitBuf, 0, sizeof(DV_DIGIT));
- if(ISX_dx_getdig(m_Handle, m_TptPlay, &m_DigitBuf, EV_ASYNC) != 0)
- {
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_ERROR, _T("{DspCh}: 通道[%d-%d-%d]收号失败, reason = %s"),
- m_Id.NodeNo, m_Id.BoardNo, m_Id.ChanNo, ISX_ATDV_ERRMSGP(m_Handle));
- return false;
- }
- }
- else
- {
- if(ISX_dx_playiottdata(m_Handle, m_IottPlay, m_TptPlay, &m_XpbPlay, EV_ASYNC) != 0)
- {
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_ERROR, _T("{DspCh}: 通道[%d-%d-%d]放音失败, file = %s, reason = %s"),
- m_Id.NodeNo, m_Id.BoardNo, m_Id.ChanNo, m_AudioFilePlay, ISX_ATDV_ERRMSGP(m_Handle));
- return false;
- }
- }
- return true;
- }
- }
- /*****************************************************************
- **【函数名称】 playTone
- **【函数功能】 放Tone音
- **【参数】
- **【返回值】
- ****************************************************************/
- bool CDspChannel::playTone( int ToneTp )
- {
- if(ToneTp == CHANNEL_TONE_NULL)
- {
- m_Job = DEV_VOC_JOB_NONE;
- return ISX_dx_stopch(m_Handle, EV_STOPPLAY|EV_ASYNC) == 0;
- }
- switch(ToneTp)
- {
- case CHANNEL_TONE_RINGBACK:
- sprintf_s(m_AudioFilePlay, MAX_PATH, _T("%s\0"), TONE_NAME_RINGBACK);
- break;
- case CHANNEL_TONE_DIAL:
- sprintf_s(m_AudioFilePlay, MAX_PATH, _T("%s\0"), TONE_NAME_DIAL);
- break;
- case CHANNEL_TONE_BUSY:
- sprintf_s(m_AudioFilePlay, MAX_PATH, _T("%s\0"), TONE_NAME_BUSY);
- break;
- case CHANNEL_TONE_HOLD:
- sprintf_s(m_AudioFilePlay, MAX_PATH, _T("%s\0"), TONE_NAME_HOLD);
- break;
- default:
- return false;
- }
- m_Job = DEV_VOC_JOB_PLAY_TONE;
- memset(m_IottPlay, 0, sizeof(DX_IOTT) * 2);
- m_IottPlay[0].io_fhandle = CMC::GetInstance().allocPrd(m_Id.NodeNo).handle();
- m_IottPlay[0].io_bufp = m_AudioFilePlay;
- m_IottPlay[0].io_offset = 0;
- m_IottPlay[0].io_length = -1;
- m_IottPlay[0].io_type = IO_PRD_DEV | IO_CONT;
- m_IottPlay[1].io_fhandle = CMC::GetInstance().allocPrd(m_Id.NodeNo).handle();
- m_IottPlay[1].io_bufp = m_AudioFilePlay;
- m_IottPlay[1].io_offset = 0;
- m_IottPlay[1].io_length = -1;
- m_IottPlay[1].io_type = IO_PRD_DEV | IO_EOT;
- memset(&m_TptPlay[0], 0, sizeof(DV_TPT));
- m_TptPlay[0].tp_type = IO_EOT;
- m_TptPlay[0].tp_termno = DX_MAXTIME;
- m_TptPlay[0].tp_length = 65535;
- m_TptPlay[0].tp_flags = TF_MAXTIME;
- memset(&m_XpbPlay, 0, sizeof(m_XpbPlay));
- m_XpbPlay.wFileFormat = FILE_FORMAT_VOX; // WAV file.
- m_XpbPlay.wDataFormat = DATA_FORMAT_G711_ALAW; // ALAW编码格式
- m_XpbPlay.wBitsPerSample = 8; // The number of bits per sample.
- m_XpbPlay.nSamplesPerSec = DRT_8KHZ; // Sampling rates
- ISX_dx_clrdigbuf(m_Handle);
- if(ISXE_dx_PlayMultiFiles(m_Handle, m_IottPlay, m_TptPlay, &m_XpbPlay, EV_ASYNC, ToneTp) != 0)
- {
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_ERROR, _T("{DspCh}: 通道[%d-%d-%d]放Tone音失败, file = %s, reason = %s"),
- m_Id.NodeNo, m_Id.BoardNo, m_Id.ChanNo, m_AudioFilePlay, ISX_ATDV_ERRMSGP(m_Handle));
- return false;
- }
- return true;
- }
- /*****************************************************************
- **【函数名称】 startRecord
- **【函数功能】 开始录音
- **【参数】
- **【返回值】
- ****************************************************************/
- bool CDspChannel::startRecord( RecordContent* pContent )
- {
- ASSERT(pContent != NULL);
- __construcRecStruct(pContent);
- ISX_dx_clrdigbuf(m_Handle);
- if(ISX_dx_reciottdata(m_Handle, &m_IottRec, m_TptRec, &m_XpbRec, EV_ASYNC, pContent->nTaskId) != 0)
- {
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_ERROR, _T("{DspCh}: 通道[%d-%d-%d]录音失败, file = %s, reason = %s"),
- m_Id.NodeNo, m_Id.BoardNo, m_Id.ChanNo, m_AudioFileRec, ISX_ATDV_ERRMSGP(m_Handle));
- return false;
- }
- m_IsRecording = true;
- return true;
- }
- /*****************************************************************
- **【函数名称】 stopRecord
- **【函数功能】 停止录音
- **【参数】
- **【返回值】
- ****************************************************************/
- bool CDspChannel::stopRecord( void )
- {
- m_IsRecording = false;
- return ISX_dx_stopch(m_Handle, EV_STOPREC|EV_ASYNC) == 0;
- }
- /*****************************************************************
- **【函数名称】 setVoiceMode
- **【函数功能】 设置会议语音模式
- **【参数】
- **【返回值】
- ****************************************************************/
- bool CDspChannel::setVoiceMode( int Mode )
- {
- return ISX_dx_setparm(m_Handle, DXCH_VOICE_MODE, &Mode) == 0;
- }
- /*****************************************************************
- **【函数名称】 onDevEvent
- **【函数功能】 系统事件处理
- **【参数】
- **【返回值】
- ****************************************************************/
- void CDspChannel::onDevEvent( METAEVENT* pMetaEvent )
- {
- ASSERT(pMetaEvent != NULL);
- switch(pMetaEvent->evttype)
- {
- case TDX_PLAY: // 放音结束
- __onPlayEnd();
- break;
- case TDX_RECORD: // 录音结束
- __onRecordEnd();
- break;
- case TDX_GETDIG: // 取按键结束
- __onGotDigit();
- break;
- case TDX_PLAYBEGIN: // 开始放音
- __onPlayStart();
- break;
- case TDX_RECBEGIN: // 开始录音
- __onRecordStart();
- break;
- case TDX_ERROR: // 出错处理
- __onError();
- break;
- }
- }
- /*****************************************************************
- **【函数名称】 state
- **【函数功能】 返回状态字符串
- **【参数】
- **【返回值】
- ****************************************************************/
- LPCTSTR CDspChannel::getStateStr( void ) const
- {
- switch(m_Job)
- {
- case DEV_VOC_JOB_NONE: return (m_IsRecording ? _T("录音中") : _T("空闲"));
- case DEV_VOC_JOB_PLAY_TONE: return _T("播放信号音");
- case DEV_VOC_JOB_PLAY_FILE: return _T("放音中");
- case DEV_VOC_JOB_PLAY_DTMF: return _T("放音收号");
- case DEV_VOC_JOB_GET_DTMF: return _T("收号");
- default: return _T("未知");
- }
- }
|