Ardour  9.0-pre0-582-g084a23a80d
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  void begin_write();
92  void append_event_delta(uint32_t delta_t, uint32_t size, const uint8_t* buf, event_id_t note_id);
93  void end_write(std::string const &);
94 
95  void flush() {};
96  void set_length (Temporal::Beats const &);
97 
98  double round_to_file_precision (double val) const;
99 
100  int smf_format () const;
101 
103 
104  int num_channels () const { return _num_channels; }
105  typedef std::bitset<16> UsedChannels;
106  UsedChannels const& used_channels () const { return _used_channels; }
107  void set_used_channels (UsedChannels used) { _used_channels = used; }
108  uint64_t n_note_on_events () const { return _n_note_on_events; }
109  bool has_pgm_change () const { return _has_pgm_change; }
110 
111  void track_names (std::vector<std::string>&) const;
112  void instrument_names (std::vector<std::string>&) const;
113 
114  int num_tempos () const;
115 
116  /* This is exactly modelled on smf_tempo_t */
117  struct Tempo {
118  size_t time_pulses;
124 
125  Tempo ()
126  : time_pulses (0)
127  , microseconds_per_quarter_note (-1)
128  , numerator (-1)
129  , denominator (-1)
130  , clocks_per_click (-1)
131  , notes_per_note (-1) {}
133 
134  double tempo() const {
135  return 60.0 * (1000000.0 / (double) microseconds_per_quarter_note);
136  }
137  };
138 
139  Tempo* nth_tempo (size_t n) const;
140 
141  struct MarkerAt {
142  std::string text;
143  size_t time_pulses; /* type matches libsmf smf_event_struct.time_pulses */
144 
145  MarkerAt (std::string const & txt, size_t tp) : text (txt), time_pulses (tp) {}
146  };
147 
148  typedef std::vector<MarkerAt> Markers;
149  Markers const & markers() const { return _markers; }
150  void load_markers ();
151 
152  std::shared_ptr<Temporal::TempoMap> tempo_map (bool& provided) const;
153 
154  private:
157  bool _empty;
158 
159  mutable Glib::Threads::Mutex _smf_lock;
160 
161  mutable Markers _markers;
162 
163  protected:
168 };
169 
170 }; /* namespace Evoral */
171 
172 #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:108
void begin_write()
void end_write(std::string const &)
smf_t * _smf
Definition: SMF.h:155
uint16_t num_tracks() const
void append_event_delta(uint32_t delta_t, uint32_t size, const uint8_t *buf, event_id_t note_id)
double round_to_file_precision(double val) const
bool is_empty() const
Definition: SMF.h:89
std::bitset< 16 > UsedChannels
Definition: SMF.h:105
int _num_channels
Definition: SMF.h:166
smf_track_t * _smf_track
Definition: SMF.h:156
Glib::Threads::Mutex _smf_lock
Definition: SMF.h:159
int num_tempos() const
bool _has_pgm_change
Definition: SMF.h:165
void instrument_names(std::vector< std::string > &) const
UsedChannels const & used_channels() const
Definition: SMF.h:106
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:107
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:167
int num_channels() const
Definition: SMF.h:104
bool _empty
true iff file contains(non-empty) events
Definition: SMF.h:157
std::shared_ptr< Temporal::TempoMap > tempo_map(bool &provided) const
static bool test(const std::string &path)
int smf_format() const
int seek_to_track(int track)
uint64_t _n_note_on_events
Definition: SMF.h:164
void seek_to_start() const
Markers const & markers() const
Definition: SMF.h:149
int create(const std::string &path, int track=1, uint16_t ppqn=19200)
Temporal::Beats file_duration() const
Markers _markers
Definition: SMF.h:161
std::vector< MarkerAt > Markers
Definition: SMF.h:148
bool has_pgm_change() const
Definition: SMF.h:109
void flush()
Definition: SMF.h:95
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:86
int32_t event_id_t
MarkerAt(std::string const &txt, size_t tp)
Definition: SMF.h:145
size_t time_pulses
Definition: SMF.h:143
std::string text
Definition: SMF.h:142
int microseconds_per_quarter_note
Definition: SMF.h:119
int clocks_per_click
Definition: SMF.h:122
size_t time_pulses
Definition: SMF.h:118
Tempo(smf_tempo_t *)
int denominator
Definition: SMF.h:121
double tempo() const
Definition: SMF.h:134
int notes_per_note
Definition: SMF.h:123
static Temporal::Beats max()
Definition: beats.h:300