1
Fork 0
jacker/model.hpp

303 lines
7.1 KiB
C++

#pragma once
#include <map>
#include <string>
#include <list>
#include <vector>
namespace Jacker {
class Model;
//=============================================================================
#if defined(WIN32)
template<typename Key_T, typename T>
inline typename std::map<Key_T,T>::iterator extract_iterator(
std::pair< typename std::map<Key_T,T>::iterator, bool> result) {
return result.first;
}
#else
template<typename Key_T, typename T>
inline typename std::map<Key_T,T>::iterator extract_iterator(
std::pair< typename std::map<const Key_T,T>::iterator, bool> result) {
return result.first;
}
#endif
template<typename Key_T, typename T>
inline typename std::multimap<Key_T,T>::iterator extract_iterator(
typename std::multimap<Key_T,T>::iterator result) {
return result;
}
template<typename Map_T>
class EventCollection
: public Map_T {
public:
typedef Map_T map;
typedef typename map::key_type Key;
typedef typename map::mapped_type Event;
typedef EventCollection<Map_T> BaseClass;
typedef std::list<Event> EventList;
typedef std::list<typename Map_T::iterator> IterList;
typename map::iterator add_event(const Event &event) {
return extract_iterator<typename map::key_type, Event>(
insert(typename map::value_type(event.key(),event)));
}
};
//=============================================================================
#define NOTE(N,OCTAVE) ((12*(OCTAVE))+(Note ## N))
enum {
NoteC = 0,
NoteCs = 1,
NoteD = 2,
NoteDs = 3,
NoteE = 4,
NoteF = 5,
NoteFs = 6,
NoteG = 7,
NoteGs = 8,
NoteA = 9,
NoteAs = 10,
NoteB = 11,
};
enum {
ValueNone = -1,
NoteOff = 255,
};
enum {
ParamNote = 0,
ParamVolume,
ParamCommand,
ParamValue,
ParamCCIndex,
ParamCCValue,
ParamCount,
};
enum {
MaxTracks = 32,
MaxChannels = 256,
MaxPorts = 16,
};
//=============================================================================
int sprint_note(char *buffer, int value);
//=============================================================================
// describes a parameter
struct Param {
int min_value;
int max_value;
int def_value;
int no_value;
Param();
Param(int min_value, int max_value, int default_value, int no_value);
};
//=============================================================================
struct PatternEvent {
// time index
int frame;
// index of channel
int channel;
// index of parameter
int param;
// value of parameter
int value;
PatternEvent();
PatternEvent(int frame, int channel, int param, int value);
bool is_valid() const;
int key() const;
void sanitize_value();
};
//=============================================================================
class Pattern : public EventCollection< std::multimap<int,PatternEvent> > {
friend class Model;
public:
struct Row : std::vector<Event *> {
typedef std::vector<Event *> vector;
void resize(int channel_count);
Event *get_event(int channel, int param) const;
void set_event(Event &event);
int get_value(int channel, int param) const;
};
// name of pattern (non-unique)
std::string name;
// usage count of pattern
int refcount;
iterator add_event(const Event &event);
iterator add_event(int frame, int channel, int param, int value);
void set_length(int length);
int get_length() const;
void set_channel_count(int count);
int get_channel_count() const;
void collect_events(int frame, iterator &iter, Row &row);
iterator get_event(int frame, int channel, int param);
void update_keys();
void copy_from(const Pattern &pattern);
void move_frames(int row, int step, int channel);
Pattern();
protected:
// length in frames
int length;
// number of channels
int channel_count;
};
//=============================================================================
struct SongEvent {
int frame;
int track;
bool mute;
Pattern *pattern;
SongEvent();
SongEvent(int frame, int track, Pattern &pattern);
int key() const;
int get_last_frame() const;
int get_end() const;
};
//=============================================================================
class Song : public EventCollection< std::multimap<int,SongEvent> > {
friend class Model;
public:
iterator add_event(const Event &event);
iterator add_event(int frame, int track, Pattern &pattern);
iterator get_event(int frame);
void erase(iterator iter);
void find_events(int frame, IterList &events);
void update_keys();
protected:
Song();
};
//=============================================================================
struct Measure {
int bar;
int beat;
int subframe;
Measure();
void set_frame(Model &model, int frame);
int get_frame(Model &model) const;
std::string get_string() const;
};
//=============================================================================
class Loop {
public:
Loop();
void set(int begin, int end);
void set_begin(int begin);
void set_end(int end);
void get(int &begin, int &end) const;
int get_begin() const;
int get_end() const;
protected:
int begin;
int end;
};
//=============================================================================
class Track {
public:
std::string name;
int midi_port;
int midi_channel;
bool mute;
Track();
};
//=============================================================================
typedef std::list<Pattern*> PatternList;
typedef std::vector<Track> TrackArray;
class Model {
public:
// list of all patterns
PatternList patterns;
// contains all song events
Song song;
// track infos
TrackArray tracks;
// describes the loop
Loop loop;
// tells if the loop is enabled
bool enable_loop;
// end cue in frames
int end_cue;
// how many frames are in one beat
int frames_per_beat;
// how many beats are in one bar
int beats_per_bar;
// how many beats are in one minute
int beats_per_minute;
// what port to use for the midi control
int midi_control_port;
// what channel to use for the midi control
int midi_control_channel;
void reset();
Model();
Pattern &new_pattern(const Pattern *template_pattern=NULL);
int get_track_count() const;
int get_frames_per_bar() const;
void update_pattern_refcount();
void delete_unused_patterns();
std::string get_param_name(int param) const;
std::string format_param_value(int param, int value) const;
};
//=============================================================================
} // namespace Jacker