Added the trunk/branches/tags directories at repository root, and moved previous root into trunk/

git-svn-id: https://sfml.svn.sourceforge.net/svnroot/sfml/trunk@1002 4e206d99-4929-0410-ac5d-dfc041789085
This commit is contained in:
laurentgom 2009-01-28 16:18:34 +00:00
commit 2f524481c1
974 changed files with 295448 additions and 0 deletions

110
samples/voip/Client.cpp Normal file
View file

@ -0,0 +1,110 @@
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Audio.hpp>
#include <SFML/Network.hpp>
#include <iostream>
const sf::Uint8 AudioData = 1;
const sf::Uint8 EndOfStream = 2;
////////////////////////////////////////////////////////////
/// Specialization of audio recorder for sending recorded audio
/// data through the network
////////////////////////////////////////////////////////////
class NetworkRecorder : public sf::SoundRecorder
{
public :
////////////////////////////////////////////////////////////
/// Constructor
///
/// \param Socket : Socket that holds the connection with the server
///
////////////////////////////////////////////////////////////
NetworkRecorder(sf::SocketTCP Socket) :
mySocket(Socket)
{
}
private :
////////////////////////////////////////////////////////////
/// /see SoundRecorder::ProcessSamples
///
////////////////////////////////////////////////////////////
virtual bool OnProcessSamples(const sf::Int16* Samples, std::size_t SamplesCount)
{
// Pack the audio samples into a network packet
sf::Packet PacketOut;
PacketOut << AudioData;
PacketOut.Append(Samples, SamplesCount * sizeof(sf::Int16));
// Send the audio packet to the server
return mySocket.Send(PacketOut) == sf::Socket::Done;
}
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
sf::SocketTCP mySocket; ///< Socket used to communicate with the server
};
////////////////////////////////////////////////////////////
/// Create a client, connect it to a running server and
/// start sending him audio data
///
////////////////////////////////////////////////////////////
void DoClient(unsigned short Port)
{
// Check that the device can capture audio
if (sf::SoundRecorder::CanCapture() == false)
{
std::cout << "Sorry, audio capture is not supported by your system" << std::endl;
return;
}
// Ask for server address
sf::IPAddress ServerAddress;
do
{
std::cout << "Type address or name of the server to connect to : ";
std::cin >> ServerAddress;
}
while (!ServerAddress.IsValid());
// Create a TCP socket for communicating with server
sf::SocketTCP Socket;
// Connect to the specified server
if (Socket.Connect(Port, ServerAddress) != sf::Socket::Done)
return;
std::cout << "Connected to server " << ServerAddress << std::endl;
// Wait for user input...
std::cin.ignore(10000, '\n');
std::cout << "Press enter to start recording audio";
std::cin.ignore(10000, '\n');
// Create a instance of our custom recorder
NetworkRecorder Recorder(Socket);
// Start capturing audio data
Recorder.Start(44100);
std::cout << "Recording... press enter to stop";
std::cin.ignore(10000, '\n');
Recorder.Stop();
// Send a "end-of-stream" packet
sf::Packet PacketOut;
PacketOut << EndOfStream;
Socket.Send(PacketOut);
// Close the socket when we're done
Socket.Close();
}

18
samples/voip/Makefile Normal file
View file

@ -0,0 +1,18 @@
EXEC = voip
OBJ = VoIP.o Client.o Server.o
all: $(EXEC)
voip: $(OBJ)
$(CC) $(LDFLAGS) -o $(EXECPATH)/$@ $(OBJ) -lsfml-audio -lsfml-network -lsfml-system
%.o: %.cpp
$(CC) -o $@ -c $< $(CFLAGS)
.PHONY: clean mrproper
clean:
@rm -rf *.o
mrproper: clean
@rm -rf $(EXECPATH)/$(EXEC)

213
samples/voip/Server.cpp Normal file
View file

@ -0,0 +1,213 @@
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Audio.hpp>
#include <SFML/Network.hpp>
#include <iomanip>
#include <iostream>
const sf::Uint8 AudioData = 1;
const sf::Uint8 EndOfStream = 2;
////////////////////////////////////////////////////////////
/// Customized sound stream for acquiring audio data
/// from the network
////////////////////////////////////////////////////////////
class NetworkAudioStream : public sf::SoundStream
{
public :
////////////////////////////////////////////////////////////
/// Default constructor
///
////////////////////////////////////////////////////////////
NetworkAudioStream() :
myOffset (0),
myHasFinished(false)
{
// Set the sound parameters
Initialize(1, 44100);
}
////////////////////////////////////////////////////////////
/// Destructor
///
////////////////////////////////////////////////////////////
~NetworkAudioStream()
{
// Close the sockets
myClient.Close();
myListener.Close();
}
////////////////////////////////////////////////////////////
/// Run the server, stream audio data from the client
///
////////////////////////////////////////////////////////////
void Start(unsigned short Port)
{
if (!myHasFinished)
{
// Listen to the given port for incoming connections
if (!myListener.Listen(Port))
return;
std::cout << "Server is listening to port " << Port << ", waiting for connections... " << std::endl;
// Wait for a connection
sf::IPAddress ClientAddress;
myListener.Accept(myClient, &ClientAddress);
std::cout << "Client connected : " << ClientAddress << std::endl;
// Start playback
Play();
// Start receiving audio data
ReceiveLoop();
}
else
{
// Start playback
Play();
}
}
private :
////////////////////////////////////////////////////////////
/// /see SoundStream::OnStart
///
////////////////////////////////////////////////////////////
virtual bool OnStart()
{
// Reset the playing offset
myOffset = 0;
return true;
}
////////////////////////////////////////////////////////////
/// /see SoundStream::OnGetData
///
////////////////////////////////////////////////////////////
virtual bool OnGetData(sf::SoundStream::Chunk& Data)
{
// We have reached the end of the buffer and all audio data have been played : we can stop playback
if ((myOffset == mySamples.size()) && myHasFinished)
return false;
// No new data has arrived since last update : wait until we get some
while ((myOffset == mySamples.size()) && !myHasFinished)
sf::Sleep(0.01f);
// Copy samples into a local buffer to avoid synchronization problems
// (don't forget that we run in two separate threads)
{
sf::Lock Lock(myMutex);
myTempBuffer.assign(mySamples.begin() + myOffset, mySamples.end());
}
// Fill audio data to pass to the stream
Data.Samples = &myTempBuffer[0];
Data.NbSamples = myTempBuffer.size();
// Update the playing offset
myOffset += myTempBuffer.size();
return true;
}
////////////////////////////////////////////////////////////
/// Get audio data from the client until playback is stopped
///
////////////////////////////////////////////////////////////
void ReceiveLoop()
{
while (!myHasFinished)
{
// Get waiting audio data from the network
sf::Packet PacketIn;
if (myClient.Receive(PacketIn) != sf::Socket::Done)
break;
// Extract the message ID
sf::Uint8 Id;
PacketIn >> Id;
if (Id == AudioData)
{
// Extract audio samples from the packet, and append it to our samples buffer
const sf::Int16* Samples = reinterpret_cast<const sf::Int16*>(PacketIn.GetData() + 1);
std::size_t NbSamples = (PacketIn.GetDataSize() - 1) / sizeof(sf::Int16);
// Don't forget that the other thread can access the samples array at any time
// (so we protect any operation on it with the mutex)
{
sf::Lock Lock(myMutex);
std::copy(Samples, Samples + NbSamples, std::back_inserter(mySamples));
}
}
else if (Id == EndOfStream)
{
// End of stream reached : we stop receiving audio data
std::cout << "Audio data has been 100% received !" << std::endl;
myHasFinished = true;
}
else
{
// Something's wrong...
std::cout << "Invalid packet received..." << std::endl;
myHasFinished = true;
}
}
}
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
sf::SocketTCP myListener;
sf::SocketTCP myClient;
sf::Mutex myMutex;
std::vector<sf::Int16> mySamples;
std::vector<sf::Int16> myTempBuffer;
std::size_t myOffset;
bool myHasFinished;
};
////////////////////////////////////////////////////////////
/// Launch a server and wait for incoming audio data from
/// a connected client
///
////////////////////////////////////////////////////////////
void DoServer(unsigned short Port)
{
// Build an audio stream to play sound data as it is received through the network
NetworkAudioStream AudioStream;
AudioStream.Start(Port);
// Loop until the sound playback is finished
while (AudioStream.GetStatus() != sf::SoundStream::Stopped)
{
// Leave some CPU time for other threads
sf::Sleep(0.1f);
}
std::cin.ignore(10000, '\n');
// Wait until the user presses 'enter' key
std::cout << "Press enter to replay the sound..." << std::endl;
std::cin.ignore(10000, '\n');
// Replay the sound (just to make sure replaying the received data is OK)
AudioStream.Play();
// Loop until the sound playback is finished
while (AudioStream.GetStatus() != sf::SoundStream::Stopped)
{
// Leave some CPU time for other threads
sf::Sleep(0.1f);
}
}

49
samples/voip/VoIP.cpp Normal file
View file

@ -0,0 +1,49 @@
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <iomanip>
#include <iostream>
////////////////////////////////////////////////////////////
// Function prototypes
// (I'm too lazy to put them into separate headers...)
////////////////////////////////////////////////////////////
void DoClient(unsigned short Port);
void DoServer(unsigned short Port);
////////////////////////////////////////////////////////////
/// Entry point of application
///
/// \return Application exit code
///
////////////////////////////////////////////////////////////
int main()
{
// Choose a random port for opening sockets (ports < 1024 are reserved)
const unsigned short Port = 2435;
// Client or server ?
char Who;
std::cout << "Do you want to be a server ('s') or a client ('c') ? ";
std::cin >> Who;
if (Who == 's')
{
// Run as a server
DoServer(Port);
}
else
{
// Run as a client
DoClient(Port);
}
// Wait until the user presses 'enter' key
std::cout << "Press enter to exit..." << std::endl;
std::cin.ignore(10000, '\n');
return EXIT_SUCCESS;
}