⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ixjwin32.cxx

📁 sloedgy open sip stack source code
💻 CXX
📖 第 1 页 / 共 5 页
字号:
    PTRACE(3, "xJack\tDetected dial or busy tone, line disconnected.");
    return TRUE;
  }

  return FALSE;
}


BOOL OpalIxJDevice::SetLineToLineDirect(unsigned line1, unsigned line2, BOOL connect)
{
  if (line1 >= GetLineCount() || line2 >= GetLineCount())
    return FALSE;

  if (line1 == line2)
    return FALSE;

  DWORD dwResult = 0;
  return IoControl(IOCTL_DevCtrl_SetPotsToSlic, connect ? 0 : 1, &dwResult) && dwResult != 0;
}


BOOL OpalIxJDevice::IsLineToLineDirect(unsigned line1, unsigned line2)
{
  if (line1 >= GetLineCount() || line2 >= GetLineCount())
    return FALSE;

  if (line1 == line2)
    return FALSE;

  // The IOCTL_DevCtrl_GetPotsToSlic is broken unless the line test has been
  // performed and there is a PSTN line present.
  if (!IsLinePresent(PSTNLine))
    return FALSE;

  DWORD dwResult = 1;
  if (!IoControl(IOCTL_DevCtrl_GetPotsToSlic, 0, &dwResult))
    return FALSE;

  return dwResult == 0;
}



static const struct {
  const char * mediaFormat;
  unsigned dspBitMask:3; // bit0=8020,bit1=8021,bit2=8022
  unsigned isG729:1;
  unsigned isG7231:1;
  unsigned vad:1;
  PINDEX frameSize;
  DWORD recordMode;
  DWORD recordRate;
  DWORD playbackMode;
  DWORD playbackRate;
} CodecInfo[] = {
  { OPAL_PCM16,         7, 0, 0, 0,   0, RECORD_MODE_16LINEAR,   0,                   PLAYBACK_MODE_16LINEAR,   0                     },
  { OPAL_G711_ULAW_64K, 7, 0, 0, 0,   0, RECORD_MODE_ULAW,       0,                   PLAYBACK_MODE_ULAW,       0                     },
  { OPAL_G711_ALAW_64K, 7, 0, 0, 0,   0, RECORD_MODE_ALAW,       0,                   PLAYBACK_MODE_ALAW,       0                     },
  { OPAL_G728,          2, 0, 0, 0,  20, RECORD_MODE_TRUESPEECH, RECORD_RATE_G728,    PLAYBACK_MODE_TRUESPEECH, PLAYBACK_RATE_G728    },
  { OPAL_G729,          6, 1, 0, 0,  10, RECORD_MODE_TRUESPEECH, RECORD_RATE_G729,    PLAYBACK_MODE_TRUESPEECH, PLAYBACK_RATE_G729    },
  { OPAL_G729AB,        6, 1, 0, 1,  10, RECORD_MODE_TRUESPEECH, RECORD_RATE_G729,    PLAYBACK_MODE_TRUESPEECH, PLAYBACK_RATE_G729    },

  // these two lines should be for the 5k3 codec, but this does not work properly in the driver so we lie
  { OPAL_G7231_5k3,     7, 0, 1, 0,  24, RECORD_MODE_TRUESPEECH, RECORD_RATE_G723_63, PLAYBACK_MODE_TRUESPEECH, PLAYBACK_RATE_G723_63 },
  { OPAL_G7231A_5k3,    7, 0, 1, 1,  24, RECORD_MODE_TRUESPEECH, RECORD_RATE_G723_63, PLAYBACK_MODE_TRUESPEECH, PLAYBACK_RATE_G723_63 },

  { OPAL_G7231_6k3,     7, 0, 1, 0,  24, RECORD_MODE_TRUESPEECH, RECORD_RATE_G723_63, PLAYBACK_MODE_TRUESPEECH, PLAYBACK_RATE_G723_63 },
  { OPAL_G7231A_6k3,    7, 0, 1, 1,  24, RECORD_MODE_TRUESPEECH, RECORD_RATE_G723_63, PLAYBACK_MODE_TRUESPEECH, PLAYBACK_RATE_G723_63 },

};


OpalMediaFormatList OpalIxJDevice::GetMediaFormats() const
{
  OpalMediaFormatList codecs;

  OpalIxJDevice * unconstThis = (OpalIxJDevice *)this;

  DWORD dwIdCode = 0;
  if (unconstThis->IoControl(IOCTL_DevCtrl_GetIdCode, 0, &dwIdCode)) {
    unsigned dspBit = 1 << (dwIdCode&3);
    PINDEX codec = PARRAYSIZE(CodecInfo);
    while (codec-- > 0) {
      BOOL add = (CodecInfo[codec].dspBitMask&dspBit) != 0;
      if (add && CodecInfo[codec].isG729) {
        DWORD hasG729 = 1;
        add = unconstThis->IoControl(IOCTL_Device_GetG729Enable, 0, &hasG729) && hasG729;
      }
      if (add)
        codecs += CodecInfo[codec].mediaFormat;
    }
  }

  return codecs;
}


static PINDEX FindCodec(const OpalMediaFormat & mediaFormat)
{
  for (PINDEX codecType = 0; codecType < PARRAYSIZE(CodecInfo); codecType++) {
    if (mediaFormat == CodecInfo[codecType].mediaFormat)
      return codecType;
  }

  return P_MAX_INDEX;
}


BOOL OpalIxJDevice::SetReadFormat(unsigned line, const OpalMediaFormat & mediaFormat)
{
  StopReadCodec(line);

  PWaitAndSignal mutex(readMutex);

  IoControl(IOCTL_Record_Stop);

  readCodecType = FindCodec(mediaFormat);
  if (readCodecType == P_MAX_INDEX) {
    PTRACE(1, "xJack\tUnsupported read codec requested: " << mediaFormat);
    return FALSE;
  }

  if (!writeStopped && readCodecType != writeCodecType) {
    PTRACE(1, "xJack\tAsymmetric codecs requested: "
              "read=" << CodecInfo[readCodecType].mediaFormat
           << " write=" << CodecInfo[writeCodecType].mediaFormat);
    return FALSE;
  }

  PTRACE(3, "xJack\tSetReadFormat(" << CodecInfo[readCodecType].mediaFormat << ')');

  if (!IoControl(IOCTL_Codec_SetKHz, 8000))
    return FALSE;

  if (!IoControl(IOCTL_Record_SetBufferChannelLimit, 1))
    return FALSE;

  DWORD mode;
  do {
    if (!IoControl(IOCTL_Record_SetRECMODE, CodecInfo[readCodecType].recordMode))
      return FALSE;
    if (!IoControl(IOCTL_Record_GetRECMODE, 0, &mode))
      return FALSE;
    PTRACE_IF(3, mode != CodecInfo[readCodecType].recordMode,
              "xJack\tSetRECMODE failed (" << mode << " -> " <<
              CodecInfo[readCodecType].recordMode << "), retrying");
  } while (mode != CodecInfo[readCodecType].recordMode);

  DWORD rate;
  do {
    if (!IoControl(IOCTL_Record_SetRate, CodecInfo[readCodecType].recordRate))
      return FALSE;
    if (!IoControl(IOCTL_Record_GetRate, 0, &rate))
      return FALSE;
    PTRACE_IF(3, rate != CodecInfo[readCodecType].recordRate,
              "xJack\tRecord_SetRate failed (" << rate << " -> " <<
              CodecInfo[readCodecType].recordRate << "), retrying");
  } while (rate != CodecInfo[readCodecType].recordRate);

  readFrameSize = CodecInfo[readCodecType].frameSize;
  if (readFrameSize == 0) {
    DWORD frameWords;
    if (IoControl(IOCTL_Record_GetFrameSize, 0, &frameWords))
      readFrameSize = frameWords*2;
    else {
      PTRACE(1, "xJack\tCould not get record frame size.");
      return FALSE;
    }
  }

  SetVAD(line, CodecInfo[readCodecType].vad);

  if (!IoControl(driverVersion >= NEW_DRIVER_VERSION ? IOCTL_Record_Start
                                                     : IOCTL_Record_Start_Old))
    return FALSE;

  readStopped = FALSE;

  return TRUE;
}


BOOL OpalIxJDevice::SetWriteFormat(unsigned line, const OpalMediaFormat & mediaFormat)
{
  StopWriteCodec(line);

  PWaitAndSignal mutex(writeMutex);

  IoControl(IOCTL_Playback_Stop);

  writeCodecType = FindCodec(mediaFormat);
  if (writeCodecType == P_MAX_INDEX) {
    PTRACE(1, "xJack\tUnsupported write codec requested: " << mediaFormat);
    return FALSE;
  }

  if (!readStopped && writeCodecType != readCodecType) {
    PTRACE(1, "xJack\tAsymmetric codecs requested: "
              "read=" << CodecInfo[readCodecType].mediaFormat
           << " write=" << CodecInfo[writeCodecType].mediaFormat);
    return FALSE;
  }

  PTRACE(3, "xJack\tSetWriteFormat(" << CodecInfo[writeCodecType].mediaFormat << ')');

  if (!IoControl(IOCTL_Codec_SetKHz, 8000))
    return FALSE;

  if (!IoControl(IOCTL_Playback_SetBufferChannelLimit, 1))
    return FALSE;

  DWORD mode;
  do {
    if (!IoControl(IOCTL_Playback_SetPLAYMODE, CodecInfo[writeCodecType].playbackMode))
      return FALSE;
    if (!IoControl(IOCTL_Playback_GetPLAYMODE, 0, &mode))
      return FALSE;
    PTRACE_IF(2, mode != CodecInfo[writeCodecType].playbackMode,
              "xJack\tSetPLAYMODE failed (" << mode << " -> " <<
              CodecInfo[writeCodecType].playbackMode << "), retrying");
  } while (mode != CodecInfo[writeCodecType].playbackMode);

  DWORD rate;
  do {
    if (!IoControl(IOCTL_Playback_SetRate, CodecInfo[writeCodecType].playbackRate))
      return FALSE;
    if (!IoControl(IOCTL_Playback_GetRate, 0, &rate))
      return FALSE;
    PTRACE_IF(2, rate != CodecInfo[writeCodecType].playbackRate,
              "xJack\tPlayback_SetRate failed (" << rate << " -> " <<
              CodecInfo[writeCodecType].playbackRate << "), retrying");
  } while (rate != CodecInfo[writeCodecType].playbackRate);

  writeFrameSize = CodecInfo[writeCodecType].frameSize;
  if (writeFrameSize == 0) {
    DWORD frameWords;
    if (IoControl(IOCTL_Playback_GetFrameSize, 0, &frameWords))
      writeFrameSize = frameWords*2;
    else {
      PTRACE(1, "xJack\tCould not get playback frame size.");
      return FALSE;
    }
  }

  SetVAD(line, CodecInfo[writeCodecType].vad);

  if (!IoControl(driverVersion >= NEW_DRIVER_VERSION ? IOCTL_Playback_Start
                                                     : IOCTL_Playback_Start_Old))
    return FALSE;

  writeStopped = FALSE;
  return TRUE;
}


OpalMediaFormat OpalIxJDevice::GetReadFormat(unsigned)
{
  if (readCodecType == P_MAX_INDEX)
    return "";
  return CodecInfo[readCodecType].mediaFormat;
}


OpalMediaFormat OpalIxJDevice::GetWriteFormat(unsigned)
{
  if (writeCodecType == P_MAX_INDEX)
    return "";
  return CodecInfo[writeCodecType].mediaFormat;
}


BOOL OpalIxJDevice::SetRawCodec(unsigned)
{
  if (inRawMode)
    return FALSE;

  PTRACE(3, "xJack\tSetRawCodec()");

  // Default to 30ms frames of 16 bit PCM data
  readFrameSize = 480;
  writeFrameSize = 480;

  if (hReadEvent == NULL)
    hReadEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
  if (hWriteEvent == NULL)
    hWriteEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

  HANDLE hEventArr[2];

  if (GetOperatingSystem() == IsWindows9x) {
    CHAR K32Path[MAX_PATH];
    HINSTANCE hK32;
    HANDLE (WINAPI *OpenVxDHandle)(HANDLE);

    GetSystemDirectory(K32Path, MAX_PATH);
    strcat(K32Path, "\\kernel32.dll");
    hK32 = LoadLibrary(K32Path);

    OpenVxDHandle = (HANDLE(WINAPI *)(HANDLE))GetProcAddress(hK32, "OpenVxDHandle");
    hEventArr[0] = OpenVxDHandle(hReadEvent);
    hEventArr[1] = OpenVxDHandle(hWriteEvent);
    FreeLibrary(hK32);
  }
  else
  {
    hEventArr[0] = hReadEvent;
    hEventArr[1] = hWriteEvent;
  }

  readMutex.Wait();
  writeMutex.Wait();

  DWORD dwReturn, dwBytesReturned;
  inRawMode = IoControl(IOCTL_Fax_Start,
                        hEventArr, sizeof(hEventArr),
                        &dwReturn, sizeof(dwReturn), &dwBytesReturned);
  readCodecType = writeCodecType = 0;
  readStopped = writeStopped = !inRawMode;

  readMutex.Signal();
  writeMutex.Signal();

  return inRawMode;
}


BOOL OpalIxJDevice::StopReadCodec(unsigned line)
{
  if (inRawMode)
    return StopRawCodec(line);

  PTRACE(3, "xJack\tStopping read codec");

  readMutex.Wait();
  if (!readStopped) {
    readStopped = TRUE;
    IoControl(IOCTL_Record_Stop);
  }
  readMutex.Signal();

  return OpalLineInterfaceDevice::StopReadCodec(line);
}


BOOL OpalIxJDevice::StopWriteCodec(unsigned line)
{
  if (inRawMode)
    return StopRawCodec(line);

  PTRACE(3, "xJack\tStopping write codec");

  writeMutex.Wait();
  if (!writeStopped) {
    writeStopped = TRUE;
    IoControl(IOCTL_Playback_Stop);
  }
  writeMutex.Signal();

  return OpalLineInterfaceDevice::StopWriteCodec(line);
}


BOOL OpalIxJDevice::StopRawCodec(unsigned line)
{
  if (!inRawMode) {
    BOOL ok = StopReadCodec(line);
    return StopWriteCodec(line) && ok;
  }

  PTRACE(3, "xJack\tStopping raw codec");

  readMutex.Wait();
  writeMutex.Wait();
  readStopped = TRUE;
  writeStopped = TRUE;
  BOOL ok = IoControl(IOCTL_Fax_Stop);
  readMutex.Signal();
  writeMutex.Signal();

  inRawMode = FALSE;

  OpalLineInterfaceDevice::StopReadCodec(line);
  OpalLineInterfaceDevice::StopWriteCodec(line);
  return ok;
}


PINDEX OpalIxJDevice::GetReadFrameSize(unsigned)
{
  return readFrameSize;
}


BOOL OpalIxJDevice::SetReadFrameSize(unsigned, PINDEX size)
{
  if (!inRawMode)
    return FALSE;

  readFrameSize = size;
  return TRUE;
}


PINDEX OpalIxJDevice::GetWriteFrameSize(unsigned)
{
  return writeFrameSize;
}


BOOL OpalIxJDevice::SetWriteFrameSize(unsigned, PINDEX size)
{
  if (!inRawMode)
    return FALSE;

  writeFrameSize = size;
  return TRUE;
}


BOOL OpalIxJDevice::ReadFrame(unsigned, void * buffer, PINDEX & count)
{
  count = 0;

  PWaitAndSignal mutex(readMutex);
  if (readStopped)
    return FALSE;

  DWORD dwBytesReturned = 0;
  if (inRawMode) {
    if (WaitForSingleObjectEx(hReadEvent, 1000, TRUE) != WAIT_OBJECT_0) {
      osError = EAGAIN;
      PTRACE(1, "xJack\tRead Timeout!");
      return FALSE;
    }
    IoControl(IOCTL_Fax_Read, NULL, 0, buffer, readFrameSize, &dwBytesReturned);
    count = (PINDEX)dwBytesReturned;
    return TRUE;
  }

  BOOL reblockG729 = CodecInfo[readCodecType].isG729;
  WORD temp_frame_buffer[6];

  PWin32Overlapped overlap;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -