add play and save audio

This commit is contained in:
2025-04-22 16:04:30 +03:00
parent 4252eb88ce
commit ad3786465d
3 changed files with 81 additions and 1 deletions

76
src/hack/audio/play.hpp Normal file
View File

@@ -0,0 +1,76 @@
#pragma once
#include <vector>
#include "hack/logger/logger.hpp"
#include <portaudio.h>
namespace hack::utils
{
namespace
{
const int FRAMES_PER_BUFFER = 256;
// callback - вызывается, когда нужны новые аудио-данные
static int callback(const void*, void* output_buffer, unsigned long frames, const PaStreamCallbackTimeInfo*, PaStreamCallbackFlags, void* data)
{
auto& samples = *static_cast<std::vector<double>*>(data);
static size_t pos = 0;
auto* out = static_cast<float*>(output_buffer);
for (unsigned long i = 0; i < frames; ++i)
{
// передаем даннеы если есть, иначе - тишина.
if (pos < samples.size()) out[i] = static_cast<float>(samples[pos++]);
else out[i] = 0.0f;
}
return (pos >= samples.size()) ? paComplete : paContinue;
}
}
// пока только wav
inline void play(std::vector<double>& samples, int sample_rate)
{
PaError err = Pa_Initialize();
if (err != paNoError)
{
hack::error()("PortAudio error: ", Pa_GetErrorText(err));
return;
}
// открытие потока
PaStream* stream;
err = Pa_OpenDefaultStream(&stream,
0, // Нет входных каналов
1, // 1 выходной канал (моно)
paFloat32, // 32-bit floating-point output
sample_rate,
FRAMES_PER_BUFFER,
callback,
samples.data());
if (err != paNoError)
{
std::cerr << "PortAudio error: " << Pa_GetErrorText(err) << std::endl;
Pa_Terminate();
return;
}
// запуск потока
err = Pa_StartStream(stream);
if (err != paNoError)
{
std::cerr << "PortAudio error: " << Pa_GetErrorText(err) << std::endl;
Pa_CloseStream(stream);
Pa_Terminate();
return;
}
// ждём окончания воспроизведения
while (Pa_IsStreamActive(stream)) Pa_Sleep(100); // Пауза 100 мс между проверками
// очистка
Pa_CloseStream(stream);
Pa_Terminate();
}
}

View File

@@ -7,7 +7,8 @@
namespace hack::utils
{
inline void save_wav(const std::string& path, const std::vector<float>& samples, int sample_rate)
// пока только wav
inline void save(const std::string& path, const std::vector<float>& samples, int sample_rate)
{
SF_INFO sf_info;
sf_info.samplerate = sample_rate;
@@ -34,3 +35,4 @@ namespace hack::utils
}
}