2 Copyright (C) 2006 Paul Davis
4 This program is free software; you can redistribute it and/or modify it
5 under the terms of the GNU General Public License as published by the Free
6 Software Foundation; either version 2 of the License, or (at your option)
9 This program is distributed in the hope that it will be useful, but WITHOUT
10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 You should have received a copy of the GNU General Public License along
15 with this program; if not, write to the Free Software Foundation, Inc.,
16 675 Mass Ave, Cambridge, MA 02139, USA.
21 using std::cerr; using std::endl;
23 #include <ardour/buffer.h>
29 Buffer::create(DataType type, size_t capacity)
31 if (type == DataType::AUDIO)
32 return new AudioBuffer(capacity);
33 else if (type == DataType::MIDI)
34 return new MidiBuffer(capacity);
40 AudioBuffer::AudioBuffer(size_t capacity)
41 : Buffer(DataType::AUDIO, capacity)
44 _size = capacity; // For audio buffers, size = capacity (always)
46 #ifdef NO_POSIX_MEMALIGN
47 _data = (Sample *) malloc(sizeof(Sample) * capacity);
49 posix_memalign((void**)&_data, 16, sizeof(Sample) * capacity);
59 AudioBuffer::~AudioBuffer()
65 // FIXME: mirroring for MIDI buffers?
66 MidiBuffer::MidiBuffer(size_t capacity)
67 : Buffer(DataType::MIDI, capacity)
76 #ifdef NO_POSIX_MEMALIGN
77 _events = (MidiEvent *) malloc(sizeof(MidiEvent) * capacity);
78 _data = (RawMidi *) malloc(sizeof(RawMidi) * capacity * MAX_EVENT_SIZE);
80 posix_memalign((void**)&_events, 16, sizeof(MidiEvent) * capacity);
81 posix_memalign((void**)&_data, 16, sizeof(RawMidi) * capacity * MAX_EVENT_SIZE);
88 MidiBuffer::~MidiBuffer()
95 /** Read events from @a src starting at time @a offset into the START of this buffer, for
96 * time direction @a nframes. Relative time, where 0 = start of buffer.
98 * Note that offset and nframes refer to sample time, NOT buffer offsets or event counts.
101 MidiBuffer::read_from(const Buffer& src, jack_nframes_t nframes, jack_nframes_t offset)
103 assert(src.type() == DataType::MIDI);
104 const MidiBuffer& msrc = (MidiBuffer&)src;
106 assert(_capacity >= src.size());
111 // FIXME: This is embarrassingly slow. branch branch branch
112 for (size_t i=0; i < src.size(); ++i) {
113 const MidiEvent& ev = msrc[i];
114 if (ev.time >= offset && ev.time < offset+nframes) {
121 /** Push an event into the buffer.
123 * Note that the raw MIDI pointed to by ev will be COPIED and unmodified.
124 * That is, the caller still owns it, if it needs freeing it's Not My Problem(TM).
126 * @return false if operation failed (not enough room)
129 MidiBuffer::push_back(const MidiEvent& ev)
131 if (_size == _capacity)
134 RawMidi* const write_loc = _data + (_size * MAX_EVENT_SIZE);
136 memcpy(write_loc, ev.buffer, ev.size);
138 _events[_size].buffer = write_loc;
141 //cerr << "MidiBuffer: pushed, size = " << _size << endl;
148 MidiBuffer::silence(jack_nframes_t dur, jack_nframes_t offset)
150 // FIXME use parameters
152 //assert(dur == _capacity);
154 memset(_events, 0, sizeof(MidiEvent) * _capacity);
155 memset(_data, 0, sizeof(RawMidi) * _capacity * MAX_EVENT_SIZE);
160 } // namespace ARDOUR