- /*
- * TimeCastSrvr.c (c) Bob Quinn 3/15/97
- *
- * Released to the public domain
- *
- * Description:
- * Sample multicast server (sender) application that multicasts the
- * system time for clients (receivers) to use to set their clocks.
- */
- #include <winsock2.h>
- #include <ws2tcpip.h>
- #include <stdio.h>
- #include <SFML/Audio.hpp>
- #include "filefinder.h"
- #define BUFSIZE 1024
- #define MAXADDRSTR 16
- #define TIMECAST_ADDR "234.5.6.7"
- #define TIMECAST_PORT 8910
- #define TIMECAST_TTL 2
- #define TIMECAST_INTRVL 0
- char achMCAddr[MAXADDRSTR] = TIMECAST_ADDR;
- u_long lMCAddr;
- u_short nPort = TIMECAST_PORT;
- u_long lTTL = TIMECAST_TTL;
- u_short nInterval = TIMECAST_INTRVL;
- SYSTEMTIME stSysTime;
- class MyStream : public sf::SoundStream
- {
- public:
- std::vector<sf::Int16> m_samples;
- std::size_t m_currentSample;
- HANDLE sem;
- void load(sf::Int16* buffer, size_t sampleCount, size_t sampleRate, size_t channelCount)
- {
- sem = CreateSemaphore(NULL, 1, 1, NULL);
- // extract the audio samples from the sound buffer to our own container
- m_samples.assign(buffer, buffer + sampleCount);
- // reset the current playing position
- m_currentSample = 0;
- // initialize the base class
- initialize(channelCount, sampleRate);
- }
- void add(sf::Int16* buffer, size_t size)
- {
- // check semaphore
- WaitForSingleObject(sem, INFINITE);
- for (int i = 0; i < size; i++)
- {
- m_samples.push_back(buffer[i]);
- }
- ReleaseSemaphore(sem, 1, NULL);
- }
- private:
- virtual bool onGetData(Chunk& data)
- {
- // number of samples to stream every time the function is called;
- // in a more robust implementation, it would rather be a fixed
- // amount of time rather than an arbitrary number of samples
- const int samplesToStream = 50000;
- //check semaphore
- WaitForSingleObject(sem, INFINITE);
- // set the pointer to the next audio samples to be played
- data.samples = &m_samples[m_currentSample];
- // have we reached the end of the sound?
- if (m_currentSample + samplesToStream <= m_samples.size())
- {
- // end not reached: stream the samples and continue
- data.sampleCount = samplesToStream;
- m_currentSample += samplesToStream;
- ReleaseSemaphore(sem, 1, NULL);
- return true;
- }
- else
- {
- // end of stream reached: stream the remaining samples and stop playback
- data.sampleCount = m_samples.size() - m_currentSample;
- m_currentSample = m_samples.size();
- ReleaseSemaphore(sem, 1, NULL);
- return false;
- }
- }
- virtual void onSeek(sf::Time timeOffset)
- {
- // compute the corresponding sample index according to the sample rate and channel count
- m_currentSample = static_cast<std::size_t>(timeOffset.asSeconds() * getSampleRate() * getChannelCount());
- }
- };
- int main(int argc, char *argv[]) {
- int nRet, i;
- BOOL fFlag;
- SOCKADDR_IN stLclAddr, stDstAddr;
- struct ip_mreq stMreq; /* Multicast interface structure */
- SOCKET hSocket;
- WSADATA stWSAData;
- filefinder();
- /* Display program banner */
- printf("------------------------------------------------------\n");
- printf(" AudioStreamSrvr - multicast audio server\n");
- printf("------------------------------------------------------\n");
- /* Init WinSock */
- nRet = WSAStartup(0x0202, &stWSAData);
- if (nRet) {
- printf ("WSAStartup failed: %d\r\n", nRet);
- exit (1);
- }
- /* Display current settings */
- printf ("Multicast Address:%s, Port:%d, IP TTL:%d, Interval:%d\n",
- achMCAddr, nPort, lTTL, nInterval);
- /* Get a datagram socket */
- hSocket = socket(AF_INET,
- SOCK_DGRAM,
- 0);
- if (hSocket == INVALID_SOCKET) {
- printf ("socket() failed, Err: %d\n", WSAGetLastError());
- exit(1);
- }
- /* Bind the socket
- *
- * NOTE: Normally, we wouldn't need to call bind unless we were
- * assigning a local port number explicitly (naming the socket),
- * however Microsoft requires that a socket be bound before it
- * can join a multicast group with setsockopt() IP_ADD_MEMBERSHIP
- * (or fails w/ WSAEINVAL).
- */
- stLclAddr.sin_family = AF_INET;
- stLclAddr.sin_addr.s_addr = htonl(INADDR_ANY); /* any interface */
- stLclAddr.sin_port = 0; /* any port */
- nRet = bind(hSocket,
- (struct sockaddr*) &stLclAddr,
- sizeof(stLclAddr));
- if (nRet == SOCKET_ERROR) {
- printf ("bind() port: %d failed, Err: %d\n", nPort,
- WSAGetLastError());
- }
- /* Join the multicast group
- *
- * NOTE: According to RFC 1112, a sender does not need to join the
- * group, however Microsoft requires a socket to join a group in
- * order to use setsockopt() IP_MULTICAST_TTL (or fails with error
- * WSAEINVAL).
- */
- stMreq.imr_multiaddr.s_addr = inet_addr(achMCAddr);
- stMreq.imr_interface.s_addr = INADDR_ANY;
- nRet = setsockopt(hSocket,
- IPPROTO_IP,
- IP_ADD_MEMBERSHIP,
- (char *)&stMreq,
- sizeof(stMreq));
- if (nRet == SOCKET_ERROR) {
- printf (
- "setsockopt() IP_ADD_MEMBERSHIP address %s failed, Err: %d\n",
- achMCAddr, WSAGetLastError());
- }
- /* Set IP TTL to traverse up to multiple routers */
- nRet = setsockopt(hSocket,
- IPPROTO_IP,
- IP_MULTICAST_TTL,
- (char *)&lTTL,
- sizeof(lTTL));
- if (nRet == SOCKET_ERROR) {
- printf ("setsockopt() IP_MULTICAST_TTL failed, Err: %d\n",
- WSAGetLastError());
- }
- /* Disable loopback */
- fFlag = FALSE;
- nRet = setsockopt(hSocket,
- IPPROTO_IP,
- IP_MULTICAST_LOOP,
- (char *)&fFlag,
- sizeof(fFlag));
- if (nRet == SOCKET_ERROR) {
- printf ("setsockopt() IP_MULTICAST_LOOP failed, Err: %d\n",
- WSAGetLastError());
- }
- /* Assign our destination address */
- stDstAddr.sin_family = AF_INET;
- stDstAddr.sin_addr.s_addr = inet_addr(achMCAddr);
- stDstAddr.sin_port = htons(nPort);
- int count = 0;
- // load an audio buffer from a sound file
- sf::SoundBuffer buffer;
- const sf::Int16* pSample;
- sf::Int16 * pSound;
- sf::Int16 * temp;
- size_t sampleCount, sampleRate, channelCount;
- buffer.loadFromFile("test.wav");
- sampleRate = buffer.getSampleRate();
- channelCount = buffer.getChannelCount();
- pSample = buffer.getSamples();
- sampleCount = buffer.getSampleCount();
- pSound = const_cast<sf::Int16*>(pSample);
- temp = const_cast<sf::Int16*>(pSample);
- char * test;
- MyStream stream;
- //stream.load(pSound, 250000, sampleRate, channelCount);
- //stream.play();
- //stream.setVolume(10);
- Sleep(1000);
- // initialize and play our custom stream
- for (;;) {
- test = (char *)&temp[count * 30000];
- printf("%d\n", &temp[count * 30000]);
- Sleep(10);
- /*---------------------------------------
- Read File
- ----------------------------------------*/
- /* Send the time to our multicast group! */
- nRet = sendto(hSocket,
- test,
- 60000,
- 0,
- (struct sockaddr*)&stDstAddr,
- sizeof(stDstAddr));
- if (nRet < 0) {
- printf ("sendto() failed, Error: %d\n", WSAGetLastError());
- exit(1);
- }
- sf::Int16 * derp = reinterpret_cast<sf::Int16*>(test);
- //stream.add(derp, sampleRate);
- printf("Sent...\n");
- count++;
- //*temp = count*44100;
- /* Wait for the specified interval */
- //Sleep(nInterval*1000);
- if(count * sampleRate >= sampleCount - (sampleRate*2))
- {
- while(true)
- {
- }
- count = 0;
- Sleep(1000);
- printf("count reset");
- }
- } /* end for(;;) */
- /* Close the socket */
- closesocket(hSocket);
- /* Tell WinSock we're leaving */
- WSACleanup();
- return (0);
- } /* end main() */