123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124 |
- #pragma once
- #include <vector>
- #include <fstream>
- #include "AudioSink.h"
- #include <alsa/asoundlib.h>
- #include <stdio.h>
- #include <BellTask.h>
- #include <unistd.h>
- #include <memory>
- #include <mutex>
- #define PCM_DEVICE "default"
- template <typename T, int SIZE>
- class RingbufferPointer
- {
- typedef std::unique_ptr<T> TPointer;
- public:
- explicit RingbufferPointer()
- {
- // create objects
- for (int i = 0; i < SIZE; i++)
- {
- buf_[i] = std::make_unique<T>();
- }
- }
- bool push(TPointer &item)
- {
- std::lock_guard<std::mutex> lock(mutex_);
- if (full())
- return false;
- std::swap(buf_[head_], item);
- if (full_)
- tail_ = (tail_ + 1) % max_size_;
- head_ = (head_ + 1) % max_size_;
- full_ = head_ == tail_;
- return true;
- }
- bool pop(TPointer &item)
- {
- std::lock_guard<std::mutex> lock(mutex_);
- if (empty())
- return false;
- std::swap(buf_[tail_], item);
- full_ = false;
- tail_ = (tail_ + 1) % max_size_;
- return true;
- }
- void reset()
- {
- std::lock_guard<std::mutex> lock(mutex_);
- head_ = tail_;
- full_ = false;
- }
- bool empty() const
- {
- return (!full_ && (head_ == tail_));
- }
- bool full() const
- {
- return full_;
- }
- int capacity() const
- {
- return max_size_;
- }
- int size() const
- {
- int size = max_size_;
- if (!full_)
- {
- if (head_ >= tail_)
- size = head_ - tail_;
- else
- size = max_size_ + head_ - tail_;
- }
- return size;
- }
- private:
- TPointer buf_[SIZE];
- std::mutex mutex_;
- int head_ = 0;
- int tail_ = 0;
- const int max_size_ = SIZE;
- bool full_ = 0;
- };
- class ALSAAudioSink : public AudioSink, public bell::Task
- {
- public:
- ALSAAudioSink();
- ~ALSAAudioSink();
- void feedPCMFrames(const uint8_t *buffer, size_t bytes);
- void runTask();
- private:
- RingbufferPointer<std::vector<uint8_t>, 3> ringbuffer;
- unsigned int pcm;
- snd_pcm_t *pcm_handle;
- snd_pcm_hw_params_t *params;
- snd_pcm_uframes_t frames;
- int buff_size;
- std::vector<uint8_t> buff;
- };
|