mirror of
https://github.com/sle118/squeezelite-esp32.git
synced 2025-12-10 21:47:04 +03:00
catching up (trying to) wiht CSpot
This commit is contained in:
124
components/spotify/cspot/bell/include/sinks/unix/ALSAAudioSink.h
Normal file
124
components/spotify/cspot/bell/include/sinks/unix/ALSAAudioSink.h
Normal file
@@ -0,0 +1,124 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <fstream>
|
||||
#include "AudioSink.h"
|
||||
#include <alsa/asoundlib.h>
|
||||
#include <stdio.h>
|
||||
#include <Task.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;
|
||||
};
|
||||
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <fstream>
|
||||
#include "AudioSink.h"
|
||||
|
||||
class NamedPipeAudioSink : public AudioSink
|
||||
{
|
||||
public:
|
||||
NamedPipeAudioSink();
|
||||
~NamedPipeAudioSink();
|
||||
void feedPCMFrames(const uint8_t *buffer, size_t bytes);
|
||||
|
||||
private:
|
||||
std::ofstream namedPipeFile;
|
||||
};
|
||||
@@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include "portaudio.h"
|
||||
#include <stdint.h>
|
||||
#include <iostream>
|
||||
#include "AudioSink.h"
|
||||
|
||||
class PortAudioSink : public AudioSink
|
||||
{
|
||||
public:
|
||||
PortAudioSink();
|
||||
~PortAudioSink();
|
||||
void feedPCMFrames(const uint8_t *buffer, size_t bytes);
|
||||
void initialize(uint16_t sampleRate);
|
||||
bool setRate(uint16_t sampleRate) override;
|
||||
|
||||
private:
|
||||
PaStream *stream;
|
||||
};
|
||||
Reference in New Issue
Block a user