WaveSwissKnife 0.2.0.20120302
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/AUTHORS +4 -0
- data/ChangeLog +31 -0
- data/Credits +3 -0
- data/LICENSE +31 -0
- data/README +15 -0
- data/ReleaseInfo +8 -0
- data/bin/WSK.rb +14 -0
- data/ext/WSK/AnalyzeUtils/AnalyzeUtils.c +272 -0
- data/ext/WSK/AnalyzeUtils/extconf.rb +7 -0
- data/ext/WSK/ArithmUtils/ArithmUtils.c +862 -0
- data/ext/WSK/ArithmUtils/extconf.rb +15 -0
- data/ext/WSK/CommonBuild.rb +29 -0
- data/ext/WSK/FFTUtils/FFTUtils.c +662 -0
- data/ext/WSK/FFTUtils/extconf.rb +15 -0
- data/ext/WSK/FunctionUtils/FunctionUtils.c +182 -0
- data/ext/WSK/FunctionUtils/extconf.rb +15 -0
- data/ext/WSK/SilentUtils/SilentUtils.c +431 -0
- data/ext/WSK/SilentUtils/extconf.rb +7 -0
- data/ext/WSK/VolumeUtils/VolumeUtils.c +494 -0
- data/ext/WSK/VolumeUtils/extconf.rb +15 -0
- data/external/CommonUtils/build.rb +28 -0
- data/external/CommonUtils/include/CommonUtils.h +177 -0
- data/external/CommonUtils/src/CommonUtils.c +639 -0
- data/lib/WSK/Actions/Analyze.rb +176 -0
- data/lib/WSK/Actions/ApplyMap.desc.rb +15 -0
- data/lib/WSK/Actions/ApplyMap.rb +57 -0
- data/lib/WSK/Actions/ApplyVolumeFct.desc.rb +30 -0
- data/lib/WSK/Actions/ApplyVolumeFct.rb +72 -0
- data/lib/WSK/Actions/Compare.desc.rb +25 -0
- data/lib/WSK/Actions/Compare.rb +238 -0
- data/lib/WSK/Actions/ConstantCompare.desc.rb +20 -0
- data/lib/WSK/Actions/ConstantCompare.rb +61 -0
- data/lib/WSK/Actions/Cut.desc.rb +20 -0
- data/lib/WSK/Actions/Cut.rb +60 -0
- data/lib/WSK/Actions/CutFirstSignal.desc.rb +25 -0
- data/lib/WSK/Actions/CutFirstSignal.rb +72 -0
- data/lib/WSK/Actions/DCShifter.desc.rb +15 -0
- data/lib/WSK/Actions/DCShifter.rb +67 -0
- data/lib/WSK/Actions/DrawFct.desc.rb +20 -0
- data/lib/WSK/Actions/DrawFct.rb +59 -0
- data/lib/WSK/Actions/FFT.rb +104 -0
- data/lib/WSK/Actions/GenAllValues.rb +67 -0
- data/lib/WSK/Actions/GenConstant.desc.rb +20 -0
- data/lib/WSK/Actions/GenConstant.rb +56 -0
- data/lib/WSK/Actions/GenSawtooth.rb +57 -0
- data/lib/WSK/Actions/GenSine.desc.rb +20 -0
- data/lib/WSK/Actions/GenSine.rb +73 -0
- data/lib/WSK/Actions/Identity.rb +43 -0
- data/lib/WSK/Actions/Mix.desc.rb +15 -0
- data/lib/WSK/Actions/Mix.rb +149 -0
- data/lib/WSK/Actions/Multiply.desc.rb +15 -0
- data/lib/WSK/Actions/Multiply.rb +73 -0
- data/lib/WSK/Actions/NoiseGate.desc.rb +35 -0
- data/lib/WSK/Actions/NoiseGate.rb +129 -0
- data/lib/WSK/Actions/SilenceInserter.desc.rb +20 -0
- data/lib/WSK/Actions/SilenceInserter.rb +87 -0
- data/lib/WSK/Actions/SilenceRemover.desc.rb +30 -0
- data/lib/WSK/Actions/SilenceRemover.rb +74 -0
- data/lib/WSK/Actions/VolumeProfile.desc.rb +35 -0
- data/lib/WSK/Actions/VolumeProfile.rb +63 -0
- data/lib/WSK/Common.rb +292 -0
- data/lib/WSK/FFT.rb +527 -0
- data/lib/WSK/Functions.rb +770 -0
- data/lib/WSK/Launcher.rb +216 -0
- data/lib/WSK/Maps.rb +29 -0
- data/lib/WSK/Model/CachedBufferReader.rb +151 -0
- data/lib/WSK/Model/Header.rb +133 -0
- data/lib/WSK/Model/InputData.rb +193 -0
- data/lib/WSK/Model/RawReader.rb +78 -0
- data/lib/WSK/Model/WaveReader.rb +91 -0
- data/lib/WSK/OutputInterfaces/DirectStream.rb +146 -0
- data/lib/WSK/RIFFReader.rb +60 -0
- metadata +155 -0
@@ -0,0 +1,639 @@
|
|
1
|
+
/**
|
2
|
+
* Copyright (c) 2009 - 2012 Muriel Salvan (muriel@x-aeon.com)
|
3
|
+
* Licensed under the terms specified in LICENSE file. No warranty is provided.
|
4
|
+
**/
|
5
|
+
|
6
|
+
#include "CommonUtils.h"
|
7
|
+
#include "ruby.h"
|
8
|
+
#include <stdio.h>
|
9
|
+
|
10
|
+
/**
|
11
|
+
* Invoke each_raw_buffer on an input data.
|
12
|
+
* This is meant to be used with rb_iterate.
|
13
|
+
*
|
14
|
+
* Parameters::
|
15
|
+
* * *iValArgs* (<em>list<Object></em>): List of arguments:
|
16
|
+
* ** *iValInputData* (<em>WSK::Model::InputData</em>): The input data
|
17
|
+
* ** *iValIdxBeginSample* (_Integer_): Index of the first sample to search from
|
18
|
+
*/
|
19
|
+
VALUE commonutils_callEachRawBuffer(
|
20
|
+
VALUE iValArgs) {
|
21
|
+
// Read arguments
|
22
|
+
VALUE iValInputData = rb_ary_entry(iValArgs, 0);
|
23
|
+
VALUE iValIdxBeginSample = rb_ary_entry(iValArgs, 1);
|
24
|
+
|
25
|
+
return rb_funcall(iValInputData, rb_intern("each_raw_buffer"), 1, iValIdxBeginSample);
|
26
|
+
}
|
27
|
+
|
28
|
+
/**
|
29
|
+
* Invoke each_reverse_raw_buffer on an input data.
|
30
|
+
* This is meant to be used with rb_iterate.
|
31
|
+
*
|
32
|
+
* Parameters::
|
33
|
+
* * *iValArgs* (<em>list<Object></em>): List of arguments:
|
34
|
+
* ** *iValInputData* (<em>WSK::Model::InputData</em>): The input data
|
35
|
+
* ** *iValIdxBeginSample* (_Integer_): Index of the first sample to search from
|
36
|
+
*/
|
37
|
+
VALUE commonutils_callEachReverseRawBuffer(
|
38
|
+
VALUE iValArgs) {
|
39
|
+
// Read arguments
|
40
|
+
VALUE iValInputData = rb_ary_entry(iValArgs, 0);
|
41
|
+
VALUE iValIdxBeginSample = rb_ary_entry(iValArgs, 1);
|
42
|
+
|
43
|
+
return rb_funcall(iValInputData, rb_intern("each_reverse_raw_buffer"), 2, INT2FIX(0), iValIdxBeginSample);
|
44
|
+
}
|
45
|
+
|
46
|
+
/**
|
47
|
+
* Iterate through a raw buffer.
|
48
|
+
*
|
49
|
+
* Parameters::
|
50
|
+
* * *iPtrRawBuffer* (<em>const char*</em>): The raw buffer
|
51
|
+
* * *iNbrBitsPerSample* (<em>const int</em>): The number of bits per sample
|
52
|
+
* * *iNbrChannels* (<em>const int</em>): The number of channels
|
53
|
+
* * *iNbrSamples* (<em>const tSampleIndex</em>): The number of samples
|
54
|
+
* * *iIdxOffsetSample* (<em>const tSampleIndex</em>): The base offset of samples to be counted and given to the processing method
|
55
|
+
* * *iPtrProcessMethod* (<em>const tPtrFctProcess</em>): Pointer to the method to call for processing
|
56
|
+
* * *iPtrArgs* (<em>void*</em>): Pointer to a user specific struct that will be given to the processing function
|
57
|
+
*/
|
58
|
+
void commonutils_iterateThroughRawBuffer(
|
59
|
+
const char* iPtrRawBuffer,
|
60
|
+
const int iNbrBitsPerSample,
|
61
|
+
const int iNbrChannels,
|
62
|
+
const tSampleIndex iNbrSamples,
|
63
|
+
const tSampleIndex iIdxOffsetSample,
|
64
|
+
const tPtrFctProcess iPtrProcessMethod,
|
65
|
+
void* iPtrArgs) {
|
66
|
+
// Parse the data. This is done differently depending on the data structure
|
67
|
+
// Define variables outside the loops to not allocate and initialize heap size for nothing
|
68
|
+
tSampleIndex lIdxBufferSample;
|
69
|
+
int lIdxChannel;
|
70
|
+
tSampleIndex lIdxSample = iIdxOffsetSample;
|
71
|
+
// 0: Continue iterations
|
72
|
+
// 1: Break all
|
73
|
+
// 2: Skip to the next sample
|
74
|
+
int lProcessResult;
|
75
|
+
if (iNbrBitsPerSample == 8) {
|
76
|
+
unsigned char* lPtrData = (unsigned char*)iPtrRawBuffer;
|
77
|
+
for (lIdxBufferSample = 0; lIdxBufferSample < iNbrSamples; ++lIdxBufferSample) {
|
78
|
+
lProcessResult = 0;
|
79
|
+
for (lIdxChannel = 0; lIdxChannel < iNbrChannels; ++lIdxChannel) {
|
80
|
+
if (lProcessResult == 0) {
|
81
|
+
lProcessResult = iPtrProcessMethod(((tSampleValue)(*lPtrData)) - 128, lIdxSample, lIdxChannel, iPtrArgs);
|
82
|
+
}
|
83
|
+
if (lProcessResult == 1) {
|
84
|
+
break;
|
85
|
+
}
|
86
|
+
++lPtrData;
|
87
|
+
}
|
88
|
+
if (lProcessResult == 1) {
|
89
|
+
break;
|
90
|
+
}
|
91
|
+
++lIdxSample;
|
92
|
+
}
|
93
|
+
} else if (iNbrBitsPerSample == 16) {
|
94
|
+
signed short int* lPtrData = (signed short int*)iPtrRawBuffer;
|
95
|
+
for (lIdxBufferSample = 0; lIdxBufferSample < iNbrSamples; ++lIdxBufferSample) {
|
96
|
+
lProcessResult = 0;
|
97
|
+
for (lIdxChannel = 0; lIdxChannel < iNbrChannels; ++lIdxChannel) {
|
98
|
+
if (lProcessResult == 0) {
|
99
|
+
lProcessResult = iPtrProcessMethod((tSampleValue)(*lPtrData), lIdxSample, lIdxChannel, iPtrArgs);
|
100
|
+
}
|
101
|
+
if (lProcessResult == 1) {
|
102
|
+
break;
|
103
|
+
}
|
104
|
+
++lPtrData;
|
105
|
+
}
|
106
|
+
if (lProcessResult == 1) {
|
107
|
+
break;
|
108
|
+
}
|
109
|
+
++lIdxSample;
|
110
|
+
}
|
111
|
+
} else if (iNbrBitsPerSample == 24) {
|
112
|
+
t24bits* lPtrData = (t24bits*)iPtrRawBuffer;
|
113
|
+
for (lIdxBufferSample = 0; lIdxBufferSample < iNbrSamples; ++lIdxBufferSample) {
|
114
|
+
lProcessResult = 0;
|
115
|
+
for (lIdxChannel = 0; lIdxChannel < iNbrChannels; ++lIdxChannel) {
|
116
|
+
if (lProcessResult == 0) {
|
117
|
+
lProcessResult = iPtrProcessMethod((tSampleValue)(lPtrData->value), lIdxSample, lIdxChannel, iPtrArgs);
|
118
|
+
}
|
119
|
+
if (lProcessResult == 1) {
|
120
|
+
break;
|
121
|
+
}
|
122
|
+
// Increase lPtrData this way to ensure alignment.
|
123
|
+
lPtrData = (t24bits*)(((int)lPtrData)+3);
|
124
|
+
}
|
125
|
+
if (lProcessResult == 1) {
|
126
|
+
break;
|
127
|
+
}
|
128
|
+
++lIdxSample;
|
129
|
+
}
|
130
|
+
} else {
|
131
|
+
rb_raise(rb_eRuntimeError, "Unknown bits per samples: %d\n", iNbrBitsPerSample);
|
132
|
+
}
|
133
|
+
}
|
134
|
+
|
135
|
+
/**
|
136
|
+
* Iterate through a raw buffer, and writes another raw buffer.
|
137
|
+
*
|
138
|
+
* Parameters::
|
139
|
+
* * *iSelf* (_Object_): Object used to call log methods
|
140
|
+
* * *iPtrRawBuffer* (<em>const char*</em>): The raw buffer
|
141
|
+
* * *oPtrRawBufferOut* (<em>char*</em>): The raw buffer to write
|
142
|
+
* * *iNbrBitsPerSample* (<em>const int</em>): The number of bits per sample
|
143
|
+
* * *iNbrChannels* (<em>const int</em>): The number of channels
|
144
|
+
* * *iNbrSamples* (<em>const tSampleIndex</em>): The number of samples
|
145
|
+
* * *iIdxOffsetSample* (<em>const tSampleIndex</em>): The base offset of samples to be counted and given to the processing method
|
146
|
+
* * *iNeedCheck* (<em>const int</em>): Do we need checking output value ranges ? 0 = no, 1 = yes
|
147
|
+
* * *iPtrProcessMethod* (<em>const tPtrFctProcessOutput</em>): Pointer to the method to call for processing
|
148
|
+
* * *iPtrArgs* (<em>void*</em>): Pointer to a user specific struct that will be given to the processing function
|
149
|
+
*/
|
150
|
+
void commonutils_iterateThroughRawBufferOutput(
|
151
|
+
VALUE iSelf,
|
152
|
+
const char* iPtrRawBuffer,
|
153
|
+
char* oPtrRawBufferOut,
|
154
|
+
const int iNbrBitsPerSample,
|
155
|
+
const int iNbrChannels,
|
156
|
+
const tSampleIndex iNbrSamples,
|
157
|
+
const tSampleIndex iIdxOffsetSample,
|
158
|
+
const int iNeedCheck,
|
159
|
+
const tPtrFctProcessOutput iPtrProcessMethod,
|
160
|
+
void* iPtrArgs) {
|
161
|
+
// Parse the data. This is done differently depending on the data structure
|
162
|
+
// Define variables outside the loops to not allocate and initialize heap size for nothing
|
163
|
+
tSampleIndex lIdxBufferSample;
|
164
|
+
int lIdxChannel;
|
165
|
+
tSampleIndex lIdxSample = iIdxOffsetSample;
|
166
|
+
// 0: Continue iterations
|
167
|
+
// 1: Break all
|
168
|
+
// 2: Skip to the next sample
|
169
|
+
int lProcessResult;
|
170
|
+
tSampleValue lOutputValue;
|
171
|
+
// Compute max and min values if needed only
|
172
|
+
if (iNeedCheck != 0) {
|
173
|
+
char lLogMessage[256];
|
174
|
+
ID lIDLogWarn = rb_intern("log_warn");
|
175
|
+
int lMaxValue = (1 << (iNbrBitsPerSample-1)) - 1;
|
176
|
+
int lMinValue = -(1 << (iNbrBitsPerSample-1));
|
177
|
+
if (iNbrBitsPerSample == 8) {
|
178
|
+
unsigned char* lPtrData = (unsigned char*)iPtrRawBuffer;
|
179
|
+
unsigned char* lPtrDataOut = (unsigned char*)oPtrRawBufferOut;
|
180
|
+
for (lIdxBufferSample = 0; lIdxBufferSample < iNbrSamples; ++lIdxBufferSample) {
|
181
|
+
lProcessResult = 0;
|
182
|
+
for (lIdxChannel = 0; lIdxChannel < iNbrChannels; ++lIdxChannel) {
|
183
|
+
if (lProcessResult == 0) {
|
184
|
+
lProcessResult = iPtrProcessMethod(((tSampleValue)(*lPtrData)) - 128, &lOutputValue, lIdxSample, lIdxChannel, iPtrArgs);
|
185
|
+
}
|
186
|
+
if (lProcessResult == 1) {
|
187
|
+
break;
|
188
|
+
}
|
189
|
+
// Write lOutputValue
|
190
|
+
if (lOutputValue > lMaxValue) {
|
191
|
+
sprintf(lLogMessage, "@%lld,%d - Exceeding maximal value: %d, set to %d", lIdxSample, lIdxChannel, lOutputValue, lMaxValue);
|
192
|
+
rb_funcall(iSelf, lIDLogWarn, 1, rb_str_new2(lLogMessage));
|
193
|
+
lOutputValue = lMaxValue;
|
194
|
+
} else if (lOutputValue < lMinValue) {
|
195
|
+
sprintf(lLogMessage, "@%lld,%d - Exceeding minimal value: %d, set to %d", lIdxSample, lIdxChannel, lOutputValue, lMinValue);
|
196
|
+
rb_funcall(iSelf, lIDLogWarn, 1, rb_str_new2(lLogMessage));
|
197
|
+
lOutputValue = lMinValue;
|
198
|
+
}
|
199
|
+
(*lPtrDataOut) = (unsigned char)(lOutputValue + 128);
|
200
|
+
++lPtrDataOut;
|
201
|
+
++lPtrData;
|
202
|
+
}
|
203
|
+
if (lProcessResult == 1) {
|
204
|
+
break;
|
205
|
+
}
|
206
|
+
++lIdxSample;
|
207
|
+
}
|
208
|
+
} else if (iNbrBitsPerSample == 16) {
|
209
|
+
signed short int* lPtrData = (signed short int*)iPtrRawBuffer;
|
210
|
+
signed short int* lPtrDataOut = (signed short int*)oPtrRawBufferOut;
|
211
|
+
for (lIdxBufferSample = 0; lIdxBufferSample < iNbrSamples; ++lIdxBufferSample) {
|
212
|
+
lProcessResult = 0;
|
213
|
+
for (lIdxChannel = 0; lIdxChannel < iNbrChannels; ++lIdxChannel) {
|
214
|
+
if (lProcessResult == 0) {
|
215
|
+
lProcessResult = iPtrProcessMethod((tSampleValue)(*lPtrData), &lOutputValue, lIdxSample, lIdxChannel, iPtrArgs);
|
216
|
+
}
|
217
|
+
if (lProcessResult == 1) {
|
218
|
+
break;
|
219
|
+
}
|
220
|
+
// Write lOutputValue
|
221
|
+
if (lOutputValue > lMaxValue) {
|
222
|
+
sprintf(lLogMessage, "@%lld,%d - Exceeding maximal value: %d, set to %d", lIdxSample, lIdxChannel, lOutputValue, lMaxValue);
|
223
|
+
rb_funcall(iSelf, lIDLogWarn, 1, rb_str_new2(lLogMessage));
|
224
|
+
lOutputValue = lMaxValue;
|
225
|
+
} else if (lOutputValue < lMinValue) {
|
226
|
+
sprintf(lLogMessage, "@%lld,%d - Exceeding minimal value: %d, set to %d", lIdxSample, lIdxChannel, lOutputValue, lMinValue);
|
227
|
+
rb_funcall(iSelf, lIDLogWarn, 1, rb_str_new2(lLogMessage));
|
228
|
+
lOutputValue = lMinValue;
|
229
|
+
}
|
230
|
+
(*lPtrDataOut) = (signed short int)lOutputValue;
|
231
|
+
++lPtrDataOut;
|
232
|
+
++lPtrData;
|
233
|
+
}
|
234
|
+
if (lProcessResult == 1) {
|
235
|
+
break;
|
236
|
+
}
|
237
|
+
++lIdxSample;
|
238
|
+
}
|
239
|
+
} else if (iNbrBitsPerSample == 24) {
|
240
|
+
t24bits* lPtrData = (t24bits*)iPtrRawBuffer;
|
241
|
+
t24bits* lPtrDataOut = (t24bits*)oPtrRawBufferOut;
|
242
|
+
for (lIdxBufferSample = 0; lIdxBufferSample < iNbrSamples; ++lIdxBufferSample) {
|
243
|
+
lProcessResult = 0;
|
244
|
+
for (lIdxChannel = 0; lIdxChannel < iNbrChannels; ++lIdxChannel) {
|
245
|
+
if (lProcessResult == 0) {
|
246
|
+
lProcessResult = iPtrProcessMethod((tSampleValue)(lPtrData->value), &lOutputValue, lIdxSample, lIdxChannel, iPtrArgs);
|
247
|
+
}
|
248
|
+
if (lProcessResult == 1) {
|
249
|
+
break;
|
250
|
+
}
|
251
|
+
// Write lOutputValue
|
252
|
+
if (lOutputValue > lMaxValue) {
|
253
|
+
sprintf(lLogMessage, "@%lld,%d - Exceeding maximal value: %d, set to %d", lIdxSample, lIdxChannel, lOutputValue, lMaxValue);
|
254
|
+
rb_funcall(iSelf, lIDLogWarn, 1, rb_str_new2(lLogMessage));
|
255
|
+
lOutputValue = lMaxValue;
|
256
|
+
} else if (lOutputValue < lMinValue) {
|
257
|
+
sprintf(lLogMessage, "@%lld,%d - Exceeding minimal value: %d, set to %d", lIdxSample, lIdxChannel, lOutputValue, lMinValue);
|
258
|
+
rb_funcall(iSelf, lIDLogWarn, 1, rb_str_new2(lLogMessage));
|
259
|
+
lOutputValue = lMinValue;
|
260
|
+
}
|
261
|
+
lPtrDataOut->value = lOutputValue;
|
262
|
+
lPtrDataOut = (t24bits*)(((int)lPtrDataOut)+3);
|
263
|
+
// Increase lPtrData this way to ensure alignment.
|
264
|
+
lPtrData = (t24bits*)(((int)lPtrData)+3);
|
265
|
+
}
|
266
|
+
if (lProcessResult == 1) {
|
267
|
+
break;
|
268
|
+
}
|
269
|
+
++lIdxSample;
|
270
|
+
}
|
271
|
+
} else {
|
272
|
+
rb_raise(rb_eRuntimeError, "Unknown bits per samples: %d\n", iNbrBitsPerSample);
|
273
|
+
}
|
274
|
+
} else {
|
275
|
+
// No check needed here. Just write what we get.
|
276
|
+
if (iNbrBitsPerSample == 8) {
|
277
|
+
unsigned char* lPtrData = (unsigned char*)iPtrRawBuffer;
|
278
|
+
unsigned char* lPtrDataOut = (unsigned char*)oPtrRawBufferOut;
|
279
|
+
for (lIdxBufferSample = 0; lIdxBufferSample < iNbrSamples; ++lIdxBufferSample) {
|
280
|
+
lProcessResult = 0;
|
281
|
+
for (lIdxChannel = 0; lIdxChannel < iNbrChannels; ++lIdxChannel) {
|
282
|
+
if (lProcessResult == 0) {
|
283
|
+
lProcessResult = iPtrProcessMethod(((tSampleValue)(*lPtrData)) - 128, &lOutputValue, lIdxSample, lIdxChannel, iPtrArgs);
|
284
|
+
}
|
285
|
+
if (lProcessResult == 1) {
|
286
|
+
break;
|
287
|
+
}
|
288
|
+
// Write lOutputValue
|
289
|
+
(*lPtrDataOut) = (unsigned char)(lOutputValue + 128);
|
290
|
+
++lPtrDataOut;
|
291
|
+
++lPtrData;
|
292
|
+
}
|
293
|
+
if (lProcessResult == 1) {
|
294
|
+
break;
|
295
|
+
}
|
296
|
+
++lIdxSample;
|
297
|
+
}
|
298
|
+
} else if (iNbrBitsPerSample == 16) {
|
299
|
+
signed short int* lPtrData = (signed short int*)iPtrRawBuffer;
|
300
|
+
signed short int* lPtrDataOut = (signed short int*)oPtrRawBufferOut;
|
301
|
+
for (lIdxBufferSample = 0; lIdxBufferSample < iNbrSamples; ++lIdxBufferSample) {
|
302
|
+
lProcessResult = 0;
|
303
|
+
for (lIdxChannel = 0; lIdxChannel < iNbrChannels; ++lIdxChannel) {
|
304
|
+
if (lProcessResult == 0) {
|
305
|
+
lProcessResult = iPtrProcessMethod((tSampleValue)(*lPtrData), &lOutputValue, lIdxSample, lIdxChannel, iPtrArgs);
|
306
|
+
}
|
307
|
+
if (lProcessResult == 1) {
|
308
|
+
break;
|
309
|
+
}
|
310
|
+
// Write lOutputValue
|
311
|
+
(*lPtrDataOut) = (signed short int)lOutputValue;
|
312
|
+
++lPtrDataOut;
|
313
|
+
++lPtrData;
|
314
|
+
}
|
315
|
+
if (lProcessResult == 1) {
|
316
|
+
break;
|
317
|
+
}
|
318
|
+
++lIdxSample;
|
319
|
+
}
|
320
|
+
} else if (iNbrBitsPerSample == 24) {
|
321
|
+
t24bits* lPtrData = (t24bits*)iPtrRawBuffer;
|
322
|
+
t24bits* lPtrDataOut = (t24bits*)oPtrRawBufferOut;
|
323
|
+
for (lIdxBufferSample = 0; lIdxBufferSample < iNbrSamples; ++lIdxBufferSample) {
|
324
|
+
lProcessResult = 0;
|
325
|
+
for (lIdxChannel = 0; lIdxChannel < iNbrChannels; ++lIdxChannel) {
|
326
|
+
if (lProcessResult == 0) {
|
327
|
+
lProcessResult = iPtrProcessMethod((tSampleValue)(lPtrData->value), &lOutputValue, lIdxSample, lIdxChannel, iPtrArgs);
|
328
|
+
}
|
329
|
+
if (lProcessResult == 1) {
|
330
|
+
break;
|
331
|
+
}
|
332
|
+
// Write lOutputValue
|
333
|
+
lPtrDataOut->value = lOutputValue;
|
334
|
+
lPtrDataOut = (t24bits*)(((int)lPtrDataOut)+3);
|
335
|
+
// Increase lPtrData this way to ensure alignment.
|
336
|
+
lPtrData = (t24bits*)(((int)lPtrData)+3);
|
337
|
+
}
|
338
|
+
if (lProcessResult == 1) {
|
339
|
+
break;
|
340
|
+
}
|
341
|
+
++lIdxSample;
|
342
|
+
}
|
343
|
+
} else {
|
344
|
+
rb_raise(rb_eRuntimeError, "Unknown bits per samples: %d\n", iNbrBitsPerSample);
|
345
|
+
}
|
346
|
+
}
|
347
|
+
}
|
348
|
+
|
349
|
+
/**
|
350
|
+
* Iterate through an output raw buffer only, without input raw buffer.
|
351
|
+
*
|
352
|
+
* Parameters::
|
353
|
+
* * *iSelf* (_Object_): Object used to call log methods
|
354
|
+
* * *oPtrRawBufferOut* (<em>char*</em>): The raw buffer to write
|
355
|
+
* * *iNbrBitsPerSample* (<em>const int</em>): The number of bits per sample
|
356
|
+
* * *iNbrChannels* (<em>const int</em>): The number of channels
|
357
|
+
* * *iNbrSamples* (<em>const tSampleIndex</em>): The number of samples
|
358
|
+
* * *iIdxOffsetSample* (<em>const tSampleIndex</em>): The base offset of samples to be counted and given to the processing method
|
359
|
+
* * *iNeedCheck* (<em>const int</em>): Do we need checking output value ranges ? 0 = no, 1 = yes
|
360
|
+
* * *iPtrProcessMethod* (<em>const tPtrFctProcessOutputOnly</em>): Pointer to the method to call for processing
|
361
|
+
* * *iPtrArgs* (<em>void*</em>): Pointer to a user specific struct that will be given to the processing function
|
362
|
+
*/
|
363
|
+
void commonutils_iterateThroughRawBufferOutputOnly(
|
364
|
+
VALUE iSelf,
|
365
|
+
char* oPtrRawBufferOut,
|
366
|
+
const int iNbrBitsPerSample,
|
367
|
+
const int iNbrChannels,
|
368
|
+
const tSampleIndex iNbrSamples,
|
369
|
+
const tSampleIndex iIdxOffsetSample,
|
370
|
+
const int iNeedCheck,
|
371
|
+
const tPtrFctProcessOutputOnly iPtrProcessMethod,
|
372
|
+
void* iPtrArgs) {
|
373
|
+
// Parse the data. This is done differently depending on the data structure
|
374
|
+
// Define variables outside the loops to not allocate and initialize heap size for nothing
|
375
|
+
tSampleIndex lIdxBufferSample;
|
376
|
+
int lIdxChannel;
|
377
|
+
tSampleIndex lIdxSample = iIdxOffsetSample;
|
378
|
+
// 0: Continue iterations
|
379
|
+
// 1: Break all
|
380
|
+
// 2: Skip to the next sample
|
381
|
+
int lProcessResult;
|
382
|
+
tSampleValue lOutputValue;
|
383
|
+
// Compute max and min values if needed only
|
384
|
+
if (iNeedCheck != 0) {
|
385
|
+
char lLogMessage[256];
|
386
|
+
ID lIDLogWarn = rb_intern("log_warn");
|
387
|
+
int lMaxValue = (1 << (iNbrBitsPerSample-1)) - 1;
|
388
|
+
int lMinValue = -(1 << (iNbrBitsPerSample-1));
|
389
|
+
if (iNbrBitsPerSample == 8) {
|
390
|
+
unsigned char* lPtrDataOut = (unsigned char*)oPtrRawBufferOut;
|
391
|
+
for (lIdxBufferSample = 0; lIdxBufferSample < iNbrSamples; ++lIdxBufferSample) {
|
392
|
+
lProcessResult = 0;
|
393
|
+
for (lIdxChannel = 0; lIdxChannel < iNbrChannels; ++lIdxChannel) {
|
394
|
+
if (lProcessResult == 0) {
|
395
|
+
lProcessResult = iPtrProcessMethod(&lOutputValue, lIdxSample, lIdxChannel, iPtrArgs);
|
396
|
+
}
|
397
|
+
if (lProcessResult == 1) {
|
398
|
+
break;
|
399
|
+
}
|
400
|
+
// Write lOutputValue
|
401
|
+
if (lOutputValue > lMaxValue) {
|
402
|
+
sprintf(lLogMessage, "@%lld,%d - Exceeding maximal value: %d, set to %d", lIdxSample, lIdxChannel, lOutputValue, lMaxValue);
|
403
|
+
rb_funcall(iSelf, lIDLogWarn, 1, rb_str_new2(lLogMessage));
|
404
|
+
lOutputValue = lMaxValue;
|
405
|
+
} else if (lOutputValue < lMinValue) {
|
406
|
+
sprintf(lLogMessage, "@%lld,%d - Exceeding minimal value: %d, set to %d", lIdxSample, lIdxChannel, lOutputValue, lMinValue);
|
407
|
+
rb_funcall(iSelf, lIDLogWarn, 1, rb_str_new2(lLogMessage));
|
408
|
+
lOutputValue = lMinValue;
|
409
|
+
}
|
410
|
+
(*lPtrDataOut) = (unsigned char)(lOutputValue + 128);
|
411
|
+
++lPtrDataOut;
|
412
|
+
}
|
413
|
+
if (lProcessResult == 1) {
|
414
|
+
break;
|
415
|
+
}
|
416
|
+
++lIdxSample;
|
417
|
+
}
|
418
|
+
} else if (iNbrBitsPerSample == 16) {
|
419
|
+
signed short int* lPtrDataOut = (signed short int*)oPtrRawBufferOut;
|
420
|
+
for (lIdxBufferSample = 0; lIdxBufferSample < iNbrSamples; ++lIdxBufferSample) {
|
421
|
+
lProcessResult = 0;
|
422
|
+
for (lIdxChannel = 0; lIdxChannel < iNbrChannels; ++lIdxChannel) {
|
423
|
+
if (lProcessResult == 0) {
|
424
|
+
lProcessResult = iPtrProcessMethod(&lOutputValue, lIdxSample, lIdxChannel, iPtrArgs);
|
425
|
+
}
|
426
|
+
if (lProcessResult == 1) {
|
427
|
+
break;
|
428
|
+
}
|
429
|
+
// Write lOutputValue
|
430
|
+
if (lOutputValue > lMaxValue) {
|
431
|
+
sprintf(lLogMessage, "@%lld,%d - Exceeding maximal value: %d, set to %d", lIdxSample, lIdxChannel, lOutputValue, lMaxValue);
|
432
|
+
rb_funcall(iSelf, lIDLogWarn, 1, rb_str_new2(lLogMessage));
|
433
|
+
lOutputValue = lMaxValue;
|
434
|
+
} else if (lOutputValue < lMinValue) {
|
435
|
+
sprintf(lLogMessage, "@%lld,%d - Exceeding minimal value: %d, set to %d", lIdxSample, lIdxChannel, lOutputValue, lMinValue);
|
436
|
+
rb_funcall(iSelf, lIDLogWarn, 1, rb_str_new2(lLogMessage));
|
437
|
+
lOutputValue = lMinValue;
|
438
|
+
}
|
439
|
+
(*lPtrDataOut) = (signed short int)lOutputValue;
|
440
|
+
++lPtrDataOut;
|
441
|
+
}
|
442
|
+
if (lProcessResult == 1) {
|
443
|
+
break;
|
444
|
+
}
|
445
|
+
++lIdxSample;
|
446
|
+
}
|
447
|
+
} else if (iNbrBitsPerSample == 24) {
|
448
|
+
t24bits* lPtrDataOut = (t24bits*)oPtrRawBufferOut;
|
449
|
+
for (lIdxBufferSample = 0; lIdxBufferSample < iNbrSamples; ++lIdxBufferSample) {
|
450
|
+
lProcessResult = 0;
|
451
|
+
for (lIdxChannel = 0; lIdxChannel < iNbrChannels; ++lIdxChannel) {
|
452
|
+
if (lProcessResult == 0) {
|
453
|
+
lProcessResult = iPtrProcessMethod(&lOutputValue, lIdxSample, lIdxChannel, iPtrArgs);
|
454
|
+
}
|
455
|
+
if (lProcessResult == 1) {
|
456
|
+
break;
|
457
|
+
}
|
458
|
+
// Write lOutputValue
|
459
|
+
if (lOutputValue > lMaxValue) {
|
460
|
+
sprintf(lLogMessage, "@%lld,%d - Exceeding maximal value: %d, set to %d", lIdxSample, lIdxChannel, lOutputValue, lMaxValue);
|
461
|
+
rb_funcall(iSelf, lIDLogWarn, 1, rb_str_new2(lLogMessage));
|
462
|
+
lOutputValue = lMaxValue;
|
463
|
+
} else if (lOutputValue < lMinValue) {
|
464
|
+
sprintf(lLogMessage, "@%lld,%d - Exceeding minimal value: %d, set to %d", lIdxSample, lIdxChannel, lOutputValue, lMinValue);
|
465
|
+
rb_funcall(iSelf, lIDLogWarn, 1, rb_str_new2(lLogMessage));
|
466
|
+
lOutputValue = lMinValue;
|
467
|
+
}
|
468
|
+
lPtrDataOut->value = lOutputValue;
|
469
|
+
// Increase lPtrDataOut this way to ensure alignment.
|
470
|
+
lPtrDataOut = (t24bits*)(((int)lPtrDataOut)+3);
|
471
|
+
}
|
472
|
+
if (lProcessResult == 1) {
|
473
|
+
break;
|
474
|
+
}
|
475
|
+
++lIdxSample;
|
476
|
+
}
|
477
|
+
} else {
|
478
|
+
rb_raise(rb_eRuntimeError, "Unknown bits per samples: %d\n", iNbrBitsPerSample);
|
479
|
+
}
|
480
|
+
} else {
|
481
|
+
// No check needed here. Just write what we get.
|
482
|
+
if (iNbrBitsPerSample == 8) {
|
483
|
+
unsigned char* lPtrDataOut = (unsigned char*)oPtrRawBufferOut;
|
484
|
+
for (lIdxBufferSample = 0; lIdxBufferSample < iNbrSamples; ++lIdxBufferSample) {
|
485
|
+
lProcessResult = 0;
|
486
|
+
for (lIdxChannel = 0; lIdxChannel < iNbrChannels; ++lIdxChannel) {
|
487
|
+
if (lProcessResult == 0) {
|
488
|
+
lProcessResult = iPtrProcessMethod(&lOutputValue, lIdxSample, lIdxChannel, iPtrArgs);
|
489
|
+
}
|
490
|
+
if (lProcessResult == 1) {
|
491
|
+
break;
|
492
|
+
}
|
493
|
+
// Write lOutputValue
|
494
|
+
(*lPtrDataOut) = (unsigned char)(lOutputValue + 128);
|
495
|
+
++lPtrDataOut;
|
496
|
+
}
|
497
|
+
if (lProcessResult == 1) {
|
498
|
+
break;
|
499
|
+
}
|
500
|
+
++lIdxSample;
|
501
|
+
}
|
502
|
+
} else if (iNbrBitsPerSample == 16) {
|
503
|
+
signed short int* lPtrDataOut = (signed short int*)oPtrRawBufferOut;
|
504
|
+
for (lIdxBufferSample = 0; lIdxBufferSample < iNbrSamples; ++lIdxBufferSample) {
|
505
|
+
lProcessResult = 0;
|
506
|
+
for (lIdxChannel = 0; lIdxChannel < iNbrChannels; ++lIdxChannel) {
|
507
|
+
if (lProcessResult == 0) {
|
508
|
+
lProcessResult = iPtrProcessMethod(&lOutputValue, lIdxSample, lIdxChannel, iPtrArgs);
|
509
|
+
}
|
510
|
+
if (lProcessResult == 1) {
|
511
|
+
break;
|
512
|
+
}
|
513
|
+
// Write lOutputValue
|
514
|
+
(*lPtrDataOut) = (signed short int)lOutputValue;
|
515
|
+
++lPtrDataOut;
|
516
|
+
}
|
517
|
+
if (lProcessResult == 1) {
|
518
|
+
break;
|
519
|
+
}
|
520
|
+
++lIdxSample;
|
521
|
+
}
|
522
|
+
} else if (iNbrBitsPerSample == 24) {
|
523
|
+
t24bits* lPtrDataOut = (t24bits*)oPtrRawBufferOut;
|
524
|
+
for (lIdxBufferSample = 0; lIdxBufferSample < iNbrSamples; ++lIdxBufferSample) {
|
525
|
+
lProcessResult = 0;
|
526
|
+
for (lIdxChannel = 0; lIdxChannel < iNbrChannels; ++lIdxChannel) {
|
527
|
+
if (lProcessResult == 0) {
|
528
|
+
lProcessResult = iPtrProcessMethod(&lOutputValue, lIdxSample, lIdxChannel, iPtrArgs);
|
529
|
+
}
|
530
|
+
if (lProcessResult == 1) {
|
531
|
+
break;
|
532
|
+
}
|
533
|
+
// Write lOutputValue
|
534
|
+
lPtrDataOut->value = lOutputValue;
|
535
|
+
// Increase lPtrDataOut this way to ensure alignment.
|
536
|
+
lPtrDataOut = (t24bits*)(((int)lPtrDataOut)+3);
|
537
|
+
}
|
538
|
+
if (lProcessResult == 1) {
|
539
|
+
break;
|
540
|
+
}
|
541
|
+
++lIdxSample;
|
542
|
+
}
|
543
|
+
} else {
|
544
|
+
rb_raise(rb_eRuntimeError, "Unknown bits per samples: %d\n", iNbrBitsPerSample);
|
545
|
+
}
|
546
|
+
}
|
547
|
+
}
|
548
|
+
|
549
|
+
/**
|
550
|
+
* Iterate through a raw buffer in reverse mode.
|
551
|
+
*
|
552
|
+
* Parameters::
|
553
|
+
* * *iPtrRawBuffer* (<em>const char*</em>): The raw buffer
|
554
|
+
* * *iNbrBitsPerSample* (<em>const int</em>): The number of bits per sample
|
555
|
+
* * *iNbrChannels* (<em>const int</em>): The number of channels
|
556
|
+
* * *iNbrSamples* (<em>const tSampleIndex</em>): The number of samples
|
557
|
+
* * *iIdxOffsetSample* (<em>const tSampleIndex</em>): The base offset of samples to be counted and given to the processing method
|
558
|
+
* * *iPtrProcessMethod* (<em>const tPtrFctProcess</em>): Pointer to the method to call for processing
|
559
|
+
* * *iPtrArgs* (<em>void*</em>): Pointer to a user specific struct that will be given to the processing function
|
560
|
+
*/
|
561
|
+
void commonutils_iterateReverseThroughRawBuffer(
|
562
|
+
const char* iPtrRawBuffer,
|
563
|
+
const int iNbrBitsPerSample,
|
564
|
+
const int iNbrChannels,
|
565
|
+
const tSampleIndex iNbrSamples,
|
566
|
+
const tSampleIndex iIdxOffsetSample,
|
567
|
+
const tPtrFctProcess iPtrProcessMethod,
|
568
|
+
void* iPtrArgs) {
|
569
|
+
// Parse the data. This is done differently depending on the data structure
|
570
|
+
// Define variables outside the loops to not allocate and initialize heap size for nothing
|
571
|
+
tSampleIndex lIdxBufferSample;
|
572
|
+
int lIdxChannel;
|
573
|
+
tSampleIndex lIdxSample = iIdxOffsetSample;
|
574
|
+
// 0: Continue iterations
|
575
|
+
// 1: Break all
|
576
|
+
// 2: Skip to the next sample
|
577
|
+
int lProcessResult;
|
578
|
+
if (iNbrBitsPerSample == 8) {
|
579
|
+
unsigned char* lPtrData = (unsigned char*)iPtrRawBuffer;
|
580
|
+
lPtrData += iNbrSamples*iNbrChannels - 1;
|
581
|
+
for (lIdxBufferSample = 0; lIdxBufferSample < iNbrSamples; ++lIdxBufferSample) {
|
582
|
+
lProcessResult = 0;
|
583
|
+
for (lIdxChannel = iNbrChannels-1; lIdxChannel >= 0; --lIdxChannel) {
|
584
|
+
if (lProcessResult == 0) {
|
585
|
+
lProcessResult = iPtrProcessMethod(((tSampleValue)(*lPtrData)) - 128, lIdxSample, lIdxChannel, iPtrArgs);
|
586
|
+
}
|
587
|
+
if (lProcessResult == 1) {
|
588
|
+
break;
|
589
|
+
}
|
590
|
+
--lPtrData;
|
591
|
+
}
|
592
|
+
if (lProcessResult == 1) {
|
593
|
+
break;
|
594
|
+
}
|
595
|
+
--lIdxSample;
|
596
|
+
}
|
597
|
+
} else if (iNbrBitsPerSample == 16) {
|
598
|
+
signed short int* lPtrData = (signed short int*)iPtrRawBuffer;
|
599
|
+
lPtrData += iNbrSamples*iNbrChannels - 1;
|
600
|
+
for (lIdxBufferSample = 0; lIdxBufferSample < iNbrSamples; ++lIdxBufferSample) {
|
601
|
+
lProcessResult = 0;
|
602
|
+
for (lIdxChannel = iNbrChannels-1; lIdxChannel >= 0; --lIdxChannel) {
|
603
|
+
if (lProcessResult == 0) {
|
604
|
+
lProcessResult = iPtrProcessMethod((tSampleValue)(*lPtrData), lIdxSample, lIdxChannel, iPtrArgs);
|
605
|
+
}
|
606
|
+
if (lProcessResult == 1) {
|
607
|
+
break;
|
608
|
+
}
|
609
|
+
--lPtrData;
|
610
|
+
}
|
611
|
+
if (lProcessResult == 1) {
|
612
|
+
break;
|
613
|
+
}
|
614
|
+
--lIdxSample;
|
615
|
+
}
|
616
|
+
} else if (iNbrBitsPerSample == 24) {
|
617
|
+
t24bits* lPtrData = (t24bits*)iPtrRawBuffer;
|
618
|
+
lPtrData = (t24bits*)(((int)lPtrData)+3*(((int)iNbrSamples)*iNbrChannels - 1));
|
619
|
+
for (lIdxBufferSample = 0; lIdxBufferSample < iNbrSamples; ++lIdxBufferSample) {
|
620
|
+
lProcessResult = 0;
|
621
|
+
for (lIdxChannel = iNbrChannels-1; lIdxChannel >= 0; --lIdxChannel) {
|
622
|
+
if (lProcessResult == 0) {
|
623
|
+
lProcessResult = iPtrProcessMethod((tSampleValue)(lPtrData->value), lIdxSample, lIdxChannel, iPtrArgs);
|
624
|
+
}
|
625
|
+
if (lProcessResult == 1) {
|
626
|
+
break;
|
627
|
+
}
|
628
|
+
// Increase lPtrData this way to ensure alignment.
|
629
|
+
lPtrData = (t24bits*)(((int)lPtrData)-3);
|
630
|
+
}
|
631
|
+
if (lProcessResult == 1) {
|
632
|
+
break;
|
633
|
+
}
|
634
|
+
--lIdxSample;
|
635
|
+
}
|
636
|
+
} else {
|
637
|
+
rb_raise(rb_eRuntimeError, "Unknown bits per samples: %d\n", iNbrBitsPerSample);
|
638
|
+
}
|
639
|
+
}
|