// 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 #include #include #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 ¶ms); u32 rev_search(const block &target, const search_params ¶ms); // synaptic search double calc_average_diff(search_params ¶ms); void build_synapses_thresh(search_params ¶ms, double threshold); void build_synapses_fixed(search_params ¶ms); u32 search_synapses(const block &target, search_params ¶ms); 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 &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 ¶ms); void recompute_sample_sections(); // checks sample sections bool is_block_active(u32 index); vector m_blocks; std::list m_samples; vector 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