add play and save audio
This commit is contained in:
@@ -62,4 +62,6 @@ auto main(int argc, char *argv[]) -> int
|
||||
hack::log()(hack::math::max(4, 5));
|
||||
hack::log()(hack::math::max(c, b));
|
||||
}
|
||||
|
||||
hack::warn()("TEST_WARN");
|
||||
}
|
||||
|
||||
76
src/hack/audio/play.hpp
Normal file
76
src/hack/audio/play.hpp
Normal 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();
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user