example of playing audio in chunk

This commit is contained in:
faraphel 2024-10-13 16:58:43 +02:00
parent 771d345b8c
commit 270017b1d3
5 changed files with 172 additions and 0 deletions

26
CMakeLists.txt Normal file
View file

@ -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}
)

51
source/connection.cpp Normal file
View file

@ -0,0 +1,51 @@
#include "connection.hpp"
#include <chrono>
#include <stdexcept>
#include <string>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
/*
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;
}
*/

1
source/connection.hpp Normal file
View file

@ -0,0 +1 @@
#pragma once

93
source/stream.cpp Normal file
View file

@ -0,0 +1,93 @@
#include "stream.hpp"
#include <algorithm>
#include <chrono>
#include <cstdint>
#include <iostream>
#include <stdexcept>
#include <vector>
#include <openssl/aes.h>
#include <mpg123.h>
#include <portaudio.h>
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<double>(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<std::uint8_t> 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;
}

1
source/stream.hpp Normal file
View file

@ -0,0 +1 @@
#pragma once