cleaned some messages and improved the documentation
This commit is contained in:
parent
b8edda302d
commit
73be1f9a80
4 changed files with 61 additions and 26 deletions
|
@ -30,7 +30,7 @@ Client::Client(const int channels, const double rate) {
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr
|
nullptr
|
||||||
) != paNoError)
|
) != paNoError)
|
||||||
throw std::runtime_error("Could not open PortAudio stream.");
|
throw std::runtime_error("[Client] Could not open PortAudio stream.");
|
||||||
}
|
}
|
||||||
|
|
||||||
Client::~Client() {
|
Client::~Client() {
|
||||||
|
@ -57,7 +57,7 @@ void Client::loopReceiver() {
|
||||||
0
|
0
|
||||||
);
|
);
|
||||||
if (clientSocket < 0)
|
if (clientSocket < 0)
|
||||||
throw std::runtime_error("Could not create the socket." + std::string(gai_strerror(errno)));
|
throw std::runtime_error("[Client] Could not create the socket." + std::string(gai_strerror(errno)));
|
||||||
|
|
||||||
// get the broadcast address
|
// get the broadcast address
|
||||||
addrinfo serverHints = {};
|
addrinfo serverHints = {};
|
||||||
|
@ -73,7 +73,7 @@ void Client::loopReceiver() {
|
||||||
&serverHints,
|
&serverHints,
|
||||||
&serverInfo
|
&serverInfo
|
||||||
) != 0)
|
) != 0)
|
||||||
throw std::runtime_error("Could not get the address.\n" + std::string(gai_strerror(errno)));
|
throw std::runtime_error("[Client] Could not get the address: " + std::string(gai_strerror(errno)));
|
||||||
|
|
||||||
// bind the socket to the address
|
// bind the socket to the address
|
||||||
if (bind(
|
if (bind(
|
||||||
|
@ -81,7 +81,7 @@ void Client::loopReceiver() {
|
||||||
serverInfo->ai_addr,
|
serverInfo->ai_addr,
|
||||||
serverInfo->ai_addrlen
|
serverInfo->ai_addrlen
|
||||||
) < 0)
|
) < 0)
|
||||||
throw std::runtime_error("Could not bind to the address.");
|
throw std::runtime_error("[Client] Could not bind to the address." + std::string(gai_strerror(errno)));
|
||||||
|
|
||||||
// free the server address
|
// free the server address
|
||||||
freeaddrinfo(serverInfo);
|
freeaddrinfo(serverInfo);
|
||||||
|
@ -104,12 +104,12 @@ void Client::loopReceiver() {
|
||||||
&serverAddressLength
|
&serverAddressLength
|
||||||
);
|
);
|
||||||
if (size == -1) {
|
if (size == -1) {
|
||||||
std::cerr << "Could not receive from the socket : " << gai_strerror(errno) << std::endl;
|
std::cerr << "[Client] Could not receive from the socket: " << gai_strerror(errno) << std::endl;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// save the audio data into the queue for the player
|
// save the audio data into the queue for the player
|
||||||
std::cout << "[Client] received : " << size << " bytes" << std::endl;
|
std::cout << "[Client] Received: " << size << " bytes" << std::endl;
|
||||||
this->audioQueue.push(audioPacket);
|
this->audioQueue.push(audioPacket);
|
||||||
// notify that a new audio chunk is available
|
// notify that a new audio chunk is available
|
||||||
this->audioCondition.notify_one();
|
this->audioCondition.notify_one();
|
||||||
|
@ -117,10 +117,6 @@ void Client::loopReceiver() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::loopPlayer() {
|
void Client::loopPlayer() {
|
||||||
// start the PortAudio stream
|
|
||||||
if (Pa_StartStream(this->stream) != paNoError)
|
|
||||||
throw std::runtime_error("Could not start the PortAudio stream.");
|
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
// wait for a new element in the audio queue
|
// wait for a new element in the audio queue
|
||||||
this->audioCondition.wait(
|
this->audioCondition.wait(
|
||||||
|
@ -132,10 +128,10 @@ void Client::loopPlayer() {
|
||||||
// wait until it must be played
|
// wait until it must be played
|
||||||
std::this_thread::sleep_until(audioPacket.timePlay);
|
std::this_thread::sleep_until(audioPacket.timePlay);
|
||||||
|
|
||||||
// TODO(Faraphel): check for the error ?
|
|
||||||
// TODO(Faraphel) / 2 => / encoding size
|
// TODO(Faraphel) / 2 => / encoding size
|
||||||
// TODO(Faraphel): the number of frames could be improved
|
// TODO(Faraphel): the number of frames could be improved
|
||||||
// TODO(Faraphel): more comments
|
|
||||||
|
std::cout << "[Client] Playing: " << audioPacket.timePlay << std::endl;
|
||||||
|
|
||||||
std::cout << "playing: " << audioPacket.timePlay << std::endl;
|
std::cout << "playing: " << audioPacket.timePlay << std::endl;
|
||||||
|
|
||||||
|
@ -148,13 +144,13 @@ void Client::loopPlayer() {
|
||||||
switch (error) {
|
switch (error) {
|
||||||
// success
|
// success
|
||||||
case paNoError:
|
case paNoError:
|
||||||
// the output might be very slightly underflowed,
|
// the output might be very slightly underflown,
|
||||||
// causing a very small period where no noise will be played.
|
// causing a very small period where no noise will be played.
|
||||||
case paOutputUnderflowed:
|
case paOutputUnderflowed:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
std::cerr << "Could not write to the PortAudio stream." << Pa_GetErrorText(error) << std::endl;
|
std::cerr << "[Client] Could not write to the PortAudio stream: " << Pa_GetErrorText(error) << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove the audio chunk
|
// remove the audio chunk
|
||||||
|
|
|
@ -18,15 +18,33 @@ struct AudioPacketsComparator {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the audio Client.
|
||||||
|
* Receive audio packets and play them at a specific time.
|
||||||
|
*/
|
||||||
class Client {
|
class Client {
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* :param channels: the number of channel in the audio
|
||||||
|
* :param rate: the rate of the audio
|
||||||
|
*/
|
||||||
explicit Client(int channels, double rate);
|
explicit Client(int channels, double rate);
|
||||||
~Client();
|
~Client();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indefinitely receive and play audio data.
|
||||||
|
*/
|
||||||
void loop();
|
void loop();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
/**
|
||||||
|
* Indefinitely receive audio data.
|
||||||
|
*/
|
||||||
void loopReceiver();
|
void loopReceiver();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indefinitely play audio data.
|
||||||
|
*/
|
||||||
void loopPlayer();
|
void loopPlayer();
|
||||||
|
|
||||||
PaStream* stream;
|
PaStream* stream;
|
||||||
|
|
|
@ -17,13 +17,15 @@ Server::Server() {
|
||||||
// create a new mpg123 handle
|
// create a new mpg123 handle
|
||||||
int error;
|
int error;
|
||||||
this->mpgHandle = mpg123_new(nullptr, &error);
|
this->mpgHandle = mpg123_new(nullptr, &error);
|
||||||
|
if (this->mpgHandle == nullptr)
|
||||||
|
throw std::runtime_error("[Server] Could not create a mpg123 handle.");
|
||||||
|
|
||||||
// open the mp3 file
|
// open the mp3 file
|
||||||
if (mpg123_open(
|
if (mpg123_open(
|
||||||
this->mpgHandle,
|
this->mpgHandle,
|
||||||
"./assets/Caravan Palace - Wonderland.mp3"
|
"./assets/Caravan Palace - Wonderland.mp3"
|
||||||
))
|
))
|
||||||
throw std::runtime_error("Could not open file.");
|
throw std::runtime_error("[Server] Could not open file.");
|
||||||
|
|
||||||
// get the format of the file
|
// get the format of the file
|
||||||
if (mpg123_getformat(
|
if (mpg123_getformat(
|
||||||
|
@ -32,7 +34,7 @@ Server::Server() {
|
||||||
&this->channels,
|
&this->channels,
|
||||||
&this->encoding
|
&this->encoding
|
||||||
) != MPG123_OK)
|
) != MPG123_OK)
|
||||||
throw std::runtime_error("Could not get the format of the file.");
|
throw std::runtime_error("[Server] Could not get the format of the file.");
|
||||||
}
|
}
|
||||||
|
|
||||||
Server::~Server() {
|
Server::~Server() {
|
||||||
|
@ -42,8 +44,6 @@ Server::~Server() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::loop() {
|
void Server::loop() {
|
||||||
int error;
|
|
||||||
|
|
||||||
// get the broadcast address
|
// get the broadcast address
|
||||||
addrinfo broadcastHints {};
|
addrinfo broadcastHints {};
|
||||||
broadcastHints.ai_family = AF_INET6;
|
broadcastHints.ai_family = AF_INET6;
|
||||||
|
@ -52,13 +52,13 @@ void Server::loop() {
|
||||||
|
|
||||||
// TODO(Faraphel): ip / port as argument
|
// TODO(Faraphel): ip / port as argument
|
||||||
addrinfo *broadcastInfo;
|
addrinfo *broadcastInfo;
|
||||||
if((error = getaddrinfo(
|
if(const int error = getaddrinfo(
|
||||||
"::1",
|
"::1",
|
||||||
"5650",
|
"5650",
|
||||||
&broadcastHints,
|
&broadcastHints,
|
||||||
&broadcastInfo
|
&broadcastInfo
|
||||||
)) != 0)
|
) != 0)
|
||||||
throw std::runtime_error("Could not get the address.\n" + std::string(gai_strerror(error)));
|
throw std::runtime_error("[Server] Could not get the address: " + std::string(gai_strerror(error)));
|
||||||
|
|
||||||
const int broadcastSocket = socket(
|
const int broadcastSocket = socket(
|
||||||
broadcastInfo->ai_family,
|
broadcastInfo->ai_family,
|
||||||
|
@ -66,7 +66,7 @@ void Server::loop() {
|
||||||
broadcastInfo->ai_protocol
|
broadcastInfo->ai_protocol
|
||||||
);
|
);
|
||||||
if (broadcastSocket == -1)
|
if (broadcastSocket == -1)
|
||||||
throw std::runtime_error("Could not create the socket: " + std::string(gai_strerror(errno)));
|
throw std::runtime_error("[Server] Could not create the socket: " + std::string(gai_strerror(errno)));
|
||||||
|
|
||||||
// read the file
|
// read the file
|
||||||
AudioPacket audioPacket;
|
AudioPacket audioPacket;
|
||||||
|
@ -93,10 +93,12 @@ void Server::loop() {
|
||||||
0,
|
0,
|
||||||
broadcastInfo->ai_addr,
|
broadcastInfo->ai_addr,
|
||||||
broadcastInfo->ai_addrlen
|
broadcastInfo->ai_addrlen
|
||||||
) == -1)
|
) == -1) {
|
||||||
std::cerr << "Could not send audio packet : " << strerror(errno) << std::endl;
|
std::cerr << "[Server] Could not send audio packet: " << strerror(errno) << std::endl;
|
||||||
else
|
continue;
|
||||||
std::cout << "[Server] sent : " << done << " bytes" << std::endl;
|
}
|
||||||
|
|
||||||
|
std::cout << "[Server] Sent: " << done << " bytes" << std::endl;
|
||||||
|
|
||||||
// wait 10ms to simulate lag
|
// wait 10ms to simulate lag
|
||||||
// TODO(Faraphel): should be extended to simulate live music streaming
|
// TODO(Faraphel): should be extended to simulate live music streaming
|
||||||
|
|
|
@ -2,15 +2,34 @@
|
||||||
#include <mpg123.h>
|
#include <mpg123.h>
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the audio Server.
|
||||||
|
* Read and broadcast audio data.
|
||||||
|
*/
|
||||||
class Server {
|
class Server {
|
||||||
public:
|
public:
|
||||||
explicit Server();
|
explicit Server();
|
||||||
~Server();
|
~Server();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indefinitely read and broadcast audio data.
|
||||||
|
*/
|
||||||
void loop();
|
void loop();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the current rate of the audio data.
|
||||||
|
* @return the current rate of the audio data.
|
||||||
|
*/
|
||||||
long getRate() const;
|
long getRate() const;
|
||||||
|
/**
|
||||||
|
* get the current number of channels of the audio data.
|
||||||
|
* @return the current number of channels of the audio data.
|
||||||
|
*/
|
||||||
int getChannels() const;
|
int getChannels() const;
|
||||||
|
/**
|
||||||
|
* get the current encoding of the audio data.
|
||||||
|
* @return the current encoding of the audio data.
|
||||||
|
*/
|
||||||
int getEncoding() const;
|
int getEncoding() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
Loading…
Reference in a new issue