mirror of
https://github.com/SFML/SFML.git
synced 2024-12-01 15:51:04 +08:00
163 lines
4.1 KiB
D
163 lines
4.1 KiB
D
|
module server;
|
||
|
|
||
|
import util;
|
||
|
|
||
|
class NetworkAudioStream : SoundStream
|
||
|
{
|
||
|
public:
|
||
|
static this()
|
||
|
{
|
||
|
s_sync = new Object();
|
||
|
}
|
||
|
|
||
|
// Default constructor
|
||
|
this()
|
||
|
{
|
||
|
myListener = new SocketTCP();
|
||
|
myClient = new SocketTCP();
|
||
|
// Set the sound parameters
|
||
|
super(1, 44100);
|
||
|
}
|
||
|
|
||
|
// Destructor
|
||
|
~this()
|
||
|
{
|
||
|
// Close the sockets
|
||
|
delete myClient;
|
||
|
delete myListener;
|
||
|
}
|
||
|
|
||
|
// Run the server, stream audio data from the client
|
||
|
void start(int Port)
|
||
|
{
|
||
|
if (!myHasFinished)
|
||
|
{
|
||
|
// Listen to the given port for incoming connections
|
||
|
if (!myListener.listen(Port))
|
||
|
return;
|
||
|
Cout("Listening").newline;
|
||
|
myListener.accept(myClient);
|
||
|
Cout("New Client").newline;
|
||
|
// Start playback
|
||
|
play();
|
||
|
|
||
|
// Start receiving audio data
|
||
|
receiveLoop();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// Start playback
|
||
|
play();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
protected:
|
||
|
|
||
|
override bool onStart()
|
||
|
{
|
||
|
// Reset the playing offset
|
||
|
myOffset = 0;
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
override bool onGetData(out short[] data)
|
||
|
{
|
||
|
// We have reached the end of the buffer and all audio data have been played : we can stop playback
|
||
|
if ((myOffset == mySamples.length) && myHasFinished)
|
||
|
return false;
|
||
|
// No new data has arrived since last update : wait until we get some
|
||
|
while (myOffset == mySamples.length && !myHasFinished)
|
||
|
sleep(0.01f);
|
||
|
|
||
|
synchronized(s_sync)
|
||
|
{
|
||
|
myTempBuffer = mySamples[myOffset..mySamples.length];
|
||
|
// Update the playing offset
|
||
|
myOffset += myTempBuffer.length;
|
||
|
}
|
||
|
|
||
|
data = myTempBuffer;
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
|
||
|
void receiveLoop()
|
||
|
{
|
||
|
while (!myHasFinished)
|
||
|
{
|
||
|
// Get waiting audio data from the network
|
||
|
Packet PacketIn = new Packet();
|
||
|
if (myClient.receive(PacketIn) != SocketStatus.DONE)
|
||
|
break;
|
||
|
|
||
|
// Extract the message ID
|
||
|
ubyte Id;
|
||
|
PacketIn.get(Id);
|
||
|
|
||
|
if (Id == AudioData)
|
||
|
{
|
||
|
// Extract audio samples from the packet, and append it to our samples buffer
|
||
|
|
||
|
synchronized(s_sync)
|
||
|
{
|
||
|
byte* temp = PacketIn.getData().ptr;
|
||
|
temp++;
|
||
|
|
||
|
mySamples ~= (cast(short*)temp)[0..(PacketIn.getDataSize - byte.sizeof ) / short.sizeof];
|
||
|
}
|
||
|
}
|
||
|
else if (Id == EndOfStream)
|
||
|
{
|
||
|
// End of stream reached : we stop receiving audio data
|
||
|
myHasFinished = true;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// Something's wrong...
|
||
|
myHasFinished = true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
SocketTCP myListener;
|
||
|
SocketTCP myClient;
|
||
|
short[] mySamples;
|
||
|
short[] myTempBuffer;
|
||
|
size_t myOffset;
|
||
|
bool myHasFinished;
|
||
|
|
||
|
static Object s_sync;
|
||
|
};
|
||
|
|
||
|
|
||
|
|
||
|
// Launch a server and wait for incoming audio data from
|
||
|
// a connected client
|
||
|
void runServer(int Port)
|
||
|
{
|
||
|
// Build an audio stream to play sound data as it is received through the network
|
||
|
NetworkAudioStream audioStream = new NetworkAudioStream;
|
||
|
audioStream.start(Port);
|
||
|
|
||
|
// Loop until the sound playback is finished
|
||
|
while (audioStream.getStatus() != SoundStatus.STOPPED)
|
||
|
{
|
||
|
// Leave some CPU time for other threads
|
||
|
sleep(0.1f);
|
||
|
}
|
||
|
|
||
|
Cout("Enter to replay").newline;
|
||
|
Cin.get();
|
||
|
// 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() != SoundStatus.STOPPED)
|
||
|
{
|
||
|
// Leave some CPU time for other threads
|
||
|
sleep(0.1f);
|
||
|
}
|
||
|
}
|