2023-03-03 07:43:20 +08:00
|
|
|
#ifndef SC_AUDIO_PLAYER_H
|
|
|
|
#define SC_AUDIO_PLAYER_H
|
|
|
|
|
|
|
|
#include "common.h"
|
|
|
|
|
|
|
|
#include <stdbool.h>
|
|
|
|
#include "trait/frame_sink.h"
|
2023-03-11 17:13:00 +08:00
|
|
|
#include <util/audiobuf.h>
|
2023-03-03 07:43:20 +08:00
|
|
|
#include <util/average.h>
|
|
|
|
#include <util/thread.h>
|
|
|
|
#include <util/tick.h>
|
|
|
|
|
|
|
|
#include <libavformat/avformat.h>
|
|
|
|
#include <libswresample/swresample.h>
|
|
|
|
#include <SDL2/SDL.h>
|
|
|
|
|
|
|
|
struct sc_audio_player {
|
|
|
|
struct sc_frame_sink frame_sink;
|
|
|
|
|
|
|
|
SDL_AudioDeviceID device;
|
|
|
|
|
|
|
|
// The target buffering between the producer and the consumer. This value
|
|
|
|
// is directly use for compensation.
|
|
|
|
// Since audio capture and/or encoding on the device typically produce
|
|
|
|
// blocks of 960 samples (20ms) or 1024 samples (~21.3ms), this target
|
|
|
|
// value should be higher.
|
|
|
|
sc_tick target_buffering_delay;
|
|
|
|
uint32_t target_buffering; // in samples
|
|
|
|
|
|
|
|
// Audio buffer to communicate between the receiver and the SDL audio
|
|
|
|
// callback (protected by SDL_AudioDeviceLock())
|
2023-03-11 17:13:00 +08:00
|
|
|
struct sc_audiobuf buf;
|
2023-03-03 07:43:20 +08:00
|
|
|
|
2023-03-11 17:13:00 +08:00
|
|
|
// The previous empty space in the buffer (only used by the receiver
|
|
|
|
// thread)
|
2023-03-11 17:16:43 +08:00
|
|
|
uint32_t previous_can_write;
|
2023-03-03 07:43:20 +08:00
|
|
|
|
|
|
|
// Resampler (only used from the receiver thread)
|
|
|
|
struct SwrContext *swr_ctx;
|
|
|
|
|
|
|
|
// The sample rate is the same for input and output
|
|
|
|
unsigned sample_rate;
|
|
|
|
// The number of channels is the same for input and output
|
|
|
|
unsigned nb_channels;
|
|
|
|
// The number of bytes per sample for a single channel
|
|
|
|
unsigned out_bytes_per_sample;
|
|
|
|
|
|
|
|
// Target buffer for resampling (only used by the receiver thread)
|
|
|
|
uint8_t *swr_buf;
|
|
|
|
size_t swr_buf_alloc_size;
|
|
|
|
|
|
|
|
// Number of buffered samples (may be negative on underflow) (only used by
|
|
|
|
// the receiver thread)
|
|
|
|
struct sc_average avg_buffering;
|
|
|
|
// Count the number of samples to trigger a compensation update regularly
|
|
|
|
// (only used by the receiver thread)
|
|
|
|
uint32_t samples_since_resync;
|
|
|
|
|
2023-03-11 05:15:38 +08:00
|
|
|
// Number of silence samples inserted since the last received packet
|
|
|
|
// (protected by SDL_AudioDeviceLock())
|
|
|
|
uint32_t underflow;
|
|
|
|
|
2023-03-12 06:00:48 +08:00
|
|
|
// Current applied compensation value (only used by the receiver thread)
|
|
|
|
int compensation;
|
|
|
|
|
2023-03-03 07:43:20 +08:00
|
|
|
// Set to true the first time a sample is received (protected by
|
|
|
|
// SDL_AudioDeviceLock())
|
|
|
|
bool received;
|
|
|
|
|
|
|
|
// Set to true the first time the SDL callback is called (protected by
|
|
|
|
// SDL_AudioDeviceLock())
|
|
|
|
bool played;
|
|
|
|
|
|
|
|
const struct sc_audio_player_callbacks *cbs;
|
|
|
|
void *cbs_userdata;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct sc_audio_player_callbacks {
|
|
|
|
void (*on_ended)(struct sc_audio_player *ap, bool success, void *userdata);
|
|
|
|
};
|
|
|
|
|
|
|
|
void
|
|
|
|
sc_audio_player_init(struct sc_audio_player *ap, sc_tick target_buffering);
|
|
|
|
|
|
|
|
#endif
|