diff --git a/bin/main.cpp b/bin/main.cpp index aa1b2ac..7a43ef4 100644 --- a/bin/main.cpp +++ b/bin/main.cpp @@ -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"); } diff --git a/src/hack/audio/play.hpp b/src/hack/audio/play.hpp new file mode 100644 index 0000000..b1ee2ff --- /dev/null +++ b/src/hack/audio/play.hpp @@ -0,0 +1,76 @@ +#pragma once + +#include +#include "hack/logger/logger.hpp" +#include + +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*>(data); + static size_t pos = 0; + auto* out = static_cast(output_buffer); + + for (unsigned long i = 0; i < frames; ++i) + { + // передаем даннеы если есть, иначе - тишина. + if (pos < samples.size()) out[i] = static_cast(samples[pos++]); + else out[i] = 0.0f; + } + + return (pos >= samples.size()) ? paComplete : paContinue; + } + } + + // пока только wav + inline void play(std::vector& 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(); + } +} diff --git a/src/hack/utils/save_wav.hpp b/src/hack/audio/save.hpp similarity index 90% rename from src/hack/utils/save_wav.hpp rename to src/hack/audio/save.hpp index a39de94..fe6512e 100644 --- a/src/hack/utils/save_wav.hpp +++ b/src/hack/audio/save.hpp @@ -7,7 +7,8 @@ namespace hack::utils { - inline void save_wav(const std::string& path, const std::vector& samples, int sample_rate) + // пока только wav + inline void save(const std::string& path, const std::vector& samples, int sample_rate) { SF_INFO sf_info; sf_info.samplerate = sample_rate; @@ -34,3 +35,4 @@ namespace hack::utils } } +