Ardour  9.0-rc2-38-g267efab6e8
SMF.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2008-2014 David Robillard <d@drobilla.net>
3  * Copyright (C) 2009-2017 Paul Davis <paul@linuxaudiosystems.com>
4  * Copyright (C) 2009 Hans Baier <hansfbaier@googlemail.com>
5  * Copyright (C) 2014-2016 Robin Gareus <robin@gareus.org>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License along
18  * with this program; if not, write to the Free Software Foundation, Inc.,
19  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20  */
21 
22 #ifndef EVORAL_SMF_HPP
23 #define EVORAL_SMF_HPP
24 
25 #include <glibmm/threads.h>
26 
27 #include <memory>
28 #include <set>
29 
30 #include "temporal/beats.h"
31 
32 #include "evoral/visibility.h"
33 #include "evoral/types.h"
34 
35 struct smf_struct;
36 struct smf_track_struct;
37 struct smf_tempo_struct;
38 typedef smf_struct smf_t;
41 
42 namespace Temporal {
43  class TempoMap;
44 }
45 
46 namespace Evoral {
47 
60 public:
61  class FileError : public std::exception {
62  public:
63  FileError (std::string const & n) : _file_name (n) {}
64  ~FileError () throw () {}
65  const char* what() const throw() { return "Unknown SMF error"; }
66  std::string file_name () const { return _file_name; }
67  private:
68  std::string _file_name;
69  };
70 
71  SMF();
72  virtual ~SMF();
73 
75 
76  static bool test(const std::string& path);
77  int open (const std::string& path, int track = 1, bool scan = true);
78  // XXX 19200 = 10 * Temporal::ticks_per_beat
79  int create(const std::string& path, int track=1, uint16_t ppqn=19200);
80  void close();
81 
82  void seek_to_start() const;
83  int seek_to_track(int track);
84 
85  int read_event(uint32_t* delta_t, uint32_t* size, uint8_t** buf, event_id_t* note_id) const;
86 
87  uint16_t num_tracks() const;
88  uint16_t ppqn() const;
89  bool is_empty() const { return _empty; }
90 
91  static bool is_meta (uint8_t const * buf, uint32_t size);
92  static bool is_tempo_or_meter_related (uint8_t const * buf, uint32_t size);
93 
94  void begin_write();
95  int append_event_delta (uint32_t delta_t, uint32_t size, const uint8_t* buf, event_id_t note_id, bool allow_meta = false);
96  void end_write(std::string const &);
97 
98  void flush() {};
99  void set_length (Temporal::Beats const &);
100 
101  double round_to_file_precision (double val) const;
102 
103  int smf_format () const;
104 
106  bool duration_is_explicit() const;
107 
108  int num_channels () const { return _num_channels; }
109  typedef std::bitset<16> UsedChannels;
110  UsedChannels const& used_channels () const { return _used_channels; }
111  void set_used_channels (UsedChannels used) { _used_channels = used; }
112  uint64_t n_note_on_events () const { return _n_note_on_events; }
113  bool has_pgm_change () const { return _has_pgm_change; }
114 
115  void track_names (std::vector<std::string>&) const;
116  void instrument_names (std::vector<std::string>&) const;
117 
118  int num_tempos () const;
119 
120  /* This is exactly modelled on smf_tempo_t */
121  struct Tempo {
122  size_t time_pulses;
128 
129  Tempo ()
130  : time_pulses (0)
131  , microseconds_per_quarter_note (-1)
132  , numerator (-1)
133  , denominator (-1)
134  , clocks_per_click (-1)
135  , notes_per_note (-1) {}
137 
138  double tempo() const {
139  return 60.0 * (1000000.0 / (double) microseconds_per_quarter_note);
140  }
141  };
142 
143  Tempo* nth_tempo (size_t n) const;
144 
145  struct MarkerAt {
146  std::string text;
147  size_t time_pulses; /* type matches libsmf smf_event_struct.time_pulses */
148 
149  MarkerAt (std::string const & txt, size_t tp) : text (txt), time_pulses (tp) {}
150  };
151 
152  typedef std::vector<MarkerAt> Markers;
153  Markers const & markers() const { return _markers; }
154  void load_markers ();
155 
156  std::shared_ptr<Temporal::TempoMap> tempo_map (bool& provided) const;
157 
158  private:
161  bool _empty;
162 
163  mutable Glib::Threads::Mutex _smf_lock;
164 
165  mutable Markers _markers;
166 
167  protected:
172 
173  void end_track ();
174 };
175 
176 }; /* namespace Evoral */
177 
178 #endif /* EVORAL_SMF_HPP */
smf_tempo_struct smf_tempo_t
Definition: SMF.h:40
smf_struct smf_t
Definition: SMF.h:37
smf_track_struct smf_track_t
Definition: SMF.h:39
std::string file_name() const
Definition: SMF.h:66
std::string _file_name
Definition: SMF.h:68
FileError(std::string const &n)
Definition: SMF.h:63
const char * what() const
Definition: SMF.h:65
uint64_t n_note_on_events() const
Definition: SMF.h:112
void begin_write()
void end_write(std::string const &)
smf_t * _smf
Definition: SMF.h:159
uint16_t num_tracks() const
double round_to_file_precision(double val) const
bool is_empty() const
Definition: SMF.h:89
static bool is_tempo_or_meter_related(uint8_t const *buf, uint32_t size)
std::bitset< 16 > UsedChannels
Definition: SMF.h:109
int _num_channels
Definition: SMF.h:170
smf_track_t * _smf_track
Definition: SMF.h:160
int append_event_delta(uint32_t delta_t, uint32_t size, const uint8_t *buf, event_id_t note_id, bool allow_meta=false)
Glib::Threads::Mutex _smf_lock
Definition: SMF.h:163
int num_tempos() const
bool _has_pgm_change
Definition: SMF.h:169
void instrument_names(std::vector< std::string > &) const
UsedChannels const & used_channels() const
Definition: SMF.h:110
int read_event(uint32_t *delta_t, uint32_t *size, uint8_t **buf, event_id_t *note_id) const
void set_used_channels(UsedChannels used)
Definition: SMF.h:111
void set_length(Temporal::Beats const &)
void load_markers()
void close()
void track_names(std::vector< std::string > &) const
UsedChannels _used_channels
Definition: SMF.h:171
int num_channels() const
Definition: SMF.h:108
bool _empty
true iff file contains(non-empty) events
Definition: SMF.h:161
std::shared_ptr< Temporal::TempoMap > tempo_map(bool &provided) const
static bool test(const std::string &path)
int smf_format() const
static bool is_meta(uint8_t const *buf, uint32_t size)
int seek_to_track(int track)
uint64_t _n_note_on_events
Definition: SMF.h:168
void seek_to_start() const
Markers const & markers() const
Definition: SMF.h:153
int create(const std::string &path, int track=1, uint16_t ppqn=19200)
Temporal::Beats file_duration() const
void end_track()
Markers _markers
Definition: SMF.h:165
std::vector< MarkerAt > Markers
Definition: SMF.h:152
bool has_pgm_change() const
Definition: SMF.h:113
void flush()
Definition: SMF.h:98
bool duration_is_explicit() const
uint16_t ppqn() const
virtual ~SMF()
Tempo * nth_tempo(size_t n) const
virtual Temporal::Beats duration() const
Definition: SMF.h:74
int open(const std::string &path, int track=1, bool scan=true)
#define LIBEVORAL_API
Definition: editor.h:87
int32_t event_id_t
MarkerAt(std::string const &txt, size_t tp)
Definition: SMF.h:149
size_t time_pulses
Definition: SMF.h:147
std::string text
Definition: SMF.h:146
int microseconds_per_quarter_note
Definition: SMF.h:123
int clocks_per_click
Definition: SMF.h:126
size_t time_pulses
Definition: SMF.h:122
Tempo(smf_tempo_t *)
int denominator
Definition: SMF.h:125
double tempo() const
Definition: SMF.h:138
int notes_per_note
Definition: SMF.h:127
static Temporal::Beats max()
Definition: beats.h:300