/*
* 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 * 30000 >= 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() */