AH_SIntPtr buffer_read(t_symbol *buffer, long chan, float *out, AH_SIntPtr max_length) { AH_SIntPtr length; long n_chans, format; void *samps; void *b = ibuffer_get_ptr(buffer); if (!b) return 0; if (!ibuffer_info(b, &samps, &length, &n_chans, &format)) return 0; if (chan >= n_chans) return 0; if (length > max_length || !length) return 0; ibuffer_increment_inuse(b); ibuffer_get_samps(samps, out, 0L, length, n_chans, chan, format); ibuffer_decrement_inuse(b); return length; }
AH_SIntPtr buffer_read_part(t_symbol *buffer, long chan, float *out, AH_SIntPtr offset, AH_SIntPtr read_length) { AH_SIntPtr length; long n_chans, format; void *samps; void *b = ibuffer_get_ptr(buffer); if (!b) return 0; if (!ibuffer_info(b, &samps, &length, &n_chans, &format)) return 0; ibuffer_increment_inuse(b); ibuffer_get_samps(samps, out, offset, read_length, n_chans, chan, format); ibuffer_decrement_inuse(b); return read_length; }
void ibufconcatenate_append(t_ibufconcatenate *x, t_symbol *source_name) { ibuffer_data target(x->attachment->buffer_name); ibuffer_data source(source_name); float *out_samps; double *starts = x->attachment->starts; double *ends = x->attachment->ends; long samp_offset = x->attachment->samp_offset; long num_items = x->attachment->num_items; long new_size; long old_size; double sr_const; t_atom last_added_list[3]; if (target.get_type() == kBufferMaxBuffer) { // Check we have a mono buffer and that there is space for another item if (target.get_num_chans() > 1) { error ("ibufconcatenate: only supports writing to mono buffers at this time"); return; } if (num_items >= MAX_ITEMS) return; // Check we have enough memory in the buffer if (samp_offset + source.get_length() + 1 > target.get_length()) { // Calculate memory to allocate float *temp; new_size = samp_offset + source.get_length() + 1; old_size = target.get_length(); if (old_size + GROW_SIZE > new_size) new_size = old_size + GROW_SIZE; // Allocate temporary memory temp = static_cast<float*>(malloc(sizeof(float) * target.get_length())); if (!temp) { error ("ibufconcatenate: no room left in buffer"); return; } // Copy out out_samps = static_cast<float *>(target.get_samples()); std::copy(out_samps, out_samps + old_size, temp); // Set buffer to new size target.set_size_in_samples(new_size); out_samps = static_cast<float *>(target.get_samples()); if (target.get_length()); std::copy(temp, temp + old_size, out_samps); // Free temporary memory and check the resize has worked free(temp); if (samp_offset + source.get_length() + 1 > target.get_length()) { error ("ibufconcatenate: no room left in buffer"); return; } } out_samps = static_cast<float *>(target.get_samples()); // Get samples from the source - this is constrained to only msp buffers do to unknown pointer alignment in the target (with the offset) ibuffer_get_samps(source, out_samps, samp_offset, source.get_length(), 0); // Add a silent sample *(out_samps + samp_offset + source.get_length()) = 0.f; // Store data sr_const = 1000.0 / target.get_sample_rate(); starts[num_items] = (double) samp_offset * sr_const; samp_offset = samp_offset + source.get_length() + 1; ends[num_items] = (double) (samp_offset - 1) * sr_const; x->attachment->num_items = num_items + 1; x->attachment->samp_offset = samp_offset; // Set the buffer as dirty target.set_dirty(); // We are done with the buffers target.release(); source.release(); // Output Values atom_setlong(last_added_list, num_items + 1); atom_setfloat(last_added_list+1, starts[num_items]); atom_setfloat(last_added_list+2, ends[num_items]); outlet_list(x->last_added_out, 0, 3, last_added_list); } }