using namespace ARDOUR;
using namespace PBD;
using namespace Gtk;
+using namespace sigc;
using namespace Editing;
mute_button->set_active (false);
solo_button->set_active (false);
+ // add channel selection button
+ _channel_selection_button.add(*manage(new Label("c")));
+ controls_table.property_n_rows() = 3;
+ controls_table.attach(_channel_selection_button, 1, 2, 2, 3);
+ _channel_selection_button.show_all();
+
+ // add channel selector
+ controls_vbox.pack_end(_channel_selector);
+ _channel_selector.selection_changed.connect(
+ mem_fun(*midi_track()->midi_diskstream(), &MidiDiskstream::set_channel_mask));
+ _channel_selector.show_all();
+
if (is_midi_track()) {
controls_ebox.set_name ("MidiTimeAxisViewControlsBaseUnselected");
_note_mode = midi_track()->note_mode();
#include "route_time_axis.h"
#include "canvas.h"
#include "midi_streamview.h"
+#include "midi_channel_selector.h"
namespace ARDOUR {
class Session;
ARDOUR::NoteMode _note_mode;
Gtk::RadioMenuItem* _note_mode_item;
Gtk::RadioMenuItem* _percussion_mode_item;
+ Gtk::ToggleButton _channel_selection_button;
+ MidiMultipleChannelSelector _channel_selector;
};
#endif /* __ardour_midi_time_axis_h__ */
int set_destructive (bool yn); // doom!
void set_note_mode (NoteMode m);
+
+ void set_channel_mask(uint16_t channel_mask) {
+ _playback_buf->set_channel_mask(channel_mask);
+ _capture_buf->set_channel_mask(channel_mask);
+ }
+
+ uint16_t get_channel_mask() {
+ uint16_t playback_mask = _playback_buf->get_channel_mask();
+ uint16_t capture_mask = _capture_buf->get_channel_mask();
+ assert(playback_mask == capture_mask);
+ return playback_mask;
+ }
protected:
friend class Session;
/** @param size Size in bytes.
*/
MidiRingBuffer(size_t size)
- : MidiRingBufferBase<Byte>(size)
+ : MidiRingBufferBase<Byte>(size), _channel_mask(0xFFFF)
{}
size_t write(double time, size_t size, const Byte* buf);
bool read_contents(size_t size, Byte* buf);
size_t read(MidiBuffer& dst, nframes_t start, nframes_t end, nframes_t offset=0);
+
+ void set_channel_mask(uint16_t channel_mask) { _channel_mask = channel_mask; }
+ uint16_t get_channel_mask() { return _channel_mask; }
+
+protected:
+ inline bool is_channel_event(Byte event_type_byte) {
+ // mask out channel information
+ event_type_byte &= 0xF0;
+ // midi channel events range from 0x80 to 0xE0
+ return (0x80 <= event_type_byte) && (event_type_byte <= 0xE0);
+ }
+
+private:
+ uint16_t _channel_mask;
};
buf[0], buf[1], buf[2], time);
assert(size > 0);
+
+ // filter events for channels
+ if(is_channel_event(buf[0])) {
+ Byte channel_nr = buf[0] & 0x0F;
+ if( !(_channel_mask & (1L << channel_nr)) ) {
+ return 0;
+ }
+ }
if (write_space() < (sizeof(double) + sizeof(size_t) + size)) {
return 0;
MidiRingBufferBase<Byte>::write(size, buf);
return size;
}
+
}
size_t count = 0;
- //printf("MRB - read %u .. %u + %u\n", start, end, offset);
+ printf("MRB - read %u .. %u + %u\n", start, end, offset);
while (read_space() > sizeof(double) + sizeof(size_t)) {
if (ev.time() > end)
break;
-
+
bool success = MidiRingBufferBase<Byte>::full_read(sizeof(double), (Byte*)&ev.time());
if (success)
success = MidiRingBufferBase<Byte>::full_read(sizeof(size_t), (Byte*)&ev.size());
-
+
if (!success) {
std::cerr << "MRB: READ ERROR (time/size)" << std::endl;
continue;
}
+
+ Byte first_event_byte;
+ if(success)
+ success = full_peek(sizeof(Byte), &first_event_byte);
+
+ // could this ever happen???
+ if (!success) {
+ std::cerr << "MRB: PEEK ERROR (first event byte)" << std::endl;
+ continue;
+ }
+
+ // filter events for channels
+ if(is_channel_event(first_event_byte)) {
+ Byte channel_nr = first_event_byte & 0x0F;
+ if( !(_channel_mask & (1L << channel_nr)) ) {
+ return 0;
+ }
+ }
if (ev.time() >= start) {
ev.time() -= start;
if (success) {
++count;
- //printf("MRB - read event at time %lf\n", ev.time);
+ printf("MRB - read event at time %lf\n", ev.time());
} else {
std::cerr << "MRB: READ ERROR (data)" << std::endl;
}
const DataType& data_type() const { return _type; }
+ /**
+ * Thats how the region parameters play together:
+ * <PRE>
+ * |------------------------------------------------------------------- track
+ * |..........[------------------].....| region
+ * |-----------------------------| _position
+ * |------------------| _length
+ * |----------| _start
+ * </PRE>
+ */
nframes_t position () const { return _position; }
nframes_t start () const { return _start; }
nframes_t length() const { return _length; }
static const uint16_t _ppqn = 19200;
- uint16_t _channel;
Glib::ustring _path;
Flag _flags;
string _take_id;
SMFSource::SMFSource (Session& s, std::string path, Flag flags)
: MidiSource (s, region_name_from_path(path, false))
- , _channel(0)
, _flags (Flag(flags | Writable)) // FIXME: this needs to be writable for now
, _allow_remove_if_empty(true)
, _fd (0)
SMFSource::SMFSource (Session& s, const XMLNode& node)
: MidiSource (s, node)
- , _channel(0)
, _flags (Flag (Writable|CanRename))
, _allow_remove_if_empty(true)
, _fd (0)