コード例 #1
0
ファイル: osc.cpp プロジェクト: GeoffWaddington/ReaperCSurf
int OscGetInput(OscHandler* osc)
{
  int msgcnt=0;

  if (osc->m_recvq.Available() >= sizeof(int))
  {
    static WDL_Queue s_q;
    osc->m_mutex.Enter();
    int sz=osc->m_recvq.Available();
    s_q.Add(osc->m_recvq.Get(), sz);
    osc->m_recvq.Clear();
    osc->m_mutex.Leave();

    while (s_q.Available() >= sizeof(int))
    {
      int len=*(int*)s_q.Get(sizeof(int));
      REAPER_MAKEBEINTMEM((char*)&len);

      if (len <= 0 || len > MAX_OSC_MSG_LEN || len > s_q.Available()) break;

      if (s_q.Available() > 20 && !strcmp((char*)s_q.Get(), "#bundle"))
      {
        s_q.Advance(16); // past "#bundle" and timestamp
        len=*(int*)s_q.Get(sizeof(int));
        REAPER_MAKEBEINTMEM((char*)&len);

        if (len <= 0 || len > MAX_OSC_MSG_LEN || len > s_q.Available()) break;
      }

      OscMessageRead rmsg((char*)s_q.Get(len), len);

#if OSC_DEBUG_INPUT
      char dump[MAX_OSC_MSG_LEN*2];
      rmsg.DebugDump("recv: ", dump, sizeof(dump));
#ifdef _WIN32
      strcat(dump, "\n");
      OutputDebugString(dump);
#else
      fprintf(stderr, "%s\n", dump);
#endif
#endif

      if (osc->m_recv_enable&2)
      {
        const char* msg=rmsg.GetMessage();
        const float* f=rmsg.PopFloatArg(true);
        CSurf_OnOscControlMessage(msg, f);
      }

      osc->m_handler(osc->m_obj, &rmsg);

      ++msgcnt;
    }    
    s_q.Clear();    
  }

  return msgcnt;
}
コード例 #2
0
bool ChannelPinMapper::LoadState(char* buf, int len)
{
  WDL_Queue chunk;
  chunk.Add(buf, len);
  int* pMagic = WDL_Queue__GetTFromLE(&chunk, (int*)0);
  if (!pMagic || *pMagic != PINMAPPER_MAGIC) return false;
  int* pNCh = WDL_Queue__GetTFromLE(&chunk, (int*) 0);
  int* pNPins = WDL_Queue__GetTFromLE(&chunk, (int*) 0);
  if (!pNCh || !pNPins || !(*pNCh) || !(*pNPins)) return false;
  SetNPins(*pNCh);
  SetNChannels(*pNCh);
  int maplen = *pNPins*sizeof(WDL_UINT64);
  if (chunk.Available() < maplen) return false;
  void* pMap = WDL_Queue__GetDataFromLE(&chunk, maplen, sizeof(WDL_UINT64));
  
  int sz= m_nPins*sizeof(WDL_UINT64);
  if (sz>maplen) sz=maplen;
  memcpy(m_mapping, pMap, sz);
  return true;
}
コード例 #3
0
ファイル: osc.cpp プロジェクト: GeoffWaddington/ReaperCSurf
static unsigned WINAPI OscThreadProc(LPVOID p)
{
  JNL::open_socketlib();

  int sockcnt=0;
  WDL_Queue sendq;
  char hdr[16] = { 0 };
  strcpy(hdr, "#bundle");
  hdr[12]=1; // timetag=immediate

  int i;
  for (i=0; i < s_osc_handlers.GetSize(); ++i)
  {
    OscHandler* osc=s_osc_handlers.Get(i);
    osc->m_recvsock=osc->m_sendsock-1;

    if (osc->m_recv_enable)
    {
      osc->m_recvsock=socket(AF_INET, SOCK_DGRAM, 0);
      if (osc->m_recvsock >= 0)
      {
        int on=1;
        setsockopt(osc->m_recvsock, SOL_SOCKET, SO_BROADCAST, (char*)&on, sizeof(on));
        if (!bind(osc->m_recvsock, (struct sockaddr*)&osc->m_recvaddr, sizeof(struct sockaddr))) 
        {
          SET_SOCK_BLOCK(osc->m_recvsock, false);
          ++sockcnt;
        }
        else
        {
          closesocket(osc->m_recvsock);
          osc->m_recvsock=-1;
        }
      }
    }

    if (osc->m_send_enable)
    {
      osc->m_sendsock=socket(AF_INET, SOCK_DGRAM, 0);
      if (osc->m_sendsock >= 0)
      {
        int on=1;
        setsockopt(osc->m_sendsock, SOL_SOCKET, SO_BROADCAST, (char*)&on, sizeof(on));
        ++sockcnt;
      }
    }
  }

  if (sockcnt)
  {
    while (!s_threadquit)
    {
      char buf[MAX_OSC_MSG_LEN];
      bool hadmsg=false;

      for (i=0; i < s_osc_handlers.GetSize(); ++i)
      {
        OscHandler* osc=s_osc_handlers.Get(i);

        if (osc->m_recvsock >= 0)
        {
          buf[0]=0;
          int len=recvfrom(osc->m_recvsock, buf, sizeof(buf), 0, 0, 0);
          if (len > 0)
          { 
            // unpacking bundles becomes trivial
            // if we store the packet length as big-endian
            int tlen=len;
            REAPER_MAKEBEINTMEM((char*)&tlen);

            osc->m_mutex.Enter();
            osc->m_recvq.Add(&tlen, sizeof(int));
            osc->m_recvq.Add(buf, len);
            osc->m_mutex.Leave();

            if (osc->m_recv_enable&4) // just listening
            {
              int j;
              for (j=i+1; j < s_osc_handlers.GetSize(); ++j)
              {
                OscHandler* osc2=s_osc_handlers.Get(j);
                if (osc2->m_recv_enable && 
                    !memcmp(&osc2->m_recvaddr, &osc->m_recvaddr, sizeof(struct sockaddr_in)))
                {
                  osc2->m_mutex.Enter();
                  osc2->m_recvq.Add(&tlen, sizeof(int));
                  osc2->m_recvq.Add(buf, len);
                  osc2->m_mutex.Leave();
                }
              }
            }

            hadmsg=true;
          }
        }

        if (osc->m_sendsock >= 0 && osc->m_sendq.Available())
        {    
          sendq.Add(hdr, 16);

          osc->m_mutex.Enter();
          sendq.Add(osc->m_sendq.Get(), osc->m_sendq.Available());
          osc->m_sendq.Clear();
          osc->m_mutex.Leave();

          char* packetstart=(char*)sendq.Get();
          int packetlen=16;
          bool hasbundle=false;
          sendq.Advance(16);

          while (sendq.Available() >= sizeof(int))
          {
            int len=*(int*)sendq.Get(); // not advancing
            REAPER_MAKEBEINTMEM((char*)&len);

            if (len < 1 || len > MAX_OSC_MSG_LEN || len > sendq.Available()) break;             
            
            if (packetlen > 16 && packetlen+sizeof(int)+len > osc->m_maxpacketsz)
            {
              // packet is full
              if (!hasbundle)
              {
                packetstart += 20;
                packetlen -= 20;
              }

              if (s_threadquit) break;
              sendto(osc->m_sendsock, packetstart, packetlen, 0, (struct sockaddr*)&osc->m_sendaddr, sizeof(struct sockaddr));
              if (osc->m_sendsleep) Sleep(osc->m_sendsleep);

              packetstart=(char*)sendq.Get()-16; // safe since we padded the queue start
              memcpy(packetstart, hdr, 16);
              packetlen=16;
              hasbundle=false;
            }
         
            if (packetlen > 16) hasbundle=true;
            sendq.Advance(sizeof(int)+len);
            packetlen += sizeof(int)+len;
          }

          if (packetlen > 16)
          {
            if (!hasbundle)
            {
              packetstart += 20;
              packetlen -= 20;
            }

            if (s_threadquit) break;
            sendto(osc->m_sendsock, packetstart, packetlen, 0, (struct sockaddr*)&osc->m_sendaddr, sizeof(struct sockaddr));
            if (osc->m_sendsleep) Sleep(osc->m_sendsleep);
          }

          sendq.Clear();
          hadmsg=true;
        }
      }

      if (!hadmsg) Sleep(1);
    }
  }

  // s_threadquit:
  for (i=0; i < s_osc_handlers.GetSize(); ++i)
  {
    OscHandler* osc=s_osc_handlers.Get(i);
    if (osc->m_recvsock >= 0)
    {
      shutdown(osc->m_recvsock, SHUT_RDWR);
      closesocket(osc->m_recvsock);
      osc->m_recvsock=-1;
    }
    if (osc->m_sendsock >= 0)
    {
      shutdown(osc->m_sendsock, SHUT_RDWR);
      closesocket(osc->m_sendsock);
      osc->m_sendsock=-1;
    }
  }

  JNL::close_socketlib();
  return 0;
}