diff --git a/source/Client.cpp b/source/Client.cpp index d15e815..36f22c6 100644 --- a/source/Client.cpp +++ b/source/Client.cpp @@ -30,7 +30,7 @@ Client::Client(const int channels, const double rate) { nullptr, nullptr ) != paNoError) - throw std::runtime_error("Could not open PortAudio stream."); + throw std::runtime_error("[Client] Could not open PortAudio stream."); } Client::~Client() { @@ -57,7 +57,7 @@ void Client::loopReceiver() { 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 addrinfo serverHints = {}; @@ -73,7 +73,7 @@ void Client::loopReceiver() { &serverHints, &serverInfo ) != 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 if (bind( @@ -81,7 +81,7 @@ void Client::loopReceiver() { serverInfo->ai_addr, serverInfo->ai_addrlen ) < 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 freeaddrinfo(serverInfo); @@ -104,12 +104,12 @@ void Client::loopReceiver() { &serverAddressLength ); 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; } // 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); // notify that a new audio chunk is available this->audioCondition.notify_one(); @@ -117,10 +117,6 @@ void Client::loopReceiver() { } 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) { // wait for a new element in the audio queue this->audioCondition.wait( @@ -132,10 +128,10 @@ void Client::loopPlayer() { // wait until it must be played std::this_thread::sleep_until(audioPacket.timePlay); - // TODO(Faraphel): check for the error ? // TODO(Faraphel) / 2 => / encoding size // 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; @@ -148,13 +144,13 @@ void Client::loopPlayer() { switch (error) { // success 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. case paOutputUnderflowed: break; 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 diff --git a/source/Client.hpp b/source/Client.hpp index 24925bf..5210a59 100644 --- a/source/Client.hpp +++ b/source/Client.hpp @@ -18,15 +18,33 @@ struct AudioPacketsComparator { }; +/** + * the audio Client. + * Receive audio packets and play them at a specific time. + */ class Client { public: + /** + * :param channels: the number of channel in the audio + * :param rate: the rate of the audio + */ explicit Client(int channels, double rate); ~Client(); + /** + * Indefinitely receive and play audio data. + */ void loop(); private: + /** + * Indefinitely receive audio data. + */ void loopReceiver(); + + /** + * Indefinitely play audio data. + */ void loopPlayer(); PaStream* stream; diff --git a/source/Server.cpp b/source/Server.cpp index a19cedb..6b1b0fc 100644 --- a/source/Server.cpp +++ b/source/Server.cpp @@ -17,13 +17,15 @@ Server::Server() { // create a new mpg123 handle int 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 if (mpg123_open( this->mpgHandle, "./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 if (mpg123_getformat( @@ -32,7 +34,7 @@ Server::Server() { &this->channels, &this->encoding ) != 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() { @@ -42,8 +44,6 @@ Server::~Server() { } void Server::loop() { - int error; - // get the broadcast address addrinfo broadcastHints {}; broadcastHints.ai_family = AF_INET6; @@ -52,13 +52,13 @@ void Server::loop() { // TODO(Faraphel): ip / port as argument addrinfo *broadcastInfo; - if((error = getaddrinfo( + if(const int error = getaddrinfo( "::1", "5650", &broadcastHints, &broadcastInfo - )) != 0) - throw std::runtime_error("Could not get the address.\n" + std::string(gai_strerror(error))); + ) != 0) + throw std::runtime_error("[Server] Could not get the address: " + std::string(gai_strerror(error))); const int broadcastSocket = socket( broadcastInfo->ai_family, @@ -66,7 +66,7 @@ void Server::loop() { broadcastInfo->ai_protocol ); 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 AudioPacket audioPacket; @@ -93,10 +93,12 @@ void Server::loop() { 0, broadcastInfo->ai_addr, broadcastInfo->ai_addrlen - ) == -1) - std::cerr << "Could not send audio packet : " << strerror(errno) << std::endl; - else - std::cout << "[Server] sent : " << done << " bytes" << std::endl; + ) == -1) { + std::cerr << "[Server] Could not send audio packet: " << strerror(errno) << std::endl; + continue; + } + + std::cout << "[Server] Sent: " << done << " bytes" << std::endl; // wait 10ms to simulate lag // TODO(Faraphel): should be extended to simulate live music streaming diff --git a/source/Server.hpp b/source/Server.hpp index 5f80248..bb7d11d 100644 --- a/source/Server.hpp +++ b/source/Server.hpp @@ -2,15 +2,34 @@ #include +/** + * the audio Server. + * Read and broadcast audio data. + */ class Server { public: explicit Server(); ~Server(); + /** + * Indefinitely read and broadcast audio data. + */ void loop(); + /** + * get the current rate of the audio data. + * @return the current rate of the audio data. + */ 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; + /** + * get the current encoding of the audio data. + * @return the current encoding of the audio data. + */ int getEncoding() const; private: