samplebrain/brain/src/brain.h

127 lines
3.9 KiB
C++

// Copyright (C) 2022 Then Try This
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include <list>
#include <vector>
#include <string>
#include "spiralcore/types.h"
#include "spiralcore/sample.h"
#include "block_source.h"
#include "block.h"
#include "search_params.h"
#include "window.h"
#ifndef BRAIN
#define BRAIN
namespace spiralcore {
class brain : public block_source {
public:
brain();
enum stereo_mode { MIX, LEFT, RIGHT };
// rewrites whole brain
void init(u32 block_size, u32 overlap, window::type t, bool ditchpcm=false);
void clear();
// load, chop up and add to brain
// todo: add tags
void load_sound(std::string filename, stereo_mode mode);
void delete_sound(std::string filename);
void clear_sounds() { m_samples.clear(); }
// turns on/off a sound in realtime without reprocessing
void activate_sound(std::string filename, bool active);
const sample &get_block_pcm(u32 index) const;
const sample &get_block_n_pcm(u32 index) const;
virtual const block &get_block(u32 index) const;
virtual u32 get_num_blocks() const { return m_blocks.size(); }
void set_usage_falloff(float s) { m_usage_falloff=s; }
float get_usage_falloff() { return m_usage_falloff; }
// basic search
u32 search(const block &target, const search_params &params);
u32 rev_search(const block &target, const search_params &params);
// synaptic search
double calc_average_diff(search_params &params);
void build_synapses_thresh(search_params &params, double threshold);
void build_synapses_fixed(search_params &params);
u32 search_synapses(const block &target, search_params &params);
double get_current_error() { return m_current_error; }
// randomise the synaptic pointer
void jiggle();
static bool unit_test();
class sound {
public:
sound(const std::string &name, const sample &sample) :
m_filename(name), m_sample(sample), m_num_blocks(0),
m_enabled(true), m_start(0), m_end(0) {}
sound() {}; // needed for streaming
std::string m_filename;
sample m_sample;
// filled in during chop_and_add
u32 m_num_blocks;
bool m_enabled;
// we store the blocks separately in a flat list, so we can
// directly index them, but we need to filter them by source
// sound - so we need to be able to turn large contiguous sets
// of them on and off (without a big impact on the processing
// time)
u32 m_start,m_end;
};
const std::list<sound> &get_samples() { return m_samples; }
private:
void chop_and_add(sound &s, u32 count, bool ditchpcm=false);
void deplete_usage();
u32 stickify(const block &target, u32 closest_index, f32 dist, const search_params &params);
void recompute_sample_sections();
// checks sample sections
bool is_block_active(u32 index);
vector<block> m_blocks;
std::list<sound> m_samples;
vector<string> m_active_sounds;
window m_window;
u32 m_current_block_index;
double m_current_error;
double m_average_error;
float m_usage_falloff;
friend ios &operator||(ios &s, brain &b);
friend ios &operator||(ios &s, sound &b);
};
ios &operator||(ios &s, brain::sound &b);
ios &operator||(ios &s, brain &b);
}
#endif