framework2

Форк
0
623 строки · 18.7 Кб
1
/*
2
 * ofSoundBuffer.cpp
3
 *
4
 *  Created on: 25/07/2012
5
 *      Author: arturo
6
 */
7

8
#include "ofSoundBuffer.h"
9
#include "ofSoundUtils.h"
10
#include "ofLog.h"
11
#define GLM_FORCE_CTOR_INIT
12
#include "glm/trigonometric.hpp"
13
#include <limits>
14

15
using std::vector;
16
using std::string;
17

18

19
#if !defined(TARGET_ANDROID) && !defined(TARGET_IPHONE) && !defined(TARGET_LINUX_ARM)
20
ofSoundBuffer::InterpolationAlgorithm ofSoundBuffer::defaultAlgorithm = ofSoundBuffer::Hermite;
21
#else
22
ofSoundBuffer::InterpolationAlgorithm ofSoundBuffer::defaultAlgorithm = ofSoundBuffer::Linear;
23
#endif
24

25
ofSoundBuffer::ofSoundBuffer()
26
:channels(1)
27
,samplerate(44100)
28
,tickCount(0)
29
,soundStreamDeviceID(0){
30

31
}
32

33
ofSoundBuffer::ofSoundBuffer(short * shortBuffer, std::size_t numFrames, std::size_t numChannels, unsigned int sampleRate)
34
:tickCount(0)
35
,soundStreamDeviceID(0) {
36
	copyFrom(shortBuffer, numFrames, numChannels, sampleRate);
37
	checkSizeAndChannelsConsistency("constructor");
38
}
39

40
void ofSoundBuffer::copyFrom(const short * shortBuffer, std::size_t numFrames, std::size_t numChannels, unsigned int _sampleRate) {
41
	this->channels = numChannels;
42
	setSampleRate(_sampleRate);
43
	buffer.resize(numFrames * numChannels);
44
	for(std::size_t i = 0; i < size(); i++){
45
		buffer[i] = shortBuffer[i]/float(std::numeric_limits<short>::max());
46
	}
47
	checkSizeAndChannelsConsistency("copyFrom");
48
}
49

50
void ofSoundBuffer::copyFrom(const float * floatBuffer, std::size_t numFrames, std::size_t numChannels, unsigned int _sampleRate) {
51
	this->channels = numChannels;
52
	setSampleRate(_sampleRate);
53
	buffer.assign(floatBuffer, floatBuffer + (numFrames * numChannels));
54
	checkSizeAndChannelsConsistency("copyFrom");
55
}
56

57
void ofSoundBuffer::copyFrom(const vector<short> & shortBuffer, std::size_t numChannels, unsigned int sampleRate){
58
	copyFrom(&shortBuffer[0],shortBuffer.size()/numChannels,numChannels,sampleRate);
59
}
60

61
void ofSoundBuffer::copyFrom(const vector<float> & floatBuffer, std::size_t numChannels, unsigned int sampleRate){
62
	copyFrom(&floatBuffer[0],floatBuffer.size()/numChannels,numChannels,sampleRate);
63
}
64

65
void ofSoundBuffer::toShortPCM(vector<short> & dst) const{
66
	dst.resize(size());
67
	for(std::size_t i = 0; i < size(); i++){
68
		dst[i] = buffer[i]*float(std::numeric_limits<short>::max());
69
	}
70
}
71

72
void ofSoundBuffer::toShortPCM(short * dst) const{
73
	for(std::size_t i = 0; i < size(); i++){
74
		dst[i] = buffer[i]*float(std::numeric_limits<short>::max());
75
	}
76
}
77

78
vector<float> & ofSoundBuffer::getBuffer(){
79
	return buffer;
80
}
81

82
const vector<float> & ofSoundBuffer::getBuffer() const{
83
	return buffer;
84
}
85

86
uint64_t ofSoundBuffer::getDurationMS() const{
87
	return uint64_t(getNumFrames()) * uint64_t(1000) / uint64_t(samplerate);
88
}
89

90
uint64_t ofSoundBuffer::getDurationMicros() const{
91
	return uint64_t(getNumFrames()) * uint64_t(1000000) / uint64_t(samplerate);
92
}
93

94
uint64_t ofSoundBuffer::getDurationNanos() const{
95
	return uint64_t(getNumFrames()) * uint64_t(1000000000) / uint64_t(samplerate);
96
}
97

98
void ofSoundBuffer::setNumChannels(int channels){
99
	this->channels = channels;
100
	checkSizeAndChannelsConsistency("setNumChannels");
101
}
102

103
void ofSoundBuffer::setSampleRate(unsigned int rate){
104
	samplerate = rate;
105
}
106

107
void ofSoundBuffer::allocate(size_t numSamples, size_t numChannels){
108
	resize(numSamples*numChannels);
109
	channels = numChannels;
110
}
111

112
void ofSoundBuffer::resize(std::size_t samples, float val){
113
	buffer.resize(samples, val);
114
	checkSizeAndChannelsConsistency("resize(samples,val)");
115
}
116

117
void ofSoundBuffer::clear(){
118
	buffer.clear();
119
}
120

121
void ofSoundBuffer::set(float value){
122
	buffer.assign(buffer.size(), value);
123
	checkSizeAndChannelsConsistency("set");
124
}
125

126
bool ofSoundBuffer::checkSizeAndChannelsConsistency(const std::string& _function ) {
127
	std::string function = _function;
128

129
	if ( function.size()!= 0 ){
130
		function += ": ";
131
	}
132
	if ( (size()%channels) != 0 ){
133
		ofLogWarning("ofSoundBuffer") << function << "channel count " << channels << " is not consistent with sample count " << size() << " (non-zero remainder)";
134
		return false;
135
	}
136
	return true;
137
}
138

139
float & ofSoundBuffer::operator[](std::size_t pos){
140
	return buffer[pos];
141
}
142

143
const float & ofSoundBuffer::operator[](std::size_t pos) const{
144
	return buffer[pos];
145
}
146

147
float & ofSoundBuffer::getSample(std::size_t frameIndex, std::size_t channel){
148
	return buffer[(frameIndex * channels) + channel];
149
}
150

151
const float & ofSoundBuffer::getSample(std::size_t frameIndex, std::size_t channel) const {
152
	return buffer[(frameIndex * channels) + channel];
153
}
154

155
void ofSoundBuffer::swap(ofSoundBuffer & buffer){
156
	std::swap(this->channels, buffer.channels);
157
	std::swap(this->samplerate, buffer.samplerate);
158
	std::swap(this->tickCount, buffer.tickCount);
159
	std::swap(this->soundStreamDeviceID, buffer.soundStreamDeviceID);
160
	std::swap(this->buffer, buffer.buffer);
161
}
162

163
ofSoundBuffer ofSoundBuffer::operator*(float value){
164
	ofSoundBuffer ret = *this;
165
	ret *= value;
166
	return ret;
167
}
168

169
ofSoundBuffer & ofSoundBuffer::operator*=(float value){
170
	for(std::size_t i=0;i<buffer.size();i++){
171
		buffer[i] *= value;
172
	}
173
	return *this;
174
}
175

176
void ofSoundBuffer::stereoPan(float left, float right){
177
	if(channels!=2){
178
		ofLogWarning("ofSoundBuffer") << "stereoPan called on a buffer with " << channels << " channels, only works with 2 channels";
179
		return;
180
	}
181
	float * bufferPtr = &buffer[0];
182
	for(std::size_t i=0;i<getNumFrames();i++){
183
		*bufferPtr++ *= left;
184
		*bufferPtr++ *= right;
185
	}
186
}
187

188
void ofSoundBuffer::copyTo(ofSoundBuffer & soundBuffer, std::size_t nFrames, std::size_t outChannels,std::size_t fromFrame,bool loop) const{
189
	soundBuffer.resize(nFrames*outChannels);
190
	soundBuffer.setNumChannels(outChannels);
191
	soundBuffer.setSampleRate(samplerate);
192
	soundBuffer.setTickCount(this->getTickCount());
193
	soundBuffer.setDeviceID(this->getDeviceID());
194
	copyTo(&soundBuffer[0], nFrames, outChannels, fromFrame, loop);
195
}
196

197
void ofSoundBuffer::copyTo(ofSoundBuffer & outBuffer, std::size_t fromFrame, bool loop) const{
198
	outBuffer.setTickCount(this->getTickCount());
199
	outBuffer.setDeviceID(this->getDeviceID());
200
	copyTo(&outBuffer[0], outBuffer.getNumFrames(), outBuffer.getNumChannels(), fromFrame, loop);
201
}
202

203
void ofSoundBuffer::addTo(ofSoundBuffer & soundBuffer, std::size_t nFrames, std::size_t outChannels,std::size_t fromFrame, bool loop) const {
204
	soundBuffer.resize(nFrames*outChannels);
205
	soundBuffer.setNumChannels(outChannels);
206
	soundBuffer.setSampleRate(samplerate);
207
	addTo(&soundBuffer.getBuffer()[0], nFrames, outChannels, fromFrame, loop);
208
}
209

210
void ofSoundBuffer::addTo(ofSoundBuffer & outBuffer, std::size_t fromFrame, bool loop) const{
211
	addTo(&outBuffer[0], outBuffer.getNumFrames(), outBuffer.getNumChannels(), fromFrame, loop);
212
}
213

214
void ofSoundBuffer::copyTo(float * outBuffer, std::size_t nFrames, std::size_t outChannels, std::size_t fromFrame, bool loop) const{
215
	// figure out how many frames we can copy before we need to stop or loop
216
	std::size_t nFramesToCopy = nFrames;
217
	if ((fromFrame + nFrames) >= this->getNumFrames()){
218
		nFramesToCopy = this->getNumFrames() - fromFrame;
219
	}
220
		
221
	const float * buffPtr = &buffer[fromFrame * channels];
222
	// if channels count matches we can just memcpy
223
	if(channels == outChannels){
224
		memcpy(outBuffer, buffPtr, nFramesToCopy * channels * sizeof(float));
225
		outBuffer += nFramesToCopy * outChannels;
226
	} else if(channels > outChannels){
227
		// otherwise, if we have more channels than the output is requesting,
228
		// we copy the first outChannels channels
229
		for(std::size_t i = 0; i < nFramesToCopy; i++){
230
			for(std::size_t j = 0; j < outChannels; j++){
231
				*outBuffer++ = *buffPtr++;
232
			}
233
			// and skip the rest
234
			buffPtr += channels - outChannels;
235
		}
236
	} else {
237
		// we have fewer channels than output is requesting. so replicate as many channels as possible then loop.
238
		// if we have 2 channels and output wants 5, data is copied from our channels in the following in order:
239
		// 1 2 1 2 1
240
		for(std::size_t i = 0; i < nFramesToCopy; i++){
241
			for(std::size_t j = 0; j < outChannels; j++){
242
				*outBuffer++ = buffPtr[(j%channels)];
243
			}
244
			buffPtr += channels;
245
		}
246
	}
247

248
	// do we have anything left?
249
	int framesRemaining = nFrames - (int)nFramesToCopy;
250
	if (framesRemaining > 0){
251
		if(!loop || size() == 0){
252
			// fill with 0s
253
			for(std::size_t i = 0; i < framesRemaining * outChannels; i++){
254
				outBuffer[i] = 0;
255
			}
256
		}else{
257
			// loop
258
			copyTo(outBuffer, framesRemaining, outChannels, 0, loop);
259
		}
260
	}
261
}
262

263
void ofSoundBuffer::addTo(float * outBuffer, std::size_t nFrames, std::size_t outChannels, std::size_t fromFrame, bool loop) const{
264
	// figure out how many frames we can copy before we need to stop or loop
265
	std::size_t nFramesToCopy = nFrames;
266
	if ((fromFrame + nFrames) >= this->getNumFrames()){
267
		nFramesToCopy = this->getNumFrames() - fromFrame;
268
	}
269

270
	const float * buffPtr = &buffer[fromFrame * channels];
271
	// if channels count matches it is easy
272
	if(channels == outChannels){
273
		for(std::size_t i = 0; i < (nFramesToCopy * outChannels); i++){
274
			outBuffer[i] += buffPtr[i];
275
		}
276
		outBuffer += nFramesToCopy * outChannels;
277
	} else if(channels > outChannels){
278
		// otherwise, if we have more channels than the output is requesting,
279
		// we copy the first outChannels channels
280
		for(std::size_t i = 0; i < nFramesToCopy; i++){
281
			for(std::size_t j = 0; j < outChannels; j++){
282
				*outBuffer++ += *buffPtr++;
283
			}
284
			// and skip the rest
285
			buffPtr += channels - outChannels;
286
		}
287
	} else {
288
		// we have fewer channels than output is requesting. so replicate as many channels as possible then loop.
289
		// if we have 2 channels and output wants 5, data is copied from our channels in the following in order:
290
		// 1 2 1 2 1
291
		for(std::size_t i = 0; i < nFramesToCopy; i++){
292
			for(std::size_t j = 0; j < outChannels; j++){
293
				*outBuffer++ += buffPtr[(j%channels)];
294
			}
295
			buffPtr += channels;
296
		}
297
	}
298

299
	// do we have anything left?
300
	int framesRemaining = nFrames - (int)nFramesToCopy;
301
	if (framesRemaining > 0 && loop){
302
		// loop
303
		addTo(outBuffer, framesRemaining, outChannels, 0, loop);
304
	}
305
}
306

307

308
void ofSoundBuffer::append(ofSoundBuffer & other){
309
	if(other.getNumChannels() != getNumChannels()){
310
		ofLogError() << "can't append sound buffers with different num channels";
311
		return;
312
	}
313
	buffer.insert(buffer.end(),other.buffer.begin(),other.buffer.end());
314
}
315

316
static bool prepareBufferForResampling(const ofSoundBuffer &in, ofSoundBuffer &out, std::size_t numFrames) {
317
	std::size_t totalOutBufferSize = numFrames * in.getNumChannels();
318
	
319
	if(totalOutBufferSize < out.getBuffer().max_size()) {
320
		out.resize(totalOutBufferSize,0);
321
	} else {
322
		ofLogError("ofSoundUtils") << "resampling would create a buffer size of " << totalOutBufferSize << " (too large for std::vector)";
323
		return false;
324
	}
325
	
326
	out.setNumChannels(in.getNumChannels());
327
	out.setSampleRate(in.getSampleRate());
328
	return true;
329
}
330

331
// based on maximilian optimized for performance.
332
// might lose 1 or 2 samples when it reaches the end of the buffer
333
void ofSoundBuffer::linearResampleTo(ofSoundBuffer &outBuffer, std::size_t fromFrame, std::size_t numFrames, float speed, bool loop) const {
334
	
335
	std::size_t inChannels = getNumChannels();
336
	std::size_t inFrames = getNumFrames();
337
	bool bufferReady = prepareBufferForResampling(*this, outBuffer, numFrames);
338
	
339
	if(!bufferReady) {
340
		outBuffer = *this;
341
		return;
342
	}
343
	
344
	std::size_t start = fromFrame;
345
	std::size_t end = start*inChannels + double(numFrames*inChannels)*speed;
346
	double position = start;
347
	std::size_t intPosition = position;
348
	float increment = speed;
349
	std::size_t copySize = inChannels*sizeof(float);
350
	std::size_t to;
351
	
352
	if(end<size()-2*inChannels){
353
		to = numFrames;
354
	}else if(fromFrame+2>inFrames){
355
		to = 0;
356
	}else{
357
		to = ceil(float(inFrames-2-fromFrame)/speed);
358
	}
359
	
360
	float remainder = position - intPosition;
361
	float * resBufferPtr = &outBuffer[0];
362
	float a, b;
363
	
364
	for(std::size_t i=0;i<to;i++){
365
		intPosition *= inChannels;
366
		for(std::size_t j=0;j<inChannels;j++){
367
			a = buffer[intPosition+j];
368
			b = buffer[intPosition+inChannels+j];
369
			*resBufferPtr++ = ofLerp(a,b,remainder);
370
		}
371
		position += increment;
372
		intPosition = position;
373
		remainder = position - intPosition;
374
	}
375
	if(end>=size()-2*inChannels){
376
		to = numFrames-to;
377
		if(loop){
378
			intPosition %= inFrames;
379
			for(std::size_t i=0;i<to;i++){
380
				intPosition *= inChannels;
381
				for(std::size_t j=0;j<inChannels;j++){
382
					a = buffer[intPosition+j];
383
					b = buffer[intPosition+inChannels+j];
384
					*resBufferPtr++ = ofLerp(a,b,remainder);
385
				}
386
				position += increment;
387
				intPosition = position;
388
			}
389
		}else{
390
			memset(resBufferPtr,0,to*copySize);
391
		}
392
	}
393
}
394

395
// based on maximilian optimized for performance.
396
// might lose 1 to 3 samples when it reaches the end of the buffer
397
void ofSoundBuffer::hermiteResampleTo(ofSoundBuffer &outBuffer, std::size_t fromFrame, std::size_t numFrames, float speed, bool loop) const {
398
	
399
	std::size_t inChannels = getNumChannels();
400
	std::size_t inFrames = getNumFrames();
401
	bool bufferReady = prepareBufferForResampling(*this, outBuffer, numFrames);
402
	
403
	if(!bufferReady) {
404
		outBuffer = *this;
405
		return;
406
	}
407
	
408
	std::size_t start = fromFrame;
409
	std::size_t end = start*inChannels + double(numFrames*inChannels)*speed;
410
	double position = start;
411
	std::size_t intPosition = position;
412
	float remainder = position - intPosition;
413
	float increment = speed;
414
	std::size_t copySize = inChannels*sizeof(float);
415
	std::size_t to;
416
	
417
	if(end<size()-3*inChannels){
418
		to = numFrames;
419
	}else if(fromFrame+3>inFrames){
420
		to = 0;
421
	}else{
422
		to = double(inFrames-3-fromFrame)/speed;
423
	}
424
	
425
	float * resBufferPtr = &outBuffer[0];
426
	float a,b,c,d;
427
	std::size_t from = 0;
428
	
429
	while(intPosition==0){
430
		intPosition *= inChannels;
431
		for(std::size_t j=0;j<inChannels;++j){
432
			a=loop?buffer[j]:0;
433
			b=buffer[intPosition+j];
434
			c=buffer[intPosition+j+inChannels];
435
			d=buffer[intPosition+j+inChannels*2];
436
			*resBufferPtr++ = ofInterpolateHermite(a, b, c, d, remainder);
437
		}
438
		position += increment;
439
		intPosition = position;
440
		remainder = position - intPosition;
441
		from++;
442
	}
443
	
444
	for(std::size_t i=from;i<to;++i){
445
		intPosition *= inChannels;
446
		for(std::size_t j=0;j<inChannels;++j){
447
			a=buffer[intPosition+j-inChannels];
448
			b=buffer[intPosition+j];
449
			c=buffer[intPosition+j+inChannels];
450
			d=buffer[intPosition+j+inChannels*2];
451
			*resBufferPtr++ = ofInterpolateHermite(a, b, c, d, remainder);
452
		}
453
		position += increment;
454
		intPosition = position;
455
		remainder = position - intPosition;
456
	}
457
	
458
	if(end>=size()-3*inChannels){
459
		to = numFrames-to;
460
		if(loop){
461
			intPosition %= size();
462
			for(std::size_t i=0;i<to;++i){
463
				for(std::size_t j=0;j<inChannels;++j){
464
					a=buffer[intPosition+j-inChannels];
465
					b=buffer[intPosition+j];
466
					c=buffer[intPosition+j+inChannels];
467
					d=buffer[intPosition+j+inChannels*2];
468
					*resBufferPtr++ = ofInterpolateHermite(a, b, c, d, remainder);
469
				}
470
				position += increment;
471
				intPosition = position;
472
				remainder = position - intPosition;
473
				intPosition *= inChannels;
474
			}
475
		}else{
476
			memset(resBufferPtr,0,to*copySize);
477
		}
478
	}
479
}
480

481
void ofSoundBuffer::resampleTo(ofSoundBuffer & buffer, std::size_t fromFrame, std::size_t numFrames, float speed, bool loop, InterpolationAlgorithm algorithm) const {
482
	switch(algorithm){
483
		case Linear:
484
			linearResampleTo(buffer, fromFrame, numFrames, speed, loop);
485
			break;
486
		case Hermite:
487
			hermiteResampleTo(buffer, fromFrame, numFrames, speed, loop);
488
			break;
489
	}
490
}
491

492
void ofSoundBuffer::resample(float speed, InterpolationAlgorithm algorithm){
493
	ofSoundBuffer resampled;
494
	resampleTo(resampled, 0, ceilf(getNumFrames() / speed), speed, false, algorithm);
495
	*this = resampled;
496
}
497

498
void ofSoundBuffer::getChannel(ofSoundBuffer & targetBuffer, std::size_t sourceChannel) const {
499
	if(channels == 0) {
500
		ofLogWarning("ofSoundBuffer") << "getChannel requested on empty buffer";
501
		return;
502
	}
503
	if (sourceChannel >= channels){
504
		ofLogWarning("ofSoundBuffer") << "getChannel requested channel " << sourceChannel << " but we only have " << channels << " channels. clamping channel to " << channels-1;
505
		sourceChannel = channels-1;
506
	}
507
	targetBuffer.setNumChannels(1);
508
	targetBuffer.setSampleRate(samplerate);
509
	if(channels == 1){
510
		copyTo(targetBuffer, getNumFrames(), 1, 0);
511
	}else{
512
		// fetch samples from only one channel
513
		targetBuffer.resize(getNumFrames());
514
		const float * bufferPtr = &this->buffer[sourceChannel];
515
		for(std::size_t i = 0; i < targetBuffer.getNumFrames(); i++){
516
			targetBuffer[i] = *bufferPtr;
517
			bufferPtr += channels;
518
		}
519
	}
520
}
521

522
void ofSoundBuffer::setChannel(const ofSoundBuffer & inBuffer, std::size_t targetChannel){
523
	// resize ourself to match inBuffer
524
	resize(inBuffer.getNumFrames() * channels);
525
	// copy from inBuffer to targetChannel
526
	float * bufferPtr = &this->buffer[targetChannel];
527
	const float * inBufferPtr = &(inBuffer[0]);
528
	for(std::size_t i = 0; i < getNumFrames(); i++){
529
		*bufferPtr = *inBufferPtr;
530
		bufferPtr += channels;
531
		// inBuffer.getNumChannels() is probably 1 but let's be safe
532
		inBufferPtr += inBuffer.getNumChannels(); 
533
	}
534
}
535

536
float ofSoundBuffer::getRMSAmplitude() const {
537
	double acc = 0;
538
	for(size_t i = 0; i < buffer.size(); i++){
539
		acc += buffer[i] * buffer[i];
540
	}
541
	return sqrt(acc / (double)buffer.size());
542
}
543

544
float ofSoundBuffer::getRMSAmplitudeChannel(std::size_t channel) const {
545
	if(channel > channels - 1) {
546
		return 0;
547
	}
548

549
	double acc = 0;
550
	for(size_t i = 0; i < getNumFrames(); i++) {
551
		float sample = getSample(i, channel);
552
		acc += sample * sample;
553
	}
554
	return sqrt(acc / (double)getNumFrames());
555
}
556

557
void ofSoundBuffer::normalize(float level){
558
	float maxAmplitude = 0;
559
	for(std::size_t i = 0; i < size(); i++) {
560
		maxAmplitude = std::max(maxAmplitude, std::abs(buffer[i]));
561
	}
562
	float normalizationFactor = level/maxAmplitude;
563
	for(std::size_t i = 0; i < size(); i++) {
564
		buffer[i] *= normalizationFactor;
565
	}
566
}
567

568
bool ofSoundBuffer::trimSilence(float threshold, bool trimStart, bool trimEnd) {
569
	if(buffer.empty()) {
570
		ofLogVerbose("ofSoundBuffer") << "attempted to trim empty buffer";
571
		return true;
572
	}
573
	std::size_t firstNonSilence = 0;
574
	std::size_t lastNonSilence = buffer.size() - 1;
575
	if(trimStart) {
576
		for(std::size_t i = 0; i < buffer.size(); ++i) {
577
			if(std::abs(buffer[i]) > threshold) {
578
				firstNonSilence = i;
579
				break;
580
			}
581
		}
582
	}
583
	if(trimEnd) {
584
		for(std::size_t i = lastNonSilence; i > firstNonSilence; --i) {
585
			if(std::abs(buffer[i]) > threshold) {
586
				lastNonSilence = i;
587
				break;
588
			}
589
		}
590
	}
591
	firstNonSilence -= firstNonSilence % getNumChannels();
592
	lastNonSilence  -= lastNonSilence  % getNumChannels();
593
	if(trimEnd) {
594
		buffer.erase(buffer.begin() + lastNonSilence, buffer.end());
595
	}
596
	if(trimStart) {
597
		buffer.erase(buffer.begin(), buffer.begin() + firstNonSilence);
598
	}
599
	return checkSizeAndChannelsConsistency("trimSilence");
600
}
601

602
void ofSoundBuffer::fillWithNoise(float amplitude){
603
	for (std::size_t i=0; i<size(); i++ ) {
604
		buffer[i] = ofRandom(-amplitude, amplitude);
605
	}
606
}
607

608
float ofSoundBuffer::fillWithTone( float pitchHz, float phase ){
609
	float step = glm::two_pi<float>()*(pitchHz/samplerate);
610
	for (std::size_t i=0; i<size()/channels; i++ ) {
611
		std::size_t base = i*channels;
612
		for (std::size_t j=0; j<channels; j++)
613
			buffer[base+j] = sinf(phase);
614
		phase += step;
615
	}
616
	return phase;
617
}
618

619
namespace std{
620
	void swap(ofSoundBuffer & src, ofSoundBuffer & dst){
621
		src.swap(dst);
622
	}
623
}
624

625

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.