vdr-plugin-softhddevice-drm-gles 1.6.2
audio.h
Go to the documentation of this file.
1// SPDX-License-Identifier: AGLP-3.0-or-later
2
18#ifndef __AUDIO_H
19#define __AUDIO_H
20
21#include <atomic>
22#include <chrono>
23#include <mutex>
24#include <vector>
25
26extern "C" {
27#include <libavcodec/avcodec.h>
28#include <libavfilter/avfilter.h>
29}
30
31#include <alsa/asoundlib.h>
32
33#include <vdr/thread.h>
34
35#include "event.h"
36#include "filllevel.h"
37#include "pidcontroller.h"
38#include "ringbuffer.h"
39
40class cSoftHdConfig;
41class cSoftHdDevice;
42
46class cSoftHdAudio : public cThread {
47public:
49
50 void LazyInit(void);
51 void Exit(void);
52 int Setup(AVCodecContext *, int , int , int);
53 void SetPaused(bool);
54 bool IsPaused(void) { return m_paused; };
55 void Filter(AVFrame *, AVCodecContext *);
56 void EnqueueSpdif(uint16_t *, int, AVFrame *);
58
59 void FlushBuffers(void);
60 int GetUsedBytes(void);
61 int64_t GetHardwareOutputPtsMs(void);
62 int64_t GetHardwareOutputDelayMs(void);
64 int GetPassthrough(void) const { return m_passthrough; }
65 bool HasInputPts(void) { return m_inputPts != AV_NOPTS_VALUE; }
66 int64_t GetInputPtsMs(void) { return PtsToMs(m_inputPts); }
67 int64_t GetOutputPtsMs(void);
69
70 void SetEq(int[18], int);
71 void SetVolume(int);
72 void SetDownmix(int downMix) { m_downmix = downMix; };
73 void SetSoftvol(bool softVolume) { m_softVolume = softVolume; };
74 void SetNormalize(bool, int);
75 void SetCompression(bool, int);
76 void SetStereoDescent(int);
77 void SetPassthroughMask(int);
78 void SetAutoAES(bool appendAes) { m_appendAES = appendAes; }
79 void SetTimebase(AVRational *timebase) { m_pTimebase = timebase; };
80
81 void DropSamplesOlderThanPtsMs(int64_t);
82 void ClockDriftCompensation(void);
83 void ResetHwDelayBaseline(void);
84 void SetHwDelayBaseline(void);
85
86 void Stop(void);
87
88protected:
89 virtual void Action(void);
90
91private:
92 constexpr static int AUDIO_MIN_BUFFER_FREE = 3072 * 8 * 8;
93 constexpr static int NORMALIZE_MAX_INDEX = 128;
94 constexpr static int AV_SYNC_BORDER_MS = 5000;
99 cPidController m_pidController{3, 0.005, 0, 1000};
100 std::chrono::steady_clock::time_point m_lastPidInvocation;
103
104 // common audio, alsa
105 bool m_initialized = false;
106 const int m_bytesPerSample = 2;
107 unsigned int m_hwSampleRate = 0;
108 unsigned int m_hwNumChannels = 0;
109 AVRational *m_pTimebase;
110 std::mutex m_mutex;
111 std::mutex m_pauseMutex;
112 std::vector<Event> m_eventQueue;
113 std::atomic<double> m_pitchPpm = 0;
115
117
119 std::atomic<bool> m_paused = true;
120
123 const char *m_pPCMDevice;
127 std::vector<uint16_t> m_pauseBurst;
130
131 void Enqueue(uint16_t *, int, AVFrame *);
132 void EnqueueFrame(AVFrame *);
133 bool SendAudio(int);
134 bool SendPause(void);
135 void BuildPauseBurst(void);
136
137 // Normalizer
139 const int m_normalizeSamples = 4096;
145 const int m_normalizeMinFactor = 100;
147 void Normalize(uint16_t *, int);
148
149 // Compressor
153 void Compress(uint16_t *, int);
154
155 // Amplifier
158 int m_volume = 0;
159 void SoftAmplify(int16_t *, int);
160
161 // Equalizer
163 float m_equalizerBand[18];
164
165 // mixer
166 const char *m_pMixerDevice = nullptr;
167 const char *m_pMixerChannel;
168
169 // filter
176 AVFrame *FilterGetFrame(void);
178
179 // ring buffer variables
180 static constexpr unsigned RINGBUFFER_SIZE = 3 * 5 * 7 * 8 * 2 * 1000;
182
183 // alsa
189
190 int AlsaSetup(int channels, int sample_rate, int passthrough);
191 char *OpenAlsaDevice(const char *, int);
192 char *FindAlsaDevice(const char *, const char *, int);
193 void AlsaInitPCMDevice(void);
194 void AlsaInitMixer(void);
195 void AlsaSetVolume(int);
196 void AlsaInit(void);
197 void AlsaExit(void);
198 void FlushAlsaBuffers(void);
199 void DropAlsaBuffers(void);
200 void FlushAlsaBuffersInternal(bool);
201 bool CyclicCall(void);
202 void ProcessEvents(void);
203 void HandleError(int);
204
206 int64_t PtsToMs(int64_t pts) { return pts * av_q2d(*m_pTimebase) * 1000; }
209 int FramesToMs(int frames) { return (int64_t)frames * 1000 / m_hwSampleRate; }
210 double FramesToMsDouble(int frames) { return (double)frames * 1000 / m_hwSampleRate; }
211};
212
215#endif
Event Receiver.
Definition event.h:85
Fill Level Low Pass Filter.
Definition filllevel.h:23
PID Controller.
Audio Interface.
Definition audio.h:46
int m_alsaBufferSizeFrames
alsa buffer size in frames
Definition audio.h:101
bool m_appendAES
flag ato utomatic append AES
Definition audio.h:125
cSoftHdRingbuffer m_pRingbuffer
sample ring buffer
Definition audio.h:181
int m_pitchAdjustFrameCounter
counter for pitch adjustment frames
Definition audio.h:114
double FramesToMsDouble(int frames)
Definition audio.h:210
int64_t GetInputPtsMs(void)
Definition audio.h:66
int m_compressionMaxFactor
max. compression factor
Definition audio.h:152
cSoftHdDevice * m_pDevice
pointer to device
Definition audio.h:95
const char * m_pPCMDevice
PCM device name.
Definition audio.h:123
int GetPassthrough(void) const
Definition audio.h:64
int m_volume
current volume (0 .. 1000)
Definition audio.h:158
std::mutex m_pauseMutex
mutex for a safe thread pausing
Definition audio.h:111
AVFilterContext * m_pBuffersinkCtx
Definition audio.h:174
cPidController m_pidController
PID controller for clock drift compensation with tuning values coming from educated guesses.
Definition audio.h:99
AVFilterContext * m_pBuffersrcCtx
Definition audio.h:173
AVFilterGraph * m_pFilterGraph
Definition audio.h:172
int m_passthrough
passthrough mask
Definition audio.h:122
const int m_bytesPerSample
number of bytes per sample
Definition audio.h:106
const char * m_pMixerChannel
mixer channel name
Definition audio.h:167
unsigned int m_hwSampleRate
hardware sample rate in Hz
Definition audio.h:107
int64_t PtsToMs(int64_t pts)
Definition audio.h:206
cBufferFillLevelLowPassFilter m_fillLevel
low pass filter for the buffer fill level
Definition audio.h:98
IEventReceiver * m_pEventReceiver
pointer to event receiver
Definition audio.h:97
int GetAvResyncBorderMs(void)
Definition audio.h:68
int MsToFrames(int milliseconds)
Definition audio.h:208
std::vector< Event > m_eventQueue
event queue for incoming events
Definition audio.h:112
AVRational * m_pTimebase
pointer to AVCodecContext pkts_timebase
Definition audio.h:109
void SetAutoAES(bool appendAes)
Definition audio.h:78
static constexpr int AUDIO_MIN_BUFFER_FREE
Minimum free space in audio buffer 8 packets for 8 channels.
Definition audio.h:92
bool m_compression
flag to use compress volume
Definition audio.h:150
bool m_normalize
flag to use volume normalize
Definition audio.h:138
int m_filterChanged
filter has changed
Definition audio.h:170
snd_mixer_elem_t * m_pAlsaMixerElem
alsa mixer element
Definition audio.h:186
int64_t m_inputPts
pts clock (last pts in ringbuffer)
Definition audio.h:118
int m_normalizeFactor
current normalize factor
Definition audio.h:144
cSoftHdConfig * m_pConfig
pointer to config
Definition audio.h:96
std::atomic< double > m_pitchPpm
pitch adjustment in ppm. Positive values are faster
Definition audio.h:113
int m_amplifier
software volume amplify factor
Definition audio.h:156
bool IsPaused(void)
Definition audio.h:54
void SetSoftvol(bool softVolume)
Definition audio.h:73
static constexpr int NORMALIZE_MAX_INDEX
number of normalize average samples
Definition audio.h:93
const char * m_pPassthroughDevice
passthrough device name
Definition audio.h:124
int m_normalizeMaxFactor
max. normalize factor
Definition audio.h:146
bool m_alsaUseMmap
use mmap
Definition audio.h:188
int m_compressionFactor
current compression factor
Definition audio.h:151
int64_t MsToPts(int64_t ptsMs)
Definition audio.h:207
int m_spdifBurstSize
size of the current spdif burst
Definition audio.h:126
const int m_normalizeMinFactor
min. normalize factor
Definition audio.h:145
const int m_normalizeSamples
number of normalize samples
Definition audio.h:139
int m_filterReady
filter is ready
Definition audio.h:171
int m_normalizeReady
index normalize counter
Definition audio.h:143
const char * m_pMixerDevice
mixer device name (not used)
Definition audio.h:166
bool HasInputPts(void)
Definition audio.h:65
uint32_t m_normalizeAverage[NORMALIZE_MAX_INDEX]
average of n last normalize sample blocks
Definition audio.h:141
unsigned int m_hwNumChannels
number of hardware channels
Definition audio.h:108
bool m_initialized
class initialized
Definition audio.h:105
int FramesToMs(int frames)
Definition audio.h:209
int m_stereoDescent
volume descent for stereo
Definition audio.h:157
std::mutex m_mutex
mutex for thread safety
Definition audio.h:110
static constexpr int AV_SYNC_BORDER_MS
absolute max a/v difference in ms which should trigger a resync
Definition audio.h:94
int m_alsaRatio
internal -> mixer ratio * 1000
Definition audio.h:187
int m_packetCounter
packet counter for logging
Definition audio.h:102
void SetDownmix(int downMix)
Definition audio.h:72
static constexpr unsigned RINGBUFFER_SIZE
default ring buffer size ~2s 8ch 16bit (3 * 5 * 7 * 8)
Definition audio.h:180
snd_pcm_t * m_pAlsaPCMHandle
alsa pcm handle
Definition audio.h:184
int m_downmix
set stereo downmix
Definition audio.h:116
int m_useEqualizer
flag to use equalizer
Definition audio.h:162
float m_equalizerBand[18]
equalizer band
Definition audio.h:163
snd_mixer_t * m_pAlsaMixer
alsa mixer handle
Definition audio.h:185
snd_pcm_sframes_t m_hwBaseline
saves the hw delay (pause bursts) once a real audio frame to correctly do the AV-Sync
Definition audio.h:128
int m_normalizeIndex
index into normalize average table
Definition audio.h:142
std::chrono::steady_clock::time_point m_lastPidInvocation
last time the PID controller was invoked
Definition audio.h:100
int m_normalizeCounter
normalize sample counter
Definition audio.h:140
std::atomic< bool > m_paused
audio is paused
Definition audio.h:119
bool IsBufferFull(void)
Definition audio.h:57
bool m_firstRealAudioReceived
false, as long as no real audio was sent - used to trigger the baseline set
Definition audio.h:129
std::vector< uint16_t > m_pauseBurst
holds the burst data itself
Definition audio.h:127
void SetTimebase(AVRational *timebase)
Definition audio.h:79
bool m_softVolume
flag to use soft volume
Definition audio.h:121
Plugin Configuration.
Definition config.h:29
Output Device Implementation.
Ringbuffer (FIFO) Implementation.
Definition ringbuffer.h:38
State Machine and Event Header File.
Low-pass Filter for Audio Buffer Fill Level Measurement Header File.
void LazyInit(void)
Initialize audio output module (alsa)
Definition audio.cpp:1075
char * OpenAlsaDevice(const char *, int)
Opens an alsa device.
Definition audio.cpp:1440
bool SendPause(void)
Write pause to passthrough device.
Definition audio.cpp:1358
char * FindAlsaDevice(const char *, const char *, int)
Find alsa device giving some search hints.
Definition audio.cpp:1492
void ResetHwDelayBaseline(void)
Reset the hw delay baseline.
Definition audio.cpp:1412
virtual void Action(void)
Audio thread loop, started with Start().
Definition audio.cpp:1199
void Filter(AVFrame *, AVCodecContext *)
Send audio frame to filter and enqueue it.
Definition audio.cpp:818
int AlsaSetup(int channels, int sample_rate, int passthrough)
Setup alsa audio for requested format.
Definition audio.cpp:1683
int Setup(AVCodecContext *, int, int, int)
Alsa setup wrapper.
Definition audio.cpp:729
void Enqueue(uint16_t *, int, AVFrame *)
Send audio data to ringbuffer.
Definition audio.cpp:677
void SetPassthroughMask(int)
Set audio passthrough mask.
Definition audio.cpp:1056
void SetHwDelayBaseline(void)
Set the hw delay baseline.
Definition audio.cpp:1392
void SetStereoDescent(int)
Set stereo loudness descent.
Definition audio.cpp:1045
int64_t GetHardwareOutputPtsMs(void)
Get the hardware output PTS in milliseconds.
Definition audio.cpp:923
int64_t GetHardwareOutputPtsTimebaseUnits(void)
Get the hardware output PTS in timebase units.
Definition audio.cpp:964
void EnqueueSpdif(uint16_t *, int, AVFrame *)
Enqueue prepared spdif bursts in audio output queue.
Definition audio.cpp:655
void SetVolume(int)
Set mixer volume (0-1000)
Definition audio.cpp:978
void HandleError(int)
Handle an alsa error.
Definition audio.cpp:1111
void FlushAlsaBuffersInternal(bool)
Flush alsa buffers internally.
Definition audio.cpp:1144
void ProcessEvents(void)
Process queued events and forward them to event receiver.
Definition audio.cpp:1424
bool SendAudio(int)
Write regular audio data from the ringbuffer to the hardware.
Definition audio.cpp:1298
void DropSamplesOlderThanPtsMs(int64_t)
Drop samples older than the given PTS.
Definition audio.cpp:576
int64_t GetOutputPtsMs(void)
Get the output PTS of the ringbuffer.
Definition audio.cpp:902
AVFrame * FilterGetFrame(void)
Get frame from filter sink.
Definition audio.cpp:752
size_t FreeBytes(void)
Get free bytes in ring buffer.
void ClockDriftCompensation(void)
Calculate clock drift compensation.
Definition audio.cpp:1837
void AlsaExit(void)
Cleanup the alsa audio output module.
Definition audio.cpp:1815
void SetCompression(bool, int)
Set volume compression parameters.
Definition audio.cpp:1027
void Stop(void)
Stop the thread.
Definition audio.cpp:1217
void BuildPauseBurst(void)
Build a pause spdif burst with the size of the last recognized normal spdif audio.
Definition audio.cpp:634
void AlsaInit(void)
Initialize the alsa audio output module.
Definition audio.cpp:1799
void Compress(uint16_t *, int)
Compress audio samples.
Definition audio.cpp:233
void AlsaSetVolume(int)
Set alsa mixer volume (0-1000)
Definition audio.cpp:1661
int64_t GetOutputPtsMsInternal(void)
Definition audio.cpp:909
void Exit(void)
Cleanup audio output module (alsa)
Definition audio.cpp:1090
int GetUsedBytes(void)
Get used bytes in audio ringbuffer.
Definition audio.cpp:884
void SetPaused(bool)
Set audio playback pause state.
Definition audio.cpp:1001
void AlsaInitMixer(void)
Initialize alsa mixer.
Definition audio.cpp:1607
int64_t GetHardwareOutputDelayMs(void)
Get the hardware delay in milliseconds.
Definition audio.cpp:945
void Normalize(uint16_t *, int)
Normalize audio samples.
Definition audio.cpp:152
void SetEq(int[18], int)
Set equalizer bands.
Definition audio.cpp:319
void DropAlsaBuffers(void)
Drop alsa buffers.
Definition audio.cpp:1134
bool CyclicCall(void)
Cyclic audio playback call.
Definition audio.cpp:1237
void AlsaInitPCMDevice(void)
Search for an alsa pcm device and open it.
Definition audio.cpp:1528
void EnqueueFrame(AVFrame *)
Place samples in audio output queue.
Definition audio.cpp:608
void SoftAmplify(int16_t *, int)
Amplify the samples in software.
Definition audio.cpp:290
void FlushAlsaBuffers(void)
Flush alsa buffers.
Definition audio.cpp:1126
void SetNormalize(bool, int)
Set normalize volume parameters.
Definition audio.cpp:1015
int CheckForFilterReady(AVCodecContext *)
Check if the filter has changed and is ready, init the filter if needed.
Definition audio.cpp:785
int InitFilter(AVCodecContext *)
Init audio filters.
Definition audio.cpp:401
void FlushBuffers(void)
Flush audio buffers.
Definition audio.cpp:861
#define AV_NOPTS_VALUE
Definition misc.h:74
PID (proportional, integral, derivative) Controller Header File.
Audio Ringbuffer Header File.