Untitled

By Gamboge Dolphin, 11 Years ago, written in C++, viewed 767 times.
URL http://pb.stoleyour.com/view/922e5a9b Embed
Download Paste or View RawExpand paste to full width of browser
  1. #include <winsock2.h>
  2. #include <ws2tcpip.h>
  3. #include <stdio.h>
  4. #include <SFML/Audio.hpp>
  5. #include <vector>
  6. #include <Windows.h>
  7.  
  8.  
  9. #define BUFSIZE     1024
  10. #define MAXADDRSTR  16
  11.  
  12. #define TIMECAST_ADDR "234.5.6.7"
  13. #define TIMECAST_PORT 8910
  14.  
  15. // custom audio stream that plays a loaded buffer
  16. class MyStream : public sf::SoundStream
  17. {
  18. public:
  19.  
  20.        
  21.     std::vector<sf::Int16> m_samples;
  22.     std::size_t m_currentSample;
  23.         HANDLE sem;
  24.  
  25.     void load(sf::Int16* buffer, size_t sampleCount, size_t sampleRate, size_t channelCount)
  26.     {
  27.                 sem = CreateSemaphore(NULL, 1, 1, NULL);
  28.  
  29.         // extract the audio samples from the sound buffer to our own container
  30.         m_samples.assign(buffer, buffer + sampleCount);
  31.  
  32.         // reset the current playing position
  33.         m_currentSample = 0;
  34.  
  35.         // initialize the base class
  36.         initialize(channelCount, sampleRate);
  37.     }
  38.  
  39.         void add(sf::Int16* buffer, size_t size)
  40.         {
  41.                 // check semaphore
  42.                 WaitForSingleObject(sem, INFINITE);
  43.  
  44.                 for (int i = 0; i < size; i++)
  45.                 {
  46.                         m_samples.push_back(buffer[i]);
  47.                 }
  48.                 ReleaseSemaphore(sem, 1, NULL);
  49.         }
  50.  
  51. private:
  52.  
  53.     virtual bool onGetData(Chunk& data)
  54.         {
  55.                 // number of samples to stream every time the function is called;
  56.                 // in a more robust implementation, it would rather be a fixed
  57.                 // amount of time rather than an arbitrary number of samples
  58.                 const int samplesToStream = 50000;
  59.  
  60.                 //check semaphore
  61.                 WaitForSingleObject(sem, INFINITE);
  62.  
  63.                 // set the pointer to the next audio samples to be played
  64.                 data.samples = &m_samples[m_currentSample];
  65.  
  66.                 // have we reached the end of the sound?
  67.                 if (m_currentSample + samplesToStream <= m_samples.size())
  68.                 {
  69.                         // end not reached: stream the samples and continue
  70.                         data.sampleCount = samplesToStream;
  71.                         m_currentSample += samplesToStream;
  72.                         ReleaseSemaphore(sem, 1, NULL);
  73.                         return true;
  74.                 }
  75.                 else
  76.                 {
  77.                         // end of stream reached: stream the remaining samples and stop playback
  78.                         data.sampleCount = m_samples.size() - m_currentSample;
  79.                         m_currentSample = m_samples.size();
  80.                         ReleaseSemaphore(sem, 1, NULL);
  81.                         return false;
  82.                 }
  83.  
  84.         }
  85.  
  86.     virtual void onSeek(sf::Time timeOffset)
  87.     {
  88.         // compute the corresponding sample index according to the sample rate and channel count
  89.         m_currentSample = static_cast<std::size_t>(timeOffset.asSeconds() * getSampleRate() * getChannelCount());
  90.     }
  91.  
  92. };
  93.  
  94. char achMCAddr[MAXADDRSTR] = TIMECAST_ADDR;
  95. u_long lMCAddr;
  96. u_short nPort              = TIMECAST_PORT;
  97. SYSTEMTIME *lpstSysTime, stSysTime;
  98.  
  99. int main(int argc, char *argv[]) {
  100.   int nRet;
  101.   int nIP_TTL = 2;
  102.   BOOL  fFlag;
  103.   SOCKADDR_IN stLclAddr, stSrcAddr;
  104.   struct ip_mreq stMreq;         /* Multicast interface structure */
  105.   SOCKET hSocket;
  106.   WSADATA stWSAData;
  107.  
  108.         int count = 0;
  109.     // load an audio buffer from a sound file
  110.     sf::SoundBuffer buffer;
  111.         const sf::Int16* pSample;
  112.         sf::Int16 * pSound;
  113.         sf::Int16 * temp;
  114.         sf::Int16 * test;
  115.         size_t sampleCount, sampleRate, channelCount;
  116.     buffer.loadFromFile("test.wav");
  117.  
  118.         sampleRate   = buffer.getSampleRate();
  119.         channelCount = buffer.getChannelCount();
  120.         pSample      = buffer.getSamples();
  121.         sampleCount  = buffer.getSampleCount();
  122.  
  123.  
  124.         pSound = const_cast<sf::Int16*>(pSample);
  125.         temp   = const_cast<sf::Int16*>(pSample);
  126.         test = temp;
  127.         char achInBuf [sizeof(sampleRate)];
  128.     // initialize and play our custom stream
  129.         MyStream stream;
  130.   /* Init WinSock */
  131.   nRet = WSAStartup(0x0202, &stWSAData);
  132.   if (nRet) {
  133.       printf ("WSAStartup failed: %d\r\n", nRet);
  134.       exit(1);
  135.   }
  136.  
  137.  
  138.   /* Get a datagram socket */
  139.   hSocket = socket(AF_INET,
  140.      SOCK_DGRAM,
  141.      0);
  142.   if (hSocket == INVALID_SOCKET) {
  143.     printf ("socket() failed, Err: %d\n", WSAGetLastError());
  144.     WSACleanup();
  145.     exit(1);
  146.   }
  147.  
  148.   /* Avoid (WSA)EADDRINUSE error on bind() (last one to bind should
  149.    *  receive dgrams sent to our port, but there are no guarantees of
  150.    *  this, unfortunately). */
  151.   fFlag = TRUE;
  152.   nRet = setsockopt(hSocket,
  153.      SOL_SOCKET,
  154.      SO_REUSEADDR,
  155.      (char *)&fFlag,
  156.      sizeof(fFlag));
  157.   if (nRet == SOCKET_ERROR) {
  158.     printf ("setsockopt() SO_REUSEADDR failed, Err: %d\n",
  159.       WSAGetLastError());
  160.   }
  161.  
  162.   /* Name the socket (assign the local port number to receive on) */
  163.   stLclAddr.sin_family      = AF_INET;
  164.   stLclAddr.sin_addr.s_addr = htonl(INADDR_ANY);
  165.   stLclAddr.sin_port        = htons(nPort);
  166.   nRet = bind(hSocket,
  167.       (struct sockaddr*) &stLclAddr,
  168.       sizeof(stLclAddr));
  169.   if (nRet == SOCKET_ERROR) {
  170.       printf ("bind() port: %d failed, Err: %d\n", nPort,
  171.       WSAGetLastError());
  172.   }
  173.  
  174.   /* Join the multicast group so we can receive from it */
  175.   stMreq.imr_multiaddr.s_addr = inet_addr(achMCAddr);
  176.   stMreq.imr_interface.s_addr = INADDR_ANY;
  177.   nRet = setsockopt(hSocket,
  178.      IPPROTO_IP,
  179.      IP_ADD_MEMBERSHIP,
  180.      (char *)&stMreq,
  181.      sizeof(stMreq));
  182.   if (nRet == SOCKET_ERROR) {
  183.     printf(
  184.       "setsockopt() IP_ADD_MEMBERSHIP address %s failed, Err: %d\n",
  185.       achMCAddr, WSAGetLastError());
  186.   }
  187.  
  188.   int addr_size = sizeof(struct sockaddr_in);
  189.    
  190.     stream.load(pSound, 250000, sampleRate, channelCount);
  191.     stream.play();
  192.         stream.setVolume(10);
  193.         char * derp = (char *)pSound;
  194.   for (;;) {
  195.          
  196.     int addr_size = sizeof(struct sockaddr_in);
  197.  
  198.     nRet = recvfrom(hSocket,
  199.       derp,
  200.       sizeof(sampleRate),
  201.       0,
  202.       (struct sockaddr*)&stSrcAddr,
  203.       &addr_size);
  204.  
  205.     if (nRet < 0) {
  206.       printf ("recvfrom() failed, Error: %d\n", WSAGetLastError());
  207.       WSACleanup();
  208.       exit(1);
  209.     }
  210.  
  211.         temp = reinterpret_cast<sf::Int16*>(derp);
  212.         stream.add(temp, sampleRate);
  213.  
  214.   } /* end for(;;) */
  215.  
  216.   /* Leave the multicast group: With IGMP v1 this is a noop, but
  217.    *  with IGMP v2, it may send notification to multicast router.
  218.    *  Even if it's a noop, it's sanitary to cleanup after one's self.
  219.    */
  220.   stMreq.imr_multiaddr.s_addr = inet_addr(achMCAddr);
  221.   stMreq.imr_interface.s_addr = INADDR_ANY;
  222.   nRet = setsockopt(hSocket,
  223.      IPPROTO_IP,
  224.      IP_DROP_MEMBERSHIP,
  225.      (char *)&stMreq,
  226.      sizeof(stMreq));
  227.   if (nRet == SOCKET_ERROR) {
  228.     printf (
  229.       "setsockopt() IP_DROP_MEMBERSHIP address %s failed, Err: %d\n",
  230.       achMCAddr, WSAGetLastError());
  231.   }
  232.  
  233.   /* Close the socket */
  234.   closesocket(hSocket);
  235.  
  236.   /* Tell WinSock we're leaving */
  237.   WSACleanup();
  238.  
  239.   return (0);
  240. } /* end main() */

Reply to "Untitled"

Here you can reply to the paste above