* simply replacing spaces with tabs in the example files

git-svn-id: https://sfml.svn.sourceforge.net/svnroot/sfml/branches/sfml2@1440 4e206d99-4929-0410-ac5d-dfc041789085
This commit is contained in:
trass3r 2010-03-04 02:23:27 +00:00
parent 8390807b08
commit 4a19225764
9 changed files with 670 additions and 670 deletions

View File

@ -13,218 +13,218 @@ import Derelict.opengl.glu;
// An enum for each controls methods // An enum for each controls methods
enum ControlMethod enum ControlMethod
{ {
MOUSE, MOUSE,
KEYBOARD KEYBOARD
} }
void main() void main()
{ {
DerelictGL.load(); DerelictGL.load();
DerelictGLU.load(); DerelictGLU.load();
//Start the message loop //Start the message loop
Application.run(new MyForm()); Application.run(new MyForm());
} }
//A simple form with a groupbox to choose input method and the openGL control //A simple form with a groupbox to choose input method and the openGL control
class MyForm : Form class MyForm : Form
{ {
GLControl m_gl; GLControl m_gl;
GroupBox m_gbx; GroupBox m_gbx;
RadioButton m_rb1; RadioButton m_rb1;
RadioButton m_rb2; RadioButton m_rb2;
this() this()
{ {
m_gbx = new GroupBox(); m_gbx = new GroupBox();
m_gbx.dock = DockStyle.TOP; m_gbx.dock = DockStyle.TOP;
m_gbx.height = 40; m_gbx.height = 40;
m_gbx.text = "Choose your input"; m_gbx.text = "Choose your input";
this.controls.add(m_gbx); this.controls.add(m_gbx);
m_rb1 = new RadioButton(); m_rb1 = new RadioButton();
m_rb1.text = "Mouse"; m_rb1.text = "Mouse";
m_rb1.location = Point(10, 15); m_rb1.location = Point(10, 15);
m_rb1.checked = true; m_rb1.checked = true;
m_rb1.click ~= &radioButtonClick; m_rb1.click ~= &radioButtonClick;
m_gbx.controls.add(m_rb1); m_gbx.controls.add(m_rb1);
m_rb2 = new RadioButton(); m_rb2 = new RadioButton();
m_rb2.text = "Keyboard"; m_rb2.text = "Keyboard";
m_rb2.location = Point(m_rb1.width + 10, 15); m_rb2.location = Point(m_rb1.width + 10, 15);
m_rb2.click ~= &radioButtonClick; m_rb2.click ~= &radioButtonClick;
m_gbx.controls.add(m_rb2); m_gbx.controls.add(m_rb2);
m_gl = new GLControl(); m_gl = new GLControl();
m_gl.dock = DockStyle.FILL; m_gl.dock = DockStyle.FILL;
m_gl.controlMethod = ControlMethod.MOUSE; m_gl.controlMethod = ControlMethod.MOUSE;
this.controls.add(m_gl); this.controls.add(m_gl);
this.text = "DFL Opengl Integration Sample"; this.text = "DFL Opengl Integration Sample";
} }
private void radioButtonClick(Control c, EventArgs ea) private void radioButtonClick(Control c, EventArgs ea)
{ {
m_gl.controlMethod(c.text == "Mouse" ? ControlMethod.MOUSE : ControlMethod.KEYBOARD); m_gl.controlMethod(c.text == "Mouse" ? ControlMethod.MOUSE : ControlMethod.KEYBOARD);
m_gl.focus(); m_gl.focus();
} }
} }
//Our OpenGL control //Our OpenGL control
class GLControl : Control class GLControl : Control
{ {
Window m_win; Window m_win;
Input i; Input i;
Timer m_timer; Timer m_timer;
GLfloat rotx = 0.f, roty = 0.f; GLfloat rotx = 0.f, roty = 0.f;
ControlMethod m_method = ControlMethod.MOUSE; ControlMethod m_method = ControlMethod.MOUSE;
this () this ()
{ {
super(); super();
this.setStyle(ControlStyles.SELECTABLE | ControlStyles.ALL_PAINTING_IN_WM_PAINT | ControlStyles.WANT_ALL_KEYS, true); this.setStyle(ControlStyles.SELECTABLE | ControlStyles.ALL_PAINTING_IN_WM_PAINT | ControlStyles.WANT_ALL_KEYS, true);
//We set a timer to ensure periodic refresh of the window //We set a timer to ensure periodic refresh of the window
m_timer = new Timer(); m_timer = new Timer();
m_timer.interval(10); m_timer.interval(10);
m_timer.tick ~= &this.onTick; m_timer.tick ~= &this.onTick;
} }
public void controlMethod(ControlMethod m) public void controlMethod(ControlMethod m)
{ {
m_method = m; m_method = m;
} }
//Override of the onHandleCreated method of Control //Override of the onHandleCreated method of Control
//integration of DSFML window in a control need a valid handle //integration of DSFML window in a control need a valid handle
protected void onHandleCreated(EventArgs ea) protected void onHandleCreated(EventArgs ea)
{ {
super.onHandleCreated(ea); super.onHandleCreated(ea);
//Construction of the window //Construction of the window
m_win = new Window(cast(WindowHandle)this.handle); m_win = new Window(cast(WindowHandle)this.handle);
//Get the input for further use //Get the input for further use
i = m_win.getInput(); i = m_win.getInput();
//Now that the Window is instanciated, we can start the timer. //Now that the Window is instanciated, we can start the timer.
m_timer.start(); m_timer.start();
//Some opengl initializations functions //Some opengl initializations functions
glClearDepth(1.f); glClearDepth(1.f);
glClearColor(0.f, 0.f, 0.f, 0.f); glClearColor(0.f, 0.f, 0.f, 0.f);
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE); glDepthMask(GL_TRUE);
glMatrixMode(GL_PROJECTION); glMatrixMode(GL_PROJECTION);
glLoadIdentity(); glLoadIdentity();
gluPerspective(90.f, 1.f, 1.f, 500.f); gluPerspective(90.f, 1.f, 1.f, 500.f);
} }
//We handle Mouse leaving and entering the control to hide or show the cursor //We handle Mouse leaving and entering the control to hide or show the cursor
protected void onMouseEnter(MouseEventArgs mea) protected void onMouseEnter(MouseEventArgs mea)
{ {
super.onMouseEnter(mea); super.onMouseEnter(mea);
Cursor.current.hide(); Cursor.current.hide();
} }
protected void onMouseLeave(MouseEventArgs mea) protected void onMouseLeave(MouseEventArgs mea)
{ {
super.onMouseLeave(mea); super.onMouseLeave(mea);
Cursor.current.show(); Cursor.current.show();
} }
//If the window is resize, we need to modify openGL view //If the window is resize, we need to modify openGL view
protected void onResize(EventArgs ea) protected void onResize(EventArgs ea)
{ {
super.onResize(ea); super.onResize(ea);
glViewport(0, 0, this.width, this.height); glViewport(0, 0, this.width, this.height);
} }
protected void onTick(Timer t, EventArgs ea) protected void onTick(Timer t, EventArgs ea)
{ {
draw(); draw();
} }
protected void onPaint(PaintEventArgs pea) protected void onPaint(PaintEventArgs pea)
{ {
super.onPaint(pea); super.onPaint(pea);
draw(); draw();
} }
private void handleKeys() private void handleKeys()
{ {
if (i.isKeyDown(KeyCode.UP)) if (i.isKeyDown(KeyCode.UP))
rotx += 1.f; rotx += 1.f;
if (i.isKeyDown(KeyCode.DOWN)) if (i.isKeyDown(KeyCode.DOWN))
rotx += -1.f; rotx += -1.f;
if (i.isKeyDown(KeyCode.LEFT)) if (i.isKeyDown(KeyCode.LEFT))
roty += -1.f; roty += -1.f;
if (i.isKeyDown(KeyCode.RIGHT)) if (i.isKeyDown(KeyCode.RIGHT))
roty += 1.f; roty += 1.f;
} }
private void handleMousePos() private void handleMousePos()
{ {
rotx = i.getMouseY() - (this.height / 2.0); rotx = i.getMouseY() - (this.height / 2.0);
roty = i.getMouseX() - (this.width / 2.0); roty = i.getMouseX() - (this.width / 2.0);
} }
private void draw() private void draw()
{ {
if (m_method == ControlMethod.KEYBOARD) if (m_method == ControlMethod.KEYBOARD)
handleKeys(); handleKeys();
else else
handleMousePos(); handleMousePos();
m_win.setActive(true); m_win.setActive(true);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW); glMatrixMode(GL_MODELVIEW);
glLoadIdentity(); glLoadIdentity();
glTranslatef(0.f, 0.f, -200.f); glTranslatef(0.f, 0.f, -200.f);
glRotatef(rotx, 1.f, 0.f, 0.f); glRotatef(rotx, 1.f, 0.f, 0.f);
glRotatef(roty, 0.f, 1.f, 0.f); glRotatef(roty, 0.f, 1.f, 0.f);
glBegin(GL_QUADS); glBegin(GL_QUADS);
glColor3f(1.f, 0.f, 0.f); glColor3f(1.f, 0.f, 0.f);
glVertex3f(-50.f, -50.f, -50.f); glVertex3f(-50.f, -50.f, -50.f);
glVertex3f(-50.f, 50.f, -50.f); glVertex3f(-50.f, 50.f, -50.f);
glVertex3f( 50.f, 50.f, -50.f); glVertex3f( 50.f, 50.f, -50.f);
glVertex3f( 50.f, -50.f, -50.f); glVertex3f( 50.f, -50.f, -50.f);
glColor3f(0.f, 1.f, 0.f); glColor3f(0.f, 1.f, 0.f);
glVertex3f(-50.f, -50.f, 50.f); glVertex3f(-50.f, -50.f, 50.f);
glVertex3f(-50.f, 50.f, 50.f); glVertex3f(-50.f, 50.f, 50.f);
glVertex3f( 50.f, 50.f, 50.f); glVertex3f( 50.f, 50.f, 50.f);
glVertex3f( 50.f, -50.f, 50.f); glVertex3f( 50.f, -50.f, 50.f);
glColor3f(0.f, 0.f, 1.f); glColor3f(0.f, 0.f, 1.f);
glVertex3f(-50.f, -50.f, -50.f); glVertex3f(-50.f, -50.f, -50.f);
glVertex3f(-50.f, 50.f, -50.f); glVertex3f(-50.f, 50.f, -50.f);
glVertex3f(-50.f, 50.f, 50.f); glVertex3f(-50.f, 50.f, 50.f);
glVertex3f(-50.f, -50.f, 50.f); glVertex3f(-50.f, -50.f, 50.f);
glColor3f(1.f, 1.f, 0.f); glColor3f(1.f, 1.f, 0.f);
glVertex3f(50.f, -50.f, -50.f); glVertex3f(50.f, -50.f, -50.f);
glVertex3f(50.f, 50.f, -50.f); glVertex3f(50.f, 50.f, -50.f);
glVertex3f(50.f, 50.f, 50.f); glVertex3f(50.f, 50.f, 50.f);
glVertex3f(50.f, -50.f, 50.f); glVertex3f(50.f, -50.f, 50.f);
glColor3f(1.f, 0.f, 1.f); glColor3f(1.f, 0.f, 1.f);
glVertex3f(-50.f, -50.f, 50.f); glVertex3f(-50.f, -50.f, 50.f);
glVertex3f(-50.f, -50.f, -50.f); glVertex3f(-50.f, -50.f, -50.f);
glVertex3f( 50.f, -50.f, -50.f); glVertex3f( 50.f, -50.f, -50.f);
glVertex3f( 50.f, -50.f, 50.f); glVertex3f( 50.f, -50.f, 50.f);
glColor3f(0.f, 1.f, 1.f); glColor3f(0.f, 1.f, 1.f);
glVertex3f(-50.f, 50.f, 50.f); glVertex3f(-50.f, 50.f, 50.f);
glVertex3f(-50.f, 50.f, -50.f); glVertex3f(-50.f, 50.f, -50.f);
glVertex3f( 50.f, 50.f, -50.f); glVertex3f( 50.f, 50.f, -50.f);
glVertex3f( 50.f, 50.f, 50.f); glVertex3f( 50.f, 50.f, 50.f);
glEnd(); glEnd();
m_win.display(); m_win.display();
} }
} }

View File

@ -8,110 +8,110 @@ const char[][5] EFFECTS = ["nothing", "blur", "colorize", "fisheye", "wave"];
void main() void main()
{ {
int actualIndex; int actualIndex;
// Check that the system can use post effects // Check that the system can use post effects
if (PostFX.canUsePostFX() == false) if (PostFX.canUsePostFX() == false)
assert(0, "Your system doesn't support Post Effects."); assert(0, "Your system doesn't support Post Effects.");
// Create the main window // Create the main window
RenderWindow app = new RenderWindow(VideoMode(800, 600), "SFML PostFX"); RenderWindow app = new RenderWindow(VideoMode(800, 600), "SFML PostFX");
app.setFramerateLimit(100); app.setFramerateLimit(100);
// Load a cute background image to display :) // Load a cute background image to display :)
Sprite background = new Sprite(new Image("Data/background.jpg")); Sprite background = new Sprite(new Image("Data/background.jpg"));
// Load the image needed for the wave effect // Load the image needed for the wave effect
Image WaveImage = new Image("Data/wave.jpg"); Image WaveImage = new Image("Data/wave.jpg");
// Load all effects // Load all effects
PostFX[char[]] Effects; PostFX[char[]] Effects;
foreach(char[] c; EFFECTS) foreach(char[] c; EFFECTS)
{ {
Effects[c] = new PostFX("Data/" ~ c ~ ".sfx"); Effects[c] = new PostFX("Data/" ~ c ~ ".sfx");
} }
PostFX currentEffect = Effects[EFFECTS[actualIndex]]; PostFX currentEffect = Effects[EFFECTS[actualIndex]];
// Do specific initializations // Do specific initializations
Effects["nothing"].setTexture("framebuffer", null); Effects["nothing"].setTexture("framebuffer", null);
Effects["blur"].setTexture("framebuffer", null); Effects["blur"].setTexture("framebuffer", null);
Effects["blur"].setParameter("offset", 0.f); Effects["blur"].setParameter("offset", 0.f);
Effects["colorize"].setTexture("framebuffer", null); Effects["colorize"].setTexture("framebuffer", null);
Effects["colorize"].setParameter("color", 1.f, 1.f, 1.f); Effects["colorize"].setParameter("color", 1.f, 1.f, 1.f);
Effects["fisheye"].setTexture("framebuffer", null); Effects["fisheye"].setTexture("framebuffer", null);
Effects["wave"].setTexture("framebuffer", null); Effects["wave"].setTexture("framebuffer", null);
Effects["wave"].setTexture("wave", WaveImage); Effects["wave"].setTexture("wave", WaveImage);
Font f = new Font("Data/cheeseburger.ttf"); Font f = new Font("Data/cheeseburger.ttf");
// Define a string for displaying current effect description // Define a string for displaying current effect description
String curFXStr = new String("Current effect is " ~ EFFECTS[actualIndex]); Text curFXStr = new Text("Current effect is " ~ EFFECTS[actualIndex]);
curFXStr.setFont(f); curFXStr.setFont(f);
curFXStr.setPosition(20.f, 0.f); curFXStr.setPosition(20.f, 0.f);
// Define a string for displaying help // Define a string for displaying help
String infoStr = new String("Move your mouse to change the effect parameters\nPress numpad + and - to change effect\nWarning : some effects may not work\ndepending on your graphics card"c); Text infoStr = new Text("Move your mouse to change the effect parameters\nPress numpad + and - to change effect\nWarning : some effects may not work\ndepending on your graphics card"c);
infoStr.setFont(f); infoStr.setFont(f);
infoStr.setPosition(20.f, 460.f); infoStr.setPosition(20.f, 460.f);
infoStr.setColor(Color(200, 100, 150)); infoStr.setColor(Color(200, 100, 150));
// Start the game loop // Start the game loop
while (app.isOpened()) while (app.isOpened())
{ {
// Process events // Process events
Event evt; Event evt;
while (app.getEvent(evt)) while (app.getEvent(evt))
{ {
// Close window : exit // Close window : exit
if (evt.Type == Event.EventType.CLOSED || if (evt.Type == Event.EventType.CLOSED ||
evt.Type == Event.EventType.KEYPRESSED && evt.Key.Code == KeyCode.ESCAPE) evt.Type == Event.EventType.KEYPRESSED && evt.Key.Code == KeyCode.ESCAPE)
app.close(); app.close();
if (evt.Type == Event.EventType.KEYPRESSED) if (evt.Type == Event.EventType.KEYPRESSED)
{ {
// Add key : next effect // Add key : next effect
if (evt.Key.Code == KeyCode.ADD) if (evt.Key.Code == KeyCode.ADD)
{ {
if (actualIndex == 4) if (actualIndex == 4)
actualIndex = 0; actualIndex = 0;
else else
actualIndex++; actualIndex++;
currentEffect = Effects[EFFECTS[actualIndex]]; currentEffect = Effects[EFFECTS[actualIndex]];
curFXStr.setText("Current effect is " ~ EFFECTS[actualIndex]); curFXStr.setText("Current effect is " ~ EFFECTS[actualIndex]);
} }
// Subtract key : previous effect // Subtract key : previous effect
if (evt.Key.Code == KeyCode.SUBTRACT) if (evt.Key.Code == KeyCode.SUBTRACT)
{ {
if (actualIndex == 0) if (actualIndex == 0)
actualIndex = 4; actualIndex = 4;
else else
actualIndex--; actualIndex--;
currentEffect = Effects[EFFECTS[actualIndex]]; currentEffect = Effects[EFFECTS[actualIndex]];
curFXStr.setText("Current effect is " ~ EFFECTS[actualIndex]); curFXStr.setText("Current effect is " ~ EFFECTS[actualIndex]);
} }
} }
} }
// Get the mouse position in the range [0, 1] // Get the mouse position in the range [0, 1]
float X = app.getInput().getMouseX() / cast(float) app.getWidth(); float X = app.getInput().getMouseX() / cast(float) app.getWidth();
float Y = app.getInput().getMouseY() / cast(float) app.getHeight(); float Y = app.getInput().getMouseY() / cast(float) app.getHeight();
// Update the current effect // Update the current effect
if (EFFECTS[actualIndex] == "blur") currentEffect.setParameter("offset", X * Y * 0.1f); if (EFFECTS[actualIndex] == "blur") currentEffect.setParameter("offset", X * Y * 0.1f);
else if (EFFECTS[actualIndex] == "colorize") currentEffect.setParameter("color", 0.3f, X, Y); else if (EFFECTS[actualIndex] == "colorize") currentEffect.setParameter("color", 0.3f, X, Y);
else if (EFFECTS[actualIndex] == "fisheye") currentEffect.setParameter("mouse", X, 1.f - Y); else if (EFFECTS[actualIndex] == "fisheye") currentEffect.setParameter("mouse", X, 1.f - Y);
else if (EFFECTS[actualIndex] == "wave") currentEffect.setParameter("offset", X, Y); else if (EFFECTS[actualIndex] == "wave") currentEffect.setParameter("offset", X, Y);
// Draw background and apply the post-fx // Draw background and apply the post-fx
app.draw(background); app.draw(background);
app.draw(currentEffect); app.draw(currentEffect);
// Draw interface strings // Draw interface strings
app.draw(curFXStr); app.draw(curFXStr);
app.draw(infoStr); app.draw(infoStr);
// Finally, display the rendered frame on screen // Finally, display the rendered frame on screen
app.display(); app.display();
} }
} }

View File

@ -5,62 +5,62 @@ import dsfml.network.all;
version (Tango) version (Tango)
{ {
import tango.io.Console; import tango.io.Console;
import tango.io.Stdout; import tango.io.Stdout;
} }
else else
{ {
import std.stdio; import std.stdio;
} }
void main() void main()
{ {
//The TCP socket //The TCP socket
SocketTCP client = new SocketTCP(); SocketTCP client = new SocketTCP();
//Try to connect to server (on localhost for this sample) //Try to connect to server (on localhost for this sample)
client.connect(9000, IPAddress.LOCALHOST); client.connect(9000, IPAddress.LOCALHOST);
display("Connected to server."w); display("Connected to server."w);
//Prepare a packet with a string //Prepare a packet with a string
Packet p = new Packet(); Packet p = new Packet();
p.set("Hello from the client !"w); p.set("Hello from the client !"w);
if (client.send(p) != SocketStatus.DONE) // Assert on error if (client.send(p) != SocketStatus.DONE) // Assert on error
assert(0); assert(0);
//Clear the packet //Clear the packet
p.clear(); p.clear();
//Wait for the response of the server and display it //Wait for the response of the server and display it
if (client.receive(p) != SocketStatus.DONE) if (client.receive(p) != SocketStatus.DONE)
assert(0); assert(0);
wchar[] c; wchar[] c;
p.get(c); p.get(c);
display("Packet received : "w ~ c); display("Packet received : "w ~ c);
read(); read();
} }
void display(wchar[] c) void display(wchar[] c)
{ {
version (Tango) version (Tango)
{ {
Stdout(c).newline; Stdout(c).newline;
} }
else else
{ {
writefln("%s", c); writefln("%s", c);
} }
} }
void read() void read()
{ {
version (Tango) version (Tango)
{ {
Cin.get(); Cin.get();
} }
else else
{ {
readln(); readln();
} }
} }

View File

@ -5,79 +5,79 @@ import dsfml.network.all;
version (Tango) version (Tango)
{ {
import tango.io.Console; import tango.io.Console;
import tango.io.Stdout; import tango.io.Stdout;
} }
else else
{ {
import std.stdio; import std.stdio;
} }
void main() void main()
{ {
//We create a TCP socket for listening incomming client //We create a TCP socket for listening incomming client
SocketTCP listener = new SocketTCP(); SocketTCP listener = new SocketTCP();
//Set a random port for the listener //Set a random port for the listener
if (!listener.listen(9000)) if (!listener.listen(9000))
assert(0); assert(0);
//Creation of TCP socket //Creation of TCP socket
SocketTCP client = new SocketTCP(); SocketTCP client = new SocketTCP();
IPAddress ipClient; IPAddress ipClient;
display("Waiting for client."w); display("Waiting for client."w);
if (listener.accept(client, ipClient) == SocketStatus.DONE) //This call blocks until client connection if (listener.accept(client, ipClient) == SocketStatus.DONE) //This call blocks until client connection
{ {
display("New client connected."w); display("New client connected."w);
//The packet for retrieving the client message //The packet for retrieving the client message
Packet p = new Packet(); Packet p = new Packet();
display("Waiting for data"w); display("Waiting for data"w);
if (client.receive(p) != SocketStatus.DONE) //Assert on reception error if (client.receive(p) != SocketStatus.DONE) //Assert on reception error
assert(0); assert(0);
//Display the string send by the client //Display the string send by the client
wchar[] c; wchar[] c;
p.get(c); p.get(c);
display("Packet received : "w ~ c); display("Packet received : "w ~ c);
//Clear the packet (We could use a new one) //Clear the packet (We could use a new one)
p.clear(); p.clear();
//and send response to client //and send response to client
client.send(p.set("Hello from the server !"w)); client.send(p.set("Hello from the server !"w));
} }
read(); read();
} }
/** /**
* Multilib string display * Multilib string display
*/ */
void display(wchar[] c) void display(wchar[] c)
{ {
version (Tango) version (Tango)
{ {
Stdout(c).newline; Stdout(c).newline;
} }
else else
{ {
writefln("%s", c); writefln("%s", c);
} }
} }
/** /**
* Dummy function to prevent console closing on windows * Dummy function to prevent console closing on windows
*/ */
void read() void read()
{ {
version (Tango) version (Tango)
{ {
Cin.get(); Cin.get();
} }
else else
{ {
readln(); readln();
} }
} }

View File

@ -5,12 +5,12 @@ import dsfml.audio.all;
version (Tango) version (Tango)
{ {
import tango.io.Console; import tango.io.Console;
import tango.io.Stdout; import tango.io.Stdout;
} }
else else
{ {
import std.stdio; import std.stdio;
} }
// SoundStream is an abstract class. // SoundStream is an abstract class.
@ -18,74 +18,74 @@ else
// Don't forget to call initialize() before any usage or playback will fail. // Don't forget to call initialize() before any usage or playback will fail.
class MySoundStream : SoundStream class MySoundStream : SoundStream
{ {
SoundBuffer m_buff; SoundBuffer m_buff;
short[] m_data; short[] m_data;
size_t m_cursor; size_t m_cursor;
this() this()
{ {
// We initialize the stream with some sound informations // We initialize the stream with some sound informations
super(1, 11025); super(1, 11025);
// We create a sound buffer to load samples from files // We create a sound buffer to load samples from files
m_buff = new SoundBuffer("Data/car_idle.wav"); m_buff = new SoundBuffer("Data/car_idle.wav");
m_data = m_buff.getSamples[0..m_buff.getSamplesCount]; m_data = m_buff.getSamples[0..m_buff.getSamplesCount];
} }
protected: protected:
bool onStart() bool onStart()
{ {
// No specifics things to do, just return true. // No specifics things to do, just return true.
return true; return true;
} }
bool onGetData(out short[] data) bool onGetData(out short[] data)
{ {
// We ensure that we have enough data to send // We ensure that we have enough data to send
if (m_cursor + this.getSampleRate > m_data.length) if (m_cursor + this.getSampleRate > m_data.length)
return false; return false;
// Assign data in the buffer ... // Assign data in the buffer ...
data = m_data[m_cursor..m_cursor + this.getSampleRate]; data = m_data[m_cursor..m_cursor + this.getSampleRate];
// ... and increment the cursor // ... and increment the cursor
m_cursor += this.getSampleRate; m_cursor += this.getSampleRate;
return true; return true;
} }
} }
void main() void main()
{ {
MySoundStream stream = new MySoundStream(); MySoundStream stream = new MySoundStream();
display("Playing sound !\n Press enter to stop playback."); display("Playing sound !\n Press enter to stop playback.");
stream.play(); stream.play();
read(); read();
stream.stop(); stream.stop();
} }
void display(char[] c) void display(char[] c)
{ {
version (Tango) version (Tango)
{ {
Stdout(c).newline; Stdout(c).newline;
} }
else else
{ {
writefln("%s", c); writefln("%s", c);
} }
} }
/** /**
* Dummy function to prevent console closing on windows * Dummy function to prevent console closing on windows
*/ */
void read() void read()
{ {
version (Tango) version (Tango)
{ {
Cin.get(); Cin.get();
} }
else else
{ {
readln(); readln();
} }
} }

View File

@ -9,64 +9,64 @@ class NetworkRecorder : SoundRecorder
{ {
public: public:
// Constructor // Constructor
this(SocketTCP Socket) this(SocketTCP Socket)
{ {
mySocket = Socket; mySocket = Socket;
} }
~this() ~this()
{ {
delete mySocket; delete mySocket;
} }
protected: protected:
override bool onStart() override bool onStart()
{ {
return true; return true;
} }
override void onStop() override void onStop()
{ {
} }
override bool onProcessSamples(short[] samples) override bool onProcessSamples(short[] samples)
{ {
// Pack the audio samples into a network packet // Pack the audio samples into a network packet
Packet PacketOut = new Packet(); Packet PacketOut = new Packet();
PacketOut.set(AudioData); PacketOut.set(AudioData);
PacketOut.append((cast(byte*)samples.ptr)[0..samples.length * short.sizeof]); PacketOut.append((cast(byte*)samples.ptr)[0..samples.length * short.sizeof]);
// Send the audio packet to the server // Send the audio packet to the server
return mySocket.send(PacketOut) == SocketStatus.DONE; return mySocket.send(PacketOut) == SocketStatus.DONE;
} }
SocketTCP mySocket; ///< Socket used to communicate with the server SocketTCP mySocket; ///< Socket used to communicate with the server
} }
void runClient(IPAddress adr, int port) void runClient(IPAddress adr, int port)
{ {
// Create a TCP socket for communicating with server // Create a TCP socket for communicating with server
SocketTCP Socket = new SocketTCP(); SocketTCP Socket = new SocketTCP();
// Connect to the specified server // Connect to the specified server
if (!Socket.connect(port, adr)) if (!Socket.connect(port, adr))
return; return;
// Wait for user input... // Wait for user input...
Cout("Press enter to start recording audio").newline; Cout("Press enter to start recording audio").newline;
Cin.get(); Cin.get();
// Create a instance of our custom recorder // Create a instance of our custom recorder
NetworkRecorder Recorder = new NetworkRecorder(Socket); NetworkRecorder Recorder = new NetworkRecorder(Socket);
// Start capturing audio data // Start capturing audio data
Recorder.start(44100); Recorder.start(44100);
Cout("Press enter to stop recording audio").newline; Cout("Press enter to stop recording audio").newline;
Cin.get(); Cin.get();
Recorder.stop(); Recorder.stop();
// Send a "end-of-stream" packet // Send a "end-of-stream" packet
Packet PacketOut = new Packet(); Packet PacketOut = new Packet();
PacketOut.set(EndOfStream); PacketOut.set(EndOfStream);
Socket.send(PacketOut); Socket.send(PacketOut);
} }

View File

@ -6,41 +6,41 @@ import client;
int main(char[][] args) int main(char[][] args)
{ {
char[][] argc = args.dup; char[][] argc = args.dup;
if (argc.length > 1) if (argc.length > 1)
{ {
if ( argc[1] == "-c" && if ( argc[1] == "-c" &&
argc.length == 4) argc.length == 4)
{ {
IPAddress adr = IPAddress(argc[2]); IPAddress adr = IPAddress(argc[2]);
if (adr.isValid() && if (adr.isValid() &&
parse(argc[3]) <= 60000 && parse(argc[3]) <= 60000 &&
parse(argc[3]) >= 1000) parse(argc[3]) >= 1000)
{ {
runClient(adr, parse(argc[3])); runClient(adr, parse(argc[3]));
} }
else else
printUsage(); printUsage();
} }
else if ( argc[1] == "-s" && else if ( argc[1] == "-s" &&
argc.length == 3 && argc.length == 3 &&
parse(argc[2]) <= 60000 && parse(argc[2]) <= 60000 &&
parse(argc[2]) >= 1000) parse(argc[2]) >= 1000)
{ {
runServer(parse(argc[2])); runServer(parse(argc[2]));
} }
else else
printUsage(); printUsage();
} }
else else
printUsage(); printUsage();
return 0; return 0;
} }
void printUsage() void printUsage()
{ {
Cout("Usage :\n voip.exe [-c [ip address] | -s] [port] \n -c = run as client\n -s = run as server\n ip address = address of the server\n port = port between 1000 and 65000\n").newline; Cout("Usage :\n voip.exe [-c [ip address] | -s] [port] \n -c = run as client\n -s = run as server\n ip address = address of the server\n port = port between 1000 and 65000\n").newline;
} }

View File

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

View File

@ -1,6 +1,6 @@
module util; module util;
const ubyte AudioData = 1; const ubyte AudioData = 1;
const ubyte EndOfStream = 2; const ubyte EndOfStream = 2;
public import dsfml.system.all; public import dsfml.system.all;
@ -9,41 +9,41 @@ public import dsfml.network.all;
version(Tango) version(Tango)
{ {
public import tango.io.Console; public import tango.io.Console;
public import tango.text.convert.Integer; public import tango.text.convert.Integer;
} }
else else
{ {
public import std.stdio; public import std.stdio;
//simple abstraction of Cout & Cin for phobos //simple abstraction of Cout & Cin for phobos
class Cout class Cout
{ {
static Cout s_c; static Cout s_c;
static this() static this()
{ {
s_c = new Cout(); s_c = new Cout();
} }
static Cout opCall(char[] str) static Cout opCall(char[] str)
{ {
writefln("%s", str); writefln("%s", str);
return s_c; return s_c;
} }
void newline() void newline()
{ {
} }
} }
class Cin class Cin
{ {
static char[] get() static char[] get()
{ {
return readln(); return readln();
} }
} }
public import std.string : atoi; public import std.string : atoi;
alias atoi parse; alias atoi parse;
} }