#include "StdAfx.h" #include "Mixer.h" #include "MC.h" #include "DspChannel.h" CMixer::CMixer(IMixerHost& Host) : m_Host(Host), m_pPlayDsp(NULL), m_pRecordDsp(NULL), m_pMonitorChan(NULL) { } CMixer::~CMixer(void) { } /***************************************************************** **【函数名称】 __attachDspCh **【函数功能】 关联放音DSP通道 **【参数】 **【返回值】 成功true,失败false ****************************************************************/ bool CMixer::__attachPlayDsp( void ) { CDspChannel* pDspCh = m_pPlayDsp; if(pDspCh == NULL) { pDspCh = CMC::GetInstance().allocDspCh(m_Host.node(), DEVICE_BRD_NO_ANY); ASSERT(pDspCh != NULL); if(pDspCh == NULL) return false; } if(ISX_nr_scroute(m_Host.mixHandle(), m_Host.normalType(), pDspCh->handle(), pDspCh->type(), SC_FULLDUP) == 0) { m_pPlayDsp = pDspCh; pDspCh->attach(this); return true; } return false; } /***************************************************************** **【函数名称】 __detachDsp **【函数功能】 解关联放音DSP通道 **【参数】 **【返回值】 ****************************************************************/ void CMixer::__detachPlayDsp( void ) { if(m_pPlayDsp == NULL) return; m_pPlayDsp->attach(NULL); m_pPlayDsp->reset(); ISX_nr_scunroute(m_Host.mixHandle(), m_Host.normalType(), m_pPlayDsp->handle(), m_pPlayDsp->type(), SC_FULLDUP); m_pPlayDsp = NULL; } /***************************************************************** **【函数名称】 __attachRecordDsp **【函数功能】 关联录音DSP通道 **【参数】 **【返回值】 成功true,失败false ****************************************************************/ bool CMixer::__attachRecordDsp( void ) { CDspChannel* pDspCh = m_pRecordDsp; if(pDspCh == NULL) { LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{Mixer}:关联录音,查找空闲DSP通道,host.node[%d]"), m_Host.node()); pDspCh = CMC::GetInstance().allocDspCh(m_Host.node(), DEVICE_BRD_NO_ANY); ASSERT(pDspCh != NULL); if(pDspCh == NULL) return false; } if(ISX_nr_scroute(m_Host.mixHandle(), m_Host.mixType(), pDspCh->handle(), pDspCh->type(), SC_HALFDUP) == 0) { LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{Mixer}: 关联录音DSP通道成功,Host[%d],type[%d],[%d], DSP[%d-%d-%d],type[%d],[%d]"), m_Host.node(), m_Host.mixType(), m_Host.mixHandle(), pDspCh->nodeNo(), pDspCh->boardNo(), pDspCh->chanNo(), pDspCh->type(), pDspCh->handle()); m_pRecordDsp = pDspCh; pDspCh->attach(this); return true; }else { LOGGER(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{Mixer}: 关联录音DSP通道失败,ErrorMessage=%s"), ISX_ATDV_ERRMSGP(m_Host.mixHandle())); LOGGER(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{Mixer}: 关联录音DSP通道失败,dspch,ErrorMessage=%s"), ISX_ATDV_ERRMSGP(pDspCh->handle())); LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{Mixer}: 关联录音DSP通道失败,Host[%d],type[%d],[%d], DSP[%d-%d-%d],type[%d],[%d]"), m_Host.node(), m_Host.mixType(), m_Host.mixHandle(), pDspCh->nodeNo(), pDspCh->boardNo(), pDspCh->chanNo(), pDspCh->type(), pDspCh->handle()); } return false; } /***************************************************************** **【函数名称】 __detachDsp **【函数功能】 解关联录音DSP通道 **【参数】 **【返回值】 ****************************************************************/ void CMixer::__detachRecordDsp( void ) { if(m_pRecordDsp == NULL) return; m_pRecordDsp->attach(NULL); m_pRecordDsp->reset(); ISX_nr_scunroute(m_Host.mixHandle(), m_Host.mixType(), m_pRecordDsp->handle(), m_pRecordDsp->type(), SC_HALFDUP); m_pRecordDsp = NULL; } /***************************************************************** **【函数名称】 playSound **【函数功能】 放音 **【参数】 **【返回值】 ****************************************************************/ bool CMixer::playSound( PlayVoiceContent* pContent ) { if(!__attachPlayDsp()) return false; return m_pPlayDsp->playSound(pContent); } /***************************************************************** **【函数名称】 playTone **【函数功能】 播放信号音 **【参数】 Type 信号音类型 **【返回值】 ****************************************************************/ bool CMixer::playTone( int Type ) { if(Type == CHANNEL_TONE_NULL) { if(m_pPlayDsp == NULL) return false; __detachPlayDsp(); return true; } else { if(!__attachPlayDsp()) return false; return m_pPlayDsp->playTone(Type); } } /***************************************************************** **【函数名称】 playStop **【函数功能】 停止放音 **【参数】 **【返回值】 ****************************************************************/ bool CMixer::playStop( void ) { if(m_pPlayDsp == NULL) return false; __detachPlayDsp(); return true; } /***************************************************************** **【函数名称】 startRecord **【函数功能】 开始录音 **【参数】 **【返回值】 ****************************************************************/ bool CMixer::startRecord( RecordContent* pContent ) { ASSERT(pContent != NULL); if(m_pRecordDsp == NULL) if(!__attachRecordDsp()) return false; return m_pRecordDsp->startRecord(pContent); } /***************************************************************** **【函数名称】 stopRecord **【函数功能】 停止录音 **【参数】 **【返回值】 ****************************************************************/ bool CMixer::stopRecord( void ) { if(m_pRecordDsp == NULL) return false; return m_pRecordDsp->stopRecord(); } /***************************************************************** **【函数名称】 release **【函数功能】 释放资源 **【参数】 **【返回值】 ****************************************************************/ void CMixer::release( void ) { if(m_pMonitorChan != NULL) { ISX_nr_scunroute(m_Host.mixHandle(), m_Host.normalType(), m_pMonitorChan->handle(), m_pMonitorChan->type(), SC_HALFDUP); m_pMonitorChan = NULL; } __detachPlayDsp(); __detachRecordDsp(); } /***************************************************************** **【函数名称】 setupMonitor **【函数功能】 建立监听 **【参数】 **【返回值】 ****************************************************************/ bool CMixer::setupMonitor( CChannelResource* pMonitorParty ) { ASSERT(pMonitorParty != NULL); if(m_pRecordDsp == NULL){ LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{Mixer}: 建立监听,Host[%d],type[%d],[%d],录音DSP通道空闲"), m_Host.node(), m_Host.mixType(), m_Host.mixHandle()); } else { LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{Mixer}: 建立监听,Host[%d],type[%d],[%d], RecordDSP[%d-%d-%d],type[%d],[%d]"), m_Host.node(), m_Host.mixType(), m_Host.mixHandle(), m_pRecordDsp->nodeNo(), m_pRecordDsp->boardNo(), m_pRecordDsp->chanNo(), m_pRecordDsp->type(), m_pRecordDsp->handle()); } //ASSERT(m_pRecordDsp == NULL); // 录音DSP必须为空,否则混音线路的+R端非空闲,则无法实现监听 if(ISX_nr_scroute(m_Host.mixHandle(), m_Host.mixType(), pMonitorParty->handle(), pMonitorParty->type(), SC_HALFDUP) == 0) //if(ISX_nr_scroute(m_Host.mixHandle(), m_Host.normalType(), pMonitorParty->handle(), pMonitorParty->type(), SC_HALFDUP) == 0) { m_pMonitorChan = pMonitorParty; return true; } return false; } /***************************************************************** **【函数名称】 undoMonitor **【函数功能】 撤销监听 **【参数】 **【返回值】 ****************************************************************/ bool CMixer::undoMonitor( CChannelResource* pMonitorParty ) { if(m_pMonitorChan != NULL) { ASSERT(m_pMonitorChan == pMonitorParty); ISX_nr_scunroute(m_Host.mixHandle(), m_Host.mixType(), m_pMonitorChan->handle(), m_pMonitorChan->type(), SC_HALFDUP); //ISX_nr_scunroute(m_Host.mixHandle(), m_Host.normalType(), m_pMonitorChan->handle(), m_pMonitorChan->type(), SC_HALFDUP); m_pMonitorChan = NULL; return true; } return false; } /***************************************************************** **【函数名称】 onPlayEnd **【函数功能】 放音完毕的处理函数 **【参数】 **【返回值】 ****************************************************************/ void CMixer::onPlayEnd( LPCTSTR lpDtmf ) { //__detachPlayDsp(); 因为毅航设备DTMF检测不建议随机使用DSP通道,故中继线路转坐席之前如要放音则使用同一DSP通道 m_Host.onPlayEnd(lpDtmf); } /***************************************************************** **【函数名称】 undoMonitor **【函数功能】 录音完毕的处理函数 **【参数】 **【返回值】 ****************************************************************/ void CMixer::onRecEnd( UINT TaskId ) { __detachRecordDsp(); m_Host.onRecEnd(TaskId); } /***************************************************************** **【函数名称】 undoMonitor **【函数功能】 Tone音完毕的处理函数 **【参数】 **【返回值】 ****************************************************************/ void CMixer::onToneEnd( int ToneTp ) { __detachPlayDsp(); m_Host.onToneEnd(ToneTp); }