looper/playback.h

101 lines
No EOL
2.7 KiB
C++

#pragma once
#include <SDL_mixer.h>
#include <thread>
#include <SDL.h>
#include <SDL_audio.h>
#include <string>
#include <atomic>
#include <mutex>
#include <SoundTouch.h>
#include <span>
#include <optional>
#include <vector>
#include <queue>
using namespace soundtouch;
using std::span;
using std::optional;
using std::vector;
using std::queue;
enum {
PlaybackSignalNone = 0,
PlaybackSignalFileChanged = 1 << 0,
PlaybackSignalSpeedChanged = 1 << 1,
PlaybackSignalTempoChanged = 1 << 2,
PlaybackSignalPitchChanged = 1 << 3,
PlaybackSignalPaused = 1 << 4,
PlaybackSignalResumed = 1 << 5,
PlaybackSignalStopped = 1 << 6,
PlaybackSignalErrorOccurred = 1 << 7,
PlaybackSignalSeeked = 1 << 8,
PlaybackSignalStarted = 1 << 9
};
class Playback {
private:
std::string filePath;
std::atomic_bool running;
std::atomic_bool file_changed;
std::atomic_bool seeking;
std::atomic_bool update;
std::atomic_bool restart;
std::atomic_bool playback_ready;
std::atomic_bool speed_changed;
std::atomic_bool tempo_changed;
std::atomic_bool pitch_changed;
std::atomic_bool pause_changed;
std::mutex flag_mutex;
std::mutex error_mutex;
std::thread thread;
double position;
double length;
bool paused;
Uint8* buf;
size_t bufsize;
Mix_CommonMixer_t general_mixer;
SDL_AudioDeviceID device;
SoundTouch *st;
SDL_AudioSpec spec;
/// @brief A fake SDL_AudioSpec used to trick SDL Mixer X into allocating a bigger buffer.
SDL_AudioSpec fakespec;
void SDLCallbackInner(Uint8 *stream, int len);
static void SDLCallback(void *userdata, Uint8 *stream, int len);
Mix_Music *Load(const char* file);
void Unload(Mix_Music* music);
void ThreadFunc();
void UpdateST();
double GetMaxSeconds();
queue<std::string> errors;
std::mutex current_file_mutex;
std::optional<std::string> current_file;
uint16_t signals_occurred = PlaybackSignalNone;
std::mutex signal_mutex;
void set_signal(uint16_t signal);
float prev_pitch, prev_speed, prev_tempo;
public:
Playback();
~Playback();
std::optional<std::string> get_current_file();
double GetPosition();
double GetLength();
void Seek(double position);
void Start(std::string filePath);
bool IsPaused();
void Pause();
void Stop();
void Update();
bool IsStopped();
float volume;
float speed;
float tempo;
float pitch;
float MaxSeconds = 100.0;
float MaxSpeed = 4.0;
float MaxPitch = 4.0;
float MaxTempo = 4.0;
float MinSpeed = 0.25;
float MinPitch = 0.25;
float MinTempo = 0.25;
uint16_t handle_signals(uint16_t signal);
optional<std::string> GetError();
bool ErrorExists();
};