a bit more type-safety when handling audio data during clip recording
This commit is contained in:
parent
d7c424c440
commit
26fb50d1a9
@ -549,6 +549,41 @@ class LIBARDOUR_API AudioTrigger : public Trigger {
|
|||||||
uint32_t channels () const { return data.size(); }
|
uint32_t channels () const { return data.size(); }
|
||||||
|
|
||||||
RubberBand::RubberBandStretcher* alloc_stretcher () const;
|
RubberBand::RubberBandStretcher* alloc_stretcher () const;
|
||||||
|
|
||||||
|
struct AudioData : std::vector<Sample*> {
|
||||||
|
samplecnt_t length;
|
||||||
|
samplecnt_t capacity;
|
||||||
|
|
||||||
|
AudioData () : length (0), capacity (0) {}
|
||||||
|
|
||||||
|
samplecnt_t append (Sample const * src, samplecnt_t cnt, uint32_t chan) {
|
||||||
|
if (chan >= size()) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (length + cnt >= capacity) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
samplecnt_t to_copy = std::min (cnt, (capacity - length));
|
||||||
|
memcpy (at(chan), src, cnt * sizeof (Sample));
|
||||||
|
return to_copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
samplecnt_t read (Sample * dst, samplecnt_t offset, samplecnt_t cnt, uint32_t chan) {
|
||||||
|
if (chan >= size()) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (offset + cnt > length) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
samplecnt_t to_copy = std::min (cnt, (length - (offset + cnt)));
|
||||||
|
memcpy (dst, at (chan) + offset, to_copy * sizeof (Sample));
|
||||||
|
return to_copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
void alloc (samplecnt_t cnt, uint32_t nchans);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
Sample const * audio_data (size_t n) const;
|
Sample const * audio_data (size_t n) const;
|
||||||
size_t data_length() const { return data.length; }
|
size_t data_length() const { return data.length; }
|
||||||
|
|
||||||
@ -556,13 +591,7 @@ class LIBARDOUR_API AudioTrigger : public Trigger {
|
|||||||
void retrigger ();
|
void retrigger ();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Data : std::vector<Sample*> {
|
AudioData data;
|
||||||
samplecnt_t length;
|
|
||||||
|
|
||||||
Data () : length (0) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
Data data;
|
|
||||||
RubberBand::RubberBandStretcher* _stretcher;
|
RubberBand::RubberBandStretcher* _stretcher;
|
||||||
samplepos_t _start_offset;
|
samplepos_t _start_offset;
|
||||||
|
|
||||||
@ -770,7 +799,7 @@ struct SlotArmInfo {
|
|||||||
samplecnt_t capture_length;
|
samplecnt_t capture_length;
|
||||||
RTMidiBuffer* midi_buf; /* assumed large enough */
|
RTMidiBuffer* midi_buf; /* assumed large enough */
|
||||||
RTMidiBufferBeats* beats; /* will take over data allocated for midi_but */
|
RTMidiBufferBeats* beats; /* will take over data allocated for midi_but */
|
||||||
std::vector<Sample*> audio_buf; /* assumed large enough */
|
AudioTrigger::AudioData audio_buf;
|
||||||
RubberBand::RubberBandStretcher* stretcher;
|
RubberBand::RubberBandStretcher* stretcher;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1281,6 +1281,19 @@ Trigger::start_and_roll_to (samplepos_t start_pos, samplepos_t end_position, Tri
|
|||||||
|
|
||||||
/*--------------------*/
|
/*--------------------*/
|
||||||
|
|
||||||
|
void
|
||||||
|
AudioTrigger::AudioData::alloc (samplecnt_t cnt, uint32_t nchans)
|
||||||
|
{
|
||||||
|
clear ();
|
||||||
|
reserve (nchans);
|
||||||
|
for (uint32_t n = 0; n < nchans; ++n) {
|
||||||
|
push_back (new Sample[cnt]);
|
||||||
|
}
|
||||||
|
length = 0;
|
||||||
|
capacity = cnt;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
AudioTrigger::AudioTrigger (uint32_t n, TriggerBox& b)
|
AudioTrigger::AudioTrigger (uint32_t n, TriggerBox& b)
|
||||||
: Trigger (n, b)
|
: Trigger (n, b)
|
||||||
, _stretcher (0)
|
, _stretcher (0)
|
||||||
@ -1910,8 +1923,9 @@ AudioTrigger::load_data (std::shared_ptr<AudioRegion> ar)
|
|||||||
drop_data ();
|
drop_data ();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
data.alloc (data.length, nchans);
|
||||||
|
|
||||||
for (uint32_t n = 0; n < nchans; ++n) {
|
for (uint32_t n = 0; n < nchans; ++n) {
|
||||||
data.push_back (new Sample[data.length]);
|
|
||||||
ar->read (data[n], 0, data.length, n);
|
ar->read (data[n], 0, data.length, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3490,9 +3504,7 @@ TriggerBox::arm_from_another_thread (Trigger& slot, samplepos_t now, uint32_t ch
|
|||||||
ai->midi_buf->resize (1024); // XXX Config->max_slot_midi_event_size
|
ai->midi_buf->resize (1024); // XXX Config->max_slot_midi_event_size
|
||||||
ai->beats = new RTMidiBufferBeats;
|
ai->beats = new RTMidiBufferBeats;
|
||||||
} else {
|
} else {
|
||||||
for (uint32_t n = 0; n < chans; ++n) {
|
ai->audio_buf.alloc (_session.sample_rate() * 30, chans); // XXX Config->max_slot_audio_duration
|
||||||
ai->audio_buf.push_back (new Sample[_session.sample_rate() * 30]); // XXX Config->max_slot_audio_duration
|
|
||||||
}
|
|
||||||
AudioTrigger* at = dynamic_cast<AudioTrigger*> (&slot);
|
AudioTrigger* at = dynamic_cast<AudioTrigger*> (&slot);
|
||||||
assert (at);
|
assert (at);
|
||||||
ai->stretcher = at->alloc_stretcher ();
|
ai->stretcher = at->alloc_stretcher ();
|
||||||
@ -3620,7 +3632,7 @@ TriggerBox::maybe_capture (BufferSet& bufs, samplepos_t start_sample, samplepos_
|
|||||||
for (size_t n = 0; n < n_buffers; ++n) {
|
for (size_t n = 0; n < n_buffers; ++n) {
|
||||||
assert (ai->audio_buf.size() >= n);
|
assert (ai->audio_buf.size() >= n);
|
||||||
AudioBuffer& buf (bufs.get_audio (n%n_buffers));
|
AudioBuffer& buf (bufs.get_audio (n%n_buffers));
|
||||||
memcpy (ai->audio_buf[n], buf.data() + offset, sizeof (Sample) * nframes);
|
ai->audio_buf.append (buf.data() + offset, nframes, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This count is used only for audio */
|
/* This count is used only for audio */
|
||||||
@ -5583,10 +5595,7 @@ TriggerBoxThread::build_audio_source (AudioTrigger* t)
|
|||||||
|
|
||||||
size_t n = 0;
|
size_t n = 0;
|
||||||
for (auto & src : sources) {
|
for (auto & src : sources) {
|
||||||
Source::WriterLock lock (src->mutex());
|
|
||||||
src->mark_streaming_write_started (lock);
|
|
||||||
std::dynamic_pointer_cast<AudioSource>(src)->write (t->audio_data (n), t->data_length());
|
std::dynamic_pointer_cast<AudioSource>(src)->write (t->audio_data (n), t->data_length());
|
||||||
src->mark_streaming_write_completed (lock);
|
|
||||||
++n;
|
++n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user