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

📄 ixjunix.cxx

📁 sloedgy open sip stack source code
💻 CXX
📖 第 1 页 / 共 5 页
字号:

  int stat = IOCTL2(os_handle, PHONE_PLAY_CODEC, CodecInfo[writeCodecType].mode);
  if (stat != 0) {
    PTRACE(1, "IXJ\tSecond try on set play codec");
    stat = IOCTL2(os_handle, PHONE_PLAY_CODEC, CodecInfo[writeCodecType].mode);
    if (stat != 0)
      return FALSE;
  }

  // PHONE_PLAY_DEPTH does not set return value
  IOCTL2(os_handle, PHONE_PLAY_DEPTH, 1);

  // start the codec
  stat = IOCTL(os_handle, PHONE_PLAY_START);
  if (stat != 0) {
    PTRACE(1, "IXJ\tSecond try on start play codec");
    stat = IOCTL(os_handle, PHONE_PLAY_START);
    if (stat != 0)
      return FALSE;
  }

  // wait for codec to become writable. If it doesn't happen after 100ms, give error
  fd_set wfds;
  struct timeval ts;

  for (;;) {

    FD_ZERO(&wfds);
    FD_SET(os_handle, &wfds);
    ts.tv_sec = 0;
    ts.tv_usec = 100*1000;

    stat = ::select(os_handle+1, NULL, &wfds, NULL, &ts);

    if (stat > 0)
      break;
    else if (stat == 0) {
      PTRACE(1, "IXJ\tWrite timeout on startup");
      return FALSE;
    } 

    if (errno != EINTR) {
      PTRACE(1, "IXJ\tWrite error on startup");
      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 line)
{
  if (inRawMode)
    return FALSE;

  PTRACE(2, "IXJ\tSetting raw codec mode");

  // save the current volumes
  savedPlayVol    = userPlayVol;
  savedRecVol     = userRecVol;
  savedAEC        = aecLevel;

  if (!SetReadFormat (line, CodecInfo[0].mediaFormat) ||
      !SetWriteFormat(line, CodecInfo[0].mediaFormat)) {
    PTRACE(1, "IXJ\t Failed to set raw codec");
    StopReadCodec(line);
    StopWriteCodec(line);
    return FALSE;
  }

  // set the new (maximum) volumes
  SetAEC         (line, AECOff);
  SetRecordVolume(line, 100);
  SetPlayVolume  (line, 100);

  // stop values from changing
  inRawMode = TRUE;

  return TRUE;
}


BOOL OpalIxJDevice::StopReadCodec(unsigned line)
{
  PTRACE(3, "xJack\tStopping read codec");

  PWaitAndSignal mutex(readMutex);

  if (!readStopped) {
    IOCTL(os_handle, PHONE_REC_STOP);
    readStopped = TRUE;
  }

  return OpalLineInterfaceDevice::StopReadCodec(line);
}


BOOL OpalIxJDevice::StopWriteCodec(unsigned line)
{
  PTRACE(3, "xJack\tStopping write codec");

  PWaitAndSignal mutex(readMutex);

  if (!writeStopped) {
    IOCTL(os_handle, PHONE_PLAY_STOP);
    writeStopped = TRUE;
  }

  return OpalLineInterfaceDevice::StopWriteCodec(line);
}


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

  StopReadCodec(line);
  StopWriteCodec(line);

  // allow values to change again
  inRawMode = FALSE;

  SetPlayVolume  (line, savedPlayVol);
  SetRecordVolume(line, savedRecVol);
  SetAEC         (line, savedAEC);

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


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

BOOL OpalIxJDevice::SetReadFrameSize(unsigned, PINDEX)
{
  return FALSE;
}

static void G728_Pack(const unsigned short * unpacked, BYTE * packed)
{
  packed[0] =                                ((unpacked[0] & 0x3fc) >> 2);
  packed[1] = ((unpacked[0] & 0x003) << 6) | ((unpacked[1] & 0x3f0) >> 4);
  packed[2] = ((unpacked[1] & 0x00f) << 4) | ((unpacked[2] & 0x3c0) >> 6);
  packed[3] = ((unpacked[2] & 0x03f) << 2) | ((unpacked[3] & 0x300) >> 8);
  packed[4] =  (unpacked[3] & 0x0ff);
}

static const PINDEX G723count[4] = { 24, 20, 4, 1 };


BOOL OpalIxJDevice::ReadFrame(unsigned, void * buffer, PINDEX & count)
{
  {
    PWaitAndSignal rmutex(readMutex);

    count = 0;

    if (readStopped) {
        PTRACE(1, "IXJ\tRead stopped, so ReadFrame returns false");    
        return FALSE;
    }

    if (writeStopped) {
      PThread::Sleep(30);
      memset(buffer, 0, readFrameSize);
      switch (CodecInfo[readCodecType].mode) {
        case G723_63:
        case G723_53:
          *((DWORD *)buffer) = 0x02;
          count = 4;
          break;
        case G729B:
          *((WORD *)buffer) = 0;
          count = 2;
          break;
        default:
          memset(buffer, 0, readFrameSize);
          count = readFrameSize;
          break;
      }
      return TRUE;
    }
  
    WORD temp_frame_buffer[48];   // 30ms = 12 frames = 48 vectors = 48 WORDS for unpacked vectors
    void * readBuf;
    int    readLen;
    switch (CodecInfo[readCodecType].mode) {
      case G728 :
        readBuf = temp_frame_buffer;
        readLen = sizeof(temp_frame_buffer);
        break;
      case G729B :
        readBuf = temp_frame_buffer;
        readLen = 12;
        break;
      default :
        readBuf = buffer;
        readLen = readFrameSize;
    }
  
    for (;;) {
      fd_set rfds;
      FD_ZERO(&rfds);
      FD_SET(os_handle, &rfds);
      struct timeval ts;
      ts.tv_sec = 30;
      ts.tv_usec = 0;
  #if PTRACING
      PTime then;
  #endif
      int stat = ::select(os_handle+1, &rfds, NULL, NULL, &ts);
      if (stat == 0) {
        PTRACE(1, "IXJ\tRead timeout:" << (PTime() - then));
        return FALSE;
      }
      
      if (stat > 0) {
        stat = ::read(os_handle, readBuf, readLen);
        if (stat == (int)readLen)
          break;
      }
  
      if ((stat >= 0) || (errno != EINTR)) {
        PTRACE(1, "IXJ\tRead error = " << errno);
        return FALSE;
      }
  
      PTRACE(1, "IXJ\tRead EINTR");
    }
  
    switch (CodecInfo[readCodecType].mode) {
      case G723_63:
      case G723_53:
        count = G723count[(*(BYTE *)readBuf)&3];
        break;
  
      case G728 :
        // for G728, pack four x 4 vectors
        PINDEX i;
        for (i = 0; i < 12; i++)
          G728_Pack(temp_frame_buffer+i*4, ((BYTE *)buffer)+i*5);
        count = readFrameSize;
        break;
  
      case G729B :
        switch (temp_frame_buffer[0]) {
          case 0 : // Silence
            memset(buffer, 0, 10);
            count = 10;
            break;
          case 1 : // Signal
            memcpy(buffer, &temp_frame_buffer[1], 10);
            count = 10;
            break;
          case 2 : // VAD
            memcpy(buffer, &temp_frame_buffer[1], 2);
            count = 2;
            break;
          default : // error
            PTRACE(1, "IXJ\tIllegal value from codec in G729");
            return FALSE;
        }
        break;
  
      default :
        count = readFrameSize;
    }
  }

  PThread::Yield();
  
  return TRUE;
}

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

BOOL OpalIxJDevice::SetWriteFrameSize(unsigned, PINDEX)
{
  return FALSE;
}

static void G728_Unpack(const BYTE * packed, unsigned short * unpacked)
{
  unpacked[0] = ( packed[0]         << 2) | ((packed[1] & 0xc0) >> 6);
  unpacked[1] = ((packed[1] & 0x3f) << 4) | ((packed[2] & 0xf0) >> 4);
  unpacked[2] = ((packed[2] & 0x0f) << 6) | ((packed[3] & 0xfc) >> 2);
  unpacked[3] = ((packed[3] & 0x03) << 8) |   packed[4];
}

BOOL OpalIxJDevice::WriteFrame(unsigned, const void * buffer, PINDEX count, PINDEX & written)
{
  {
    PWaitAndSignal rmutex(readMutex);
  
    written = 0;
  
    if (writeStopped) 
      return FALSE;
  
    if (readStopped) {
      PThread::Sleep(30);
      written = writeFrameSize;
      return TRUE;
    }
  
    WORD temp_frame_buffer[48];
    const void * writeBuf;
    int writeLen;
  
    switch (CodecInfo[writeCodecType].mode) {
      case G723_63:
      case G723_53:
        writeBuf = buffer;
        writeLen = 24;
        written = G723count[(*(BYTE *)buffer)&3];
        break;
  
      case G728 :
        writeBuf = temp_frame_buffer;
        writeLen = sizeof(temp_frame_buffer);
  
        // for G728, unpack twelve x 4 vectors
        PINDEX i;
        for (i = 0; i < 12; i++) 
          G728_Unpack(((const BYTE *)buffer)+i*5, temp_frame_buffer+i*4);
        written = 60;
        break;
  
      case G729B :
        writeBuf = temp_frame_buffer;
        writeLen = 12;
  
        if (count == 2) {
          temp_frame_buffer[0] = 2;
          temp_frame_buffer[1] = *(const WORD *)buffer;
          memset(&temp_frame_buffer[2], 0, 8);
          written = 2;
        }
        else {
          if (memcmp(buffer, "\0\0\0\0\0\0\0\0\0", 10) != 0)
            temp_frame_buffer[0] = 1;
          else
            temp_frame_buffer[0] = 0;
          memcpy(&temp_frame_buffer[1], buffer, 10);
          written = 10;
        }
        break;
  
      default :
        writeBuf = buffer;
        writeLen = writeFrameSize;
        written = writeFrameSize;
    }
  
    if (count < written) {
      osError = EINVAL;
      PTRACE(1, "xJack\tWrite of too small a buffer : " << count << " vs " << written);
      return FALSE;
    }
  
    for (;;) {
  
      fd_set wfds;
      FD_ZERO(&wfds);
      FD_SET(os_handle, &wfds);
      struct timeval ts;
      ts.tv_sec = 5;
      ts.tv_usec = 0;
      int stat = ::select(os_handle+1, NULL, &wfds, NULL, &ts);
  
      if (stat == 0) {
        PTRACE(1, "IXJ\tWrite timeout");
        return FALSE;
      }
  
      if (stat > 0) {
        stat = ::write(os_handle, writeBuf, writeLen);
        if (stat == (int)writeLen)
          break;
      }
  
      if ((stat >= 0) || (errno != EINTR)) {
        PTRACE(1, "IXJ\tWrite error = " << errno);
        return FALSE;
      }

      PTRACE(1, "IXJ\tWrite EINTR");
    }
  }

//  PTRACE(4, "IXJ\tWrote " << writeLen << " bytes to codec");

  PThread::Yield();

  return TRUE;
}


unsigned OpalIxJDevice::GetAverageSignalLevel(unsigned, BOOL playback)
{
  return IOCTL(os_handle, playback ? PHONE_PLAY_LEVEL : PHONE_REC_LEVEL);
}


BOOL OpalIxJDevice::EnableAudio(unsigned line, BOOL enable)
{
  if (line >= GetLineCount())
    return FALSE;

  int port = PORT_SPEAKER;

  if (enable) {
    if (enabledAudioLine != line) {
      if (enabledAudioLine != UINT_MAX && exclusiveAudioMode) {
        PTRACE(3, "xJack\tEnableAudio on port when already enabled other port.");
        return FALSE;
      }
      enabledAudioLine = line;
    }
    port = (line == POTSLine) ? PORT_POTS : PORT_PSTN;
  }
  else
    enabledAudioLine = UINT_MAX;

  return ConvertOSError(IOCTL2(os_handle, IXJCTL_PORT, port));
}


BOOL OpalIxJDevice::IsAudioEnabled(unsigned line)
{
  return enabledAudioLine == line;
}

PINDEX OpalIxJDevice::LogScaleVolume(unsigned line, PINDEX volume, BOOL isPlay)
{
  PINDEX dspMax = isPlay ? 0x100 : 0x200;

  switch (dwCardType) {

⌨️ 快捷键说明

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