📄 vpblid.cxx
字号:
return FALSE;
PTRACE(4, "VPB\tSetWriteFormat(" << mediaFormat << ')');
lineState[line].writeFormat = FindCodec(mediaFormat);
if (lineState[line].writeFormat == P_MAX_INDEX)
return FALSE;
lineState[line].DTMFplaying = FALSE;
if (vpb_play_buf_start(lineState[line].handle,
CodecInfo[lineState[line].writeFormat].mode) < 0)
return FALSE;
lineState[line].writeIdle = FALSE;
return TRUE;
}
OpalMediaFormat OpalVpbDevice::GetReadFormat(unsigned line)
{
if (lineState[line].readFormat == P_MAX_INDEX)
return "";
return CodecInfo[lineState[line].readFormat].mediaFormat;
}
OpalMediaFormat OpalVpbDevice::GetWriteFormat(unsigned line)
{
if (lineState[line].writeFormat == P_MAX_INDEX)
return "";
return CodecInfo[lineState[line].writeFormat].mediaFormat;
}
BOOL OpalVpbDevice::StopReadCodec(unsigned line)
{
if (line >= MaxLineCount)
return FALSE;
PTRACE(3, "VPB\tStopReadCodec");
if (lineState[line].readIdle)
return FALSE;
PTRACE(3, "VPB\tStopReadCodec before");
vpb_record_terminate(lineState[line].handle);
vpb_record_buf_finish(lineState[line].handle);
PTRACE(3, "VPB\tStopReadCodec after");
lineState[line].readIdle = TRUE;
return TRUE;
}
BOOL OpalVpbDevice::StopWriteCodec(unsigned line)
{
if (line >= MaxLineCount)
return FALSE;
PTRACE(1, "VPB\tStopWriteCodec");
if (lineState[line].writeIdle)
return FALSE;
PTRACE(3, "VPB\tStopWriteCodec before");
vpb_play_terminate(lineState[line].handle);
vpb_play_buf_finish(lineState[line].handle);
PTRACE(3, "VPB\tStopWriteCodec after");
lineState[line].writeIdle = TRUE;
return TRUE;
}
BOOL OpalVpbDevice::SetReadFrameSize(unsigned line, PINDEX size)
{
if (line >= MaxLineCount)
return FALSE;
lineState[line].readFrameSize = size;
return TRUE;
}
BOOL OpalVpbDevice::SetWriteFrameSize(unsigned line, PINDEX size)
{
if (line >= MaxLineCount)
return FALSE;
lineState[line].writeFrameSize = size;
return TRUE;
}
PINDEX OpalVpbDevice::GetReadFrameSize(unsigned line)
{
if (line >= MaxLineCount)
return FALSE;
return lineState[line].readFrameSize;
}
PINDEX OpalVpbDevice::GetWriteFrameSize(unsigned line)
{
if (line >= MaxLineCount)
return FALSE;
return lineState[line].writeFrameSize;
}
BOOL OpalVpbDevice::ReadFrame(unsigned line, void * buf, PINDEX & count)
{
if (line >= MaxLineCount)
return FALSE;
count = lineState[line].readFrameSize;
PTRACE(4, "VPB\tReadFrame before vpb_record_buf_sync");
vpb_record_buf_sync(lineState[line].handle, (char *)buf, (WORD)count);
PTRACE(4, "VPB\tReadFrame after vpb_record_buf_sync");
return TRUE;
}
BOOL OpalVpbDevice::WriteFrame(unsigned line, const void * buf, PINDEX count, PINDEX & written)
{
written = 0;
if (line >= MaxLineCount)
return FALSE;
PTRACE(4, "VPB\tWriteFrame before vpb_play_buf_sync");
vpb_play_buf_sync(lineState[line].handle, (char *)buf,(WORD)count);
PTRACE(4, "VPB\tWriteFrame after vpb_play_buf_sync");
written = count;
return TRUE;
}
BOOL OpalVpbDevice::SetRecordVolume(unsigned line, unsigned volume)
{
if (line >= MaxLineCount)
return FALSE;
return vpb_record_set_gain(lineState[line].handle, (float)(volume/100.0*24.0-12.0)) >= 0;
}
BOOL OpalVpbDevice::SetPlayVolume(unsigned line, unsigned volume)
{
if (line >= MaxLineCount)
return FALSE;
return vpb_play_set_gain(lineState[line].handle, (float)(volume/100.0*24.0-12.0)) >= 0;
}
char OpalVpbDevice::ReadDTMF(unsigned line)
{
if (line >= MaxLineCount)
return '\0';
VPB_DIGITS vd;
vd.term_digits = "";
vd.max_digits = 1;
vd.digit_time_out = 10;
vd.inter_digit_time_out = 10;
char buf[VPB_MAX_STR];
if (vpb_get_digits_sync(lineState[line].handle, &vd, buf) == VPB_DIGIT_MAX) {
PTRACE(3, "VPB\tReadDTMF (digit)" << buf[0]);
return buf[0];
}
return '\0';
}
/*
BOOL OpalVpbDevice::PlayFile(unsigned line, const PString & fn, BOOL syncOff=FALSE)
{
PTRACE(3, "VPB\tSono entrato in PlayFile per leggere il file " << fn << " sulla linea " <<line);
char * filename;
strcpy(filename,fn);
if(syncOff)
{
vpb_play_file_async(lineState[line].handle, filename, VPB_PLAYEND);
}
else
{
vpb_play_file_sync(lineState[line].handle, filename);
}
return TRUE;
}
*/
/*
// Ritorna il codice dell'evento sull'handle lineState[line].handle
int OpalVpbDevice::GetVPBEvent(unsigned line)
{
return vpb_get_event_mask(lineState[line].handle;
}
*/
BOOL OpalVpbDevice::PlayDTMF(unsigned line, const char * digits, DWORD, DWORD)
{
if (line >= MaxLineCount)
return FALSE;
PTRACE(3, "VPB\tPlayDTMF: " << digits);
vpb_dial_sync(lineState[line].handle, (char *)digits);
vpb_dial_sync(lineState[line].handle, ",");
return TRUE;
}
int OpalVpbDevice::GetOSHandle(unsigned line)
{
return lineState[line].handle;
}
unsigned OpalVpbDevice::IsToneDetected(unsigned line)
{
if (line >= MaxLineCount) {
PTRACE(3, "VPB\tTone Detect no tone detected, line is > MaxLineCount (" << MaxLineCount << ")");
return NoTone;
}
VPB_EVENT event;
if (vpb_get_event_ch_async(lineState[line].handle, &event) == VPB_NO_EVENTS) {
PTRACE(3, "VPB\tTone Detect no events on line " << line << " in tone detected");
return NoTone;
}
if (event.type == VPB_RING) {
PTRACE(3, "VPB\t Tone Detect: Ring tone (generated from ring event)");
return RingTone;
}
if (event.type != VPB_TONEDETECT) {
PTRACE(3, "VPB\tTone Detect. Event type is not (ring | tone). No tone detected.");
return NoTone;
}
switch (event.data) {
case VPB_DIAL :
PTRACE(3, "VPB\tTone Detect: Dial tone.");
return DialTone;
case VPB_RINGBACK :
PTRACE(3, "VPB\tTone Detect: Ring tone.");
return RingTone;
case VPB_BUSY :
PTRACE(3, "VPB\tTone Detect: Busy tone.");
return BusyTone;
case VPB_GRUNT :
PTRACE(3, "VPB\tTone Detect: Grunt tone.");
break;
}
return NoTone;
}
BOOL OpalVpbDevice::PlayTone(unsigned line, CallProgressTones tone)
{
VPB_TONE vpbtone;
PTRACE(3, "VPB\tPlayTone STARTED");
switch(tone) {
case DialTone:
PTRACE(3, "VPB\tPlayTone DialTone");
vpbtone.freq1 = 425;
vpbtone.freq2 = 450;
vpbtone.freq3 = 400;
vpbtone.level1 = -12;
vpbtone.level2 = -18;
vpbtone.level3 = -18;
vpbtone.ton = 30000;
vpbtone.toff = 10;
lineState[line].myToneThread = new ToneThread(
lineState[line].handle,
vpbtone
);
break;
case BusyTone:
vpbtone.freq1 = 425;
vpbtone.freq2 = 0;
vpbtone.freq3 = 0;
vpbtone.level1 = -12;
vpbtone.level2 = -100;
vpbtone.level3 = -100;
vpbtone.ton = 325;
vpbtone.toff = 750;
lineState[line].myToneThread = new ToneThread(
lineState[line].handle,
vpbtone
);
break;
default:
return FALSE;
}
return TRUE;
}
BOOL OpalVpbDevice::StopTone(unsigned line)
{
PTRACE(3, "VPB\tStopTone STARTED");
if (lineState[line].myToneThread) {
delete lineState[line].myToneThread;
lineState[line].myToneThread = NULL;
}
PTRACE(3, "VPB\tStopTone FINSISHED");
return TRUE;
}
BOOL OpalVpbDevice::PlayAudio(unsigned line, const PString & fn)
{
PTRACE(3, "VPB\tPlayAudio starting a new Audio Thread on line " << line << " with file " << fn);
vpb_play_file_async(lineState[line].handle, (char *)&fn, VPB_PLAYEND);
/*
lineState[line].myAudioThread = new AudioThread(
*/
return TRUE;
}
BOOL OpalVpbDevice::StopAudio(unsigned line)
{
PTRACE(3, "VPB\tStopAudio STARTED");
/*
if (lineState[line].myAudioThread) {
delete lineState[line].myAudioThread;
lineState[line].myAudioThread = NULL;
}
*/
vpb_play_terminate(lineState[line].handle);
PTRACE(3, "VPB\tStopAudio FINISHED");
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
ToneThread::ToneThread(int ahandle, VPB_TONE avpbtone) : PThread(10000, NoAutoDeleteThread) {
handle = ahandle;
vpbtone = avpbtone;
Resume();
}
ToneThread::~ToneThread() {
PTRACE(3, "VPB\tToneThread Destructor STARTED");
vpb_tone_terminate(handle);
shutdown.Signal();
WaitForTermination();
PTRACE(3, "VPB\tToneThread Destructor FINISHED");
}
void ToneThread::Main() {
PTRACE(3, "VPB\tToneThread Main STARTED");
while (!shutdown.Wait(10)) {
vpb_playtone_sync(handle, &vpbtone);
PTRACE(3, "VPB\tvpl_playtone_sync returned");
}
PTRACE(3, "VPB\tToneThread Main FINISHED");
}
#endif // HAS_VPB
/////////////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -