example of playing audio in chunk
This commit is contained in:
parent
771d345b8c
commit
270017b1d3
5 changed files with 172 additions and 0 deletions
26
CMakeLists.txt
Normal file
26
CMakeLists.txt
Normal 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
51
source/connection.cpp
Normal 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
1
source/connection.hpp
Normal file
|
@ -0,0 +1 @@
|
||||||
|
#pragma once
|
93
source/stream.cpp
Normal file
93
source/stream.cpp
Normal 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
1
source/stream.hpp
Normal file
|
@ -0,0 +1 @@
|
||||||
|
#pragma once
|
Loading…
Reference in a new issue