13
0

a bit more type-safety when handling audio data during clip recording

This commit is contained in:
Paul Davis 2024-09-27 15:58:52 -06:00
parent d7c424c440
commit 26fb50d1a9
2 changed files with 54 additions and 16 deletions

View File

@ -549,6 +549,41 @@ class LIBARDOUR_API AudioTrigger : public Trigger {
uint32_t channels () const { return data.size(); }
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;
size_t data_length() const { return data.length; }
@ -556,13 +591,7 @@ class LIBARDOUR_API AudioTrigger : public Trigger {
void retrigger ();
private:
struct Data : std::vector<Sample*> {
samplecnt_t length;
Data () : length (0) {}
};
Data data;
AudioData data;
RubberBand::RubberBandStretcher* _stretcher;
samplepos_t _start_offset;
@ -770,7 +799,7 @@ struct SlotArmInfo {
samplecnt_t capture_length;
RTMidiBuffer* midi_buf; /* assumed large enough */
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;
};

View File

@ -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)
: Trigger (n, b)
, _stretcher (0)
@ -1910,8 +1923,9 @@ AudioTrigger::load_data (std::shared_ptr<AudioRegion> ar)
drop_data ();
try {
data.alloc (data.length, nchans);
for (uint32_t n = 0; n < nchans; ++n) {
data.push_back (new Sample[data.length]);
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->beats = new RTMidiBufferBeats;
} else {
for (uint32_t n = 0; n < chans; ++n) {
ai->audio_buf.push_back (new Sample[_session.sample_rate() * 30]); // XXX Config->max_slot_audio_duration
}
ai->audio_buf.alloc (_session.sample_rate() * 30, chans); // XXX Config->max_slot_audio_duration
AudioTrigger* at = dynamic_cast<AudioTrigger*> (&slot);
assert (at);
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) {
assert (ai->audio_buf.size() >= n);
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 */
@ -5583,10 +5595,7 @@ TriggerBoxThread::build_audio_source (AudioTrigger* t)
size_t n = 0;
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());
src->mark_streaming_write_completed (lock);
++n;
}