diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..0bc1f7d --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,26 @@ +cmake_minimum_required(VERSION 3.28) +project(M2-PT-DRP LANGUAGES CXX) + + +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + + +find_package(PkgConfig REQUIRED) +pkg_check_modules(MPG123 REQUIRED libmpg123) +pkg_check_modules(PORTAUDIO REQUIRED portaudio-2.0) + + +add_executable(M2-PT-DRP + source/connection.cpp + source/stream.cpp + source/stream.hpp +) +target_include_directories(M2-PT-DRP PRIVATE + ${MPG123_INCLUDE_DIRS} + ${PORTAUDIO_INCLUDE_DIRS} +) +target_link_libraries(M2-PT-DRP PRIVATE + ${MPG123_LIBRARIES} + ${PORTAUDIO_LIBRARIES} +) \ No newline at end of file diff --git a/source/connection.cpp b/source/connection.cpp new file mode 100644 index 0000000..d24e7b4 --- /dev/null +++ b/source/connection.cpp @@ -0,0 +1,51 @@ +#include "connection.hpp" + + +#include +#include +#include +#include +#include +#include + + +/* +int main(int argc, char* argv[]) { + // create an IPv6 socket based on datagram (UDP) + const int serverSocket = socket( + AF_INET6, + SOCK_DGRAM, + 0 + ); + + // get the broadcast address + addrinfo broadcastAddressConfig = {}; + broadcastAddressConfig.ai_family = AF_INET6; + broadcastAddressConfig.ai_socktype = SOCK_DGRAM; + broadcastAddressConfig.ai_protocol = IPPROTO_UDP; + + addrinfo *broadcastAddress; + if(!getaddrinfo( + "ff02::1", // multicast address + "5650", // our port + &broadcastAddressConfig, + &broadcastAddress + )) + throw std::runtime_error("Could not get the address."); + + const std::string message = "Salut !"; + + // broadcast the message + if (sendto( + serverSocket, + message.c_str(), + message.size(), + 0, + broadcastAddress->ai_addr, + broadcastAddress->ai_addrlen + ) == -1) + throw std::runtime_error("Could not broadcast the message."); + + return 0; +} +*/ diff --git a/source/connection.hpp b/source/connection.hpp new file mode 100644 index 0000000..6f70f09 --- /dev/null +++ b/source/connection.hpp @@ -0,0 +1 @@ +#pragma once diff --git a/source/stream.cpp b/source/stream.cpp new file mode 100644 index 0000000..7b5b2db --- /dev/null +++ b/source/stream.cpp @@ -0,0 +1,93 @@ +#include "stream.hpp" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + + +int main(int argc, char* argv[]) { + // initialize the mpg123 library + if (mpg123_init() != MPG123_OK) + throw std::runtime_error("Error while initializing mpg123."); + + // create a new mpg123 handle + int error; + mpg123_handle* mpgHandle = mpg123_new(nullptr, &error); + + // open the mp3 file + if (mpg123_open(mpgHandle, "./assets/Caravan Palace - Wonderland.mp3")) + throw std::runtime_error("Could not open file."); + + // get the format of the file + long rate; + int channels; + int encoding; + mpg123_getformat(mpgHandle, &rate, &channels, &encoding); + printf("rate: %ld, channels: %d, encoding: %d\n", rate, channels, encoding); + + // --- + + // initialize the PortAudio library + if (Pa_Initialize() != paNoError) + throw std::runtime_error("Could not initialize PortAudio."); + + // open the PortAudio stream + PaStream* stream; + if (Pa_OpenDefaultStream( + &stream, + 0, + channels, + paInt16, + static_cast(rate), + 512, + nullptr, + nullptr + ) != paNoError) + throw std::runtime_error("Could not open PortAudio stream."); + + // start the PortAudio stream + if (Pa_StartStream(stream) != paNoError) + throw std::runtime_error("Could not start the PortAudio stream."); + + // --- + + // read the file + std::vector buffer(4096); + std::size_t done; + std::size_t i = 0; + + while ((error = mpg123_read(mpgHandle, buffer.data(), buffer.size(), &done)) == MPG123_OK) { + // write the audio data to the PortAudio stream + if ((error = Pa_WriteStream(stream, buffer.data(), done / 2 / channels)) != paNoError) + throw std::runtime_error( + "Could not write audio data in the PortAudio stream.\n" + + std::string(Pa_GetErrorText(error)) + ); + + printf("write (%04lu)\n", i++); + } + + // display the error message + std::printf(mpg123_plain_strerror(error)); + + // Stop the audio stream + Pa_StopStream(stream); + Pa_CloseStream(stream); + + // delete the mpg123 handle + mpg123_close(mpgHandle); + mpg123_delete(mpgHandle); + + // free the libraries + Pa_Terminate(); + mpg123_exit(); + + return error; +} diff --git a/source/stream.hpp b/source/stream.hpp new file mode 100644 index 0000000..6f70f09 --- /dev/null +++ b/source/stream.hpp @@ -0,0 +1 @@ +#pragma once