diff options
author | Roland Reichwein <mail@reichwein.it> | 2025-01-03 21:02:11 +0100 |
---|---|---|
committer | Roland Reichwein <mail@reichwein.it> | 2025-01-03 21:02:11 +0100 |
commit | 22cdfccb11679d6ae241653c9cb92c32f4fc1fde (patch) | |
tree | 16b0f8401e22c99e8d953eea14ac57a2fe50c67a /PCM.h | |
parent | 6bf4770e950299da92952f2965cccf86a903fc9f (diff) |
Integrate ClickStream into PCM
Diffstat (limited to 'PCM.h')
-rw-r--r-- | PCM.h | 60 |
1 files changed, 52 insertions, 8 deletions
@@ -1,22 +1,29 @@ #pragma once -#include "ClickStream.h" - #include "config.h" +#include "log.h" + +#include <libreichwein/file.h> #include <alsa/asoundlib.h> #include <fmt/format.h> #include <iostream> #include <string> +#include <vector> using namespace std::string_literals; class PCM { public: - PCM(ClickStream& stream): m_stream(stream) + PCM(): m_phase(1000000) { + // prepare the sample + std::string data_s = Reichwein::File::getFile("media/click.s16le"); + m_data.resize(data_s.size() / 2); // src is in bytes + memcpy(m_data.data(), data_s.data(), data_s.size()); + // non-blocking if ((err = snd_pcm_open(&handle, device, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK)) < 0) { throw std::runtime_error(fmt::format("Playback open error: {}", snd_strerror(err))); @@ -27,11 +34,11 @@ public: 1, f_sample, 1, - 100000)) < 0) { // latency in us + pcm_latency_us)) < 0) { // latency in us throw std::runtime_error(fmt::format("Playback open error: {}", snd_strerror(err))); } - m_stream.generate(); + generate(); npfd = snd_pcm_poll_descriptors_count(handle); if (npfd < 0) { @@ -69,6 +76,33 @@ public: free(pfd); } + void click() + { + snd_pcm_sframes_t delay; + if (0 > snd_pcm_delay(handle, &delay)) { + } + + m_phase = 0; // - click_latency_frames + delay + } + + // generate 1 buffer size + void generate() + { + int i; + + for (i = 0; i < nframes; i++) { + if (m_phase < 0 || m_phase >= m_data.size()) + { + buffer[i] = 0; + } + else + { + buffer[i] = m_data[m_phase]; + } + m_phase++; + } + } + int fd() { return pfd->fd; @@ -77,7 +111,7 @@ public: // write from buffer to ALSA PCM void write() { - snd_pcm_sframes_t written = snd_pcm_writei(handle, m_stream.get_buffer(), nframes); + snd_pcm_sframes_t written = snd_pcm_writei(handle, buffer, nframes); if (written < 0) { if (written == -EPIPE) { std::cout << "Warning: PCM underrun" << std::endl; @@ -93,7 +127,15 @@ public: std::cout << "Warning: written " << std::to_string(written) << " frames instead of "<< std::to_string(nframes) << std::endl; } - m_stream.generate(); + snd_pcm_sframes_t avail; + snd_pcm_sframes_t delay; + if (0 > snd_pcm_avail_delay(handle, &avail, &delay)) { + log_cout << "Error detecting avail and delay" << std::endl; + } else { + log_cout << fmt::format("Delay: {}, avail. buffer; {} frames", delay, avail) << std::endl; + } + + generate(); } bool wait_for_event() @@ -130,6 +172,8 @@ private: int npfd; struct pollfd* pfd; - ClickStream& m_stream; + std::vector<uint16_t> m_data; + int32_t m_phase; + int16_t buffer[nframes]; }; |