#ifndef qb_hpp
#define qb_hpp
#include <memory>
#include <string>
#include <vector>
#include "AudioFile/AudioFile.h"
namespace qb {
enum class node_type {
audio,
midi,
osc,
};
struct load_state {
enum stage_kind {
loading,
loaded,
failed,
};
stage_kind stage;
std::string message;
load_state(stage_kind s) : stage(s), message("") {};
load_state(stage_kind s, const std::string &m) : stage(s), message(m) {};
};
struct context;
struct node {
node(const node&) = delete;
node(node&&) = delete;
node &operator=(const node&) = delete;
node &operator=(node&&) = delete;
virtual ~node() = default;
const std::string &name() const { return _name; }
node_type type() const { return _type; }
const context* ctx() const { return _c; }
virtual int minframe() const = 0;
virtual int maxframe() const = 0;
protected:
node(const context *c, const std::string &n, node_type t);
const context *_c;
private:
std::string _name;
node_type _type;
};
using node_ptr = std::shared_ptr<node>;
using audio_file = AudioFile<float>;
using audio_file_ptr = std::shared_ptr<audio_file>;
using audio_file_cptr = std::shared_ptr<const audio_file>;
struct audio_node : public node {
audio_node(const context *c, const std::string &path);
~audio_node() override;
const std::string &path() const { return _path; }
load_state loadstate() const { return _loadstate; }
const audio_file_cptr data() const { return _data; }
const std::vector<float>& rendered() const;
// number of render samples per frame
double rsamplerate() const;
// samples packed the way saudio likes them
const std::vector<float>& packed() const;
int minframe() const override;
int maxframe() const override;
private:
void load_async();
std::vector<float> render_samples(double rsamplerate);
const std::string _path;
audio_file_ptr _data;
std::vector<float> _rhi;
std::vector<float> _rlo;
std::vector<float> _packed;
load_state _loadstate;
};
struct context
{
context();
~context() = default;
context(const context &) = delete;
context(context &&) = delete;
context &operator=(const context &) = delete;
context &operator=(context &&) = delete;
int framerate() const { return _framerate; }
void framerate(int fr) { _framerate = fr; }
void frame(int width, int height);
void shutdown();
int frame2pixel(double frame);
bool playing = false;
double playhead = 0;
double visrad = 240;
int width = 0;
int height = 0;
// for ui animations
uint32_t spinstep = 0;
private:
void initaudio();
void pushaudio();
bool audioinit = false;
int playedframe = -1;
int64_t pushedsample = -1;
const audio_node *audiosource = nullptr;
int _framerate = 24;
std::vector<qb::node_ptr> _nodes;
};
}
#endif