1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224
|
#ifndef INCLUDED_SAMPLEBUFFER_H
#define INCLUDED_SAMPLEBUFFER_H
#include <vector>
#include "eca-audio-format.h"
#include "sample-specs.h"
class SAMPLE_BUFFER_FUNCTIONS;
class SAMPLE_BUFFER_impl;
/**
* A dynamic container for storing blocks of
* audio data.
*
* Static attributes are:
* - samples of type 'sample_t' (usually 32bit float)
*
* Dynamic attributes are:
* - number of channels
* - length in samples
* - event tags
*
* Provided services:
* - copying from/to other samplebuffer objects
* - basic audio operations
* - importing and exporting data from/to\n
* raw buffers of audio data
* - changing channel count and length
* - reserving space before-hand
* - realtime-safety and pointer locking
* - access to event tags
*/
class SAMPLE_BUFFER {
friend class SAMPLE_BUFFER_FUNCTIONS;
friend class SAMPLE_ITERATOR;
friend class SAMPLE_ITERATOR_CHANNEL;
friend class SAMPLE_ITERATOR_CHANNELS;
friend class SAMPLE_ITERATOR_INTERLEAVED;
public:
/** @name Public type definitions */
/*@{*/
typedef SAMPLE_SPECS::channel_t channel_size_t;
typedef long int buf_size_t;
typedef SAMPLE_SPECS::sample_t sample_t;
enum Tag_name {
/* buffer contains last samples of a stream */
tag_end_of_stream = 1,
/* buffer contains samples from multiple inputs */
tag_mixed_content = (1 << 1),
/* buffer length may vary from buffer to another */
tag_var_length = (1 << 2),
/* internal: placeholder */
tag_last = (1 << 30),
/* internal: matches all tags */
tag_all = 0xffffffff
};
/*@}*/
public:
/** @name Constructors/destructors */
/*@{*/
SAMPLE_BUFFER (buf_size_t buffersize = 0, channel_size_t channels = 0);
~SAMPLE_BUFFER(void);
/*@}*/
public:
/** @name Copying from/to other samplebuffer objects */
/*@{*/
void add_matching_channels(const SAMPLE_BUFFER& x);
void add_matching_channels_ref(const SAMPLE_BUFFER& x);
void add_with_weight(const SAMPLE_BUFFER& x, int weight);
void copy_matching_channels(const SAMPLE_BUFFER& x);
void copy_all_content(const SAMPLE_BUFFER& x);
void copy_range(const SAMPLE_BUFFER& x, buf_size_t start_pos, buf_size_t end_pos, buf_size_t to_pos);
/*@}*/
/** @name Basic audio operations */
/*@{*/
void divide_by(sample_t dvalue);
void divide_by_ref(sample_t dvalue);
void multiply_by(sample_t factor);
void multiply_by(sample_t factor, int channel);
void multiply_by_ref(sample_t factor);
void multiply_by_ref(sample_t factor, int channel);
void limit_values(void);
void limit_values_ref(void);
void make_empty(void);
bool is_empty(void) const { return buffersize_rep == 0; }
void make_silent(void);
void make_silent(int channel);
void make_silent_ref(int channel);
void make_silent_range(buf_size_t start_pos, buf_size_t end_pos);
void make_silent_range_ref(buf_size_t start_pos, buf_size_t end_pos);
void resample(SAMPLE_SPECS::sample_rate_t from_rate, SAMPLE_SPECS::sample_rate_t to_rate);
void resample_set_quality(int quality);
int resample_get_quality(void) const;
/*@}*/
/**
* @name Importing and exporting data from/to raw buffers of audio data */
/*@{*/
void import_interleaved(unsigned char* source, buf_size_t samples, ECA_AUDIO_FORMAT::Sample_format fmt, channel_size_t ch);
void import_noninterleaved(unsigned char* source, buf_size_t samples, ECA_AUDIO_FORMAT::Sample_format fmt, channel_size_t ch);
void export_interleaved(unsigned char* target, ECA_AUDIO_FORMAT::Sample_format fmt, channel_size_t ch);
void export_noninterleaved(unsigned char* target, ECA_AUDIO_FORMAT::Sample_format fmt, channel_size_t ch);
/*@}*/
public:
/** @name Changing channel count, length and sample-rate. */
/*@{*/
void number_of_channels(channel_size_t num);
inline channel_size_t number_of_channels(void) const { return(channel_count_rep); }
void length_in_samples(buf_size_t len);
inline buf_size_t length_in_samples(void) const { return(buffersize_rep); }
/*@}*/
/**@name Reserving space before-hand */
/*@{*/
void resample_init_memory(SAMPLE_SPECS::sample_rate_t from_rate, SAMPLE_SPECS::sample_rate_t to_rate);
void reserve_channels(channel_size_t num);
void reserve_length_in_samples(buf_size_t len);
/*@}*/
/** @name Realtime-safety and pointer locking */
/*@{*/
void set_rt_lock(bool state);
void get_pointer_reflock(void);
void release_pointer_reflock(void);
/*@}*/
/** @name Event tags - for relaying additional info about the buffer */
/*@{*/
void event_tags_add(const SAMPLE_BUFFER& sbuf);
void event_tags_set(const SAMPLE_BUFFER& sbuf);
void event_tags_clear(Tag_name tagmask = tag_all);
void event_tag_set(Tag_name tag, bool val = true);
bool event_tag_test(Tag_name tag);
/*@}*/
private:
void resample_extfilter(SAMPLE_SPECS::sample_rate_t from_rate, SAMPLE_SPECS::sample_rate_t to_rate);
void resample_secret_rabbit_code(SAMPLE_SPECS::sample_rate_t from_srate, SAMPLE_SPECS::sample_rate_t to_srate);
void resample_simplefilter(SAMPLE_SPECS::sample_rate_t from_rate, SAMPLE_SPECS::sample_rate_t to_rate);
void resample_nofilter(SAMPLE_SPECS::sample_rate_t from_rate, SAMPLE_SPECS::sample_rate_t to_rate);
void resample_with_memory(SAMPLE_SPECS::sample_rate_t from_rate, SAMPLE_SPECS::sample_rate_t to_rate);
static void import_helper(const unsigned char *ibuffer,
buf_size_t* iptr,
sample_t* obuffer,
buf_size_t optr,
ECA_AUDIO_FORMAT::Sample_format fmt);
static void export_helper(unsigned char* obuffer,
buf_size_t* optr,
sample_t value,
ECA_AUDIO_FORMAT::Sample_format fmt);
public:
/** @name Data representation */
/**
* WARNING! Although 'buffer' is a public member, you should only
* use it directly for a very, very good reason. All normal
* input/output should be done via the SAMPLEBUFFER_ITERATORS
* class. Representation of 'buffer' may change at any time,
* and this will break all code using direct-access.
*
* If you do use direct access, then you must also
* use the get_pointer_reflock() and release_pointer_reflock()
* calls so that reference counting is possible.
*/
std::vector<sample_t*> buffer;
/*@}*/
private:
/** @name Private data */
/*@{*/
channel_size_t channel_count_rep;
buf_size_t buffersize_rep;
buf_size_t reserved_samples_rep;
/*@}*/
SAMPLE_BUFFER_impl* impl_repp;
private:
SAMPLE_BUFFER& operator= (const SAMPLE_BUFFER& t);
SAMPLE_BUFFER (const SAMPLE_BUFFER& x);
};
#endif
|