-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCRMS.c
executable file
·102 lines (88 loc) · 3 KB
/
CRMS.c
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
/*
* Computes the windowed RMS of a signal
*
* INPUTS:
* padded_signal: [double column vector] the padded signal
* sig_length : [int] the original signal length
* pad_size : [int] the padding size used to pad the signal before computing the RMS
* window_length: [int] the length of the RMS window to use
*
* Sagi Perel, 05/2008
*/
#include "mex.h"
#include <string.h>
#include <math.h>
double array_mean(double* arr, int arr_size)
{
int i;
double mean=arr[0];
for(i=1; i<arr_size; i++)
mean += arr[i];
return mean/arr_size;
}
void array_pow2(double* arr, int arr_size)
{
int i;
for(i=0; i<arr_size; i++)
arr[i] = pow(arr[i], 2);
}
/*
* Assumes that sig_rms is already allocated and has the size of sig_len
*/
void RMS(double* padded_sig, int sig_len, int padded_sig_length, int pad_size, double* sig_rms)
{
int i;
double sample_rms_val = 0;
int window_len = pad_size*2+1; //length of the running window we will use
#ifdef _WIN_CMRS
//the MS compiler doesn't like it - so let Matlab do allocation for us
double *tmp;
mxArray *tmpmxArray;
tmpmxArray = mxCreateDoubleMatrix(window_len, 1, mxREAL);
tmp = mxGetPr(tmpmxArray);
#else
double tmp[window_len];
#endif
//compute the RMS
for(i=pad_size; i<sig_len+pad_size; i++)
{
//to compute an RMS sample- we need to work on a small window
memcpy(tmp, &padded_sig[i-pad_size], sizeof(double)*window_len);
array_pow2(tmp,window_len);
//compute the sqrt of the mean
sample_rms_val = sqrt(array_mean(tmp,window_len));
sig_rms[i-pad_size] = sample_rms_val;
}
#ifdef _WIN_CMRS
mxDestroyArray(tmpmxArray);
#endif
}
void
mexFunction(
int num_output_args, // Number of left hand side (output) arguments
mxArray *output_arg[], // Array of left hand side arguments
int num_input_args, // Number of right hand side (input) arguments
const mxArray *input_arg[]) // Array of right hand side arguments
{
double *padded_sig, *sig_rms, *tmp;
int sig_length, padded_sig_length, pad_size, window_length;
//sanity check for input arguments
if( num_input_args != 4) mexErrMsgTxt( "RMS.c: wrong syntax: You should use RMS(padded_signal, original_signal_length, pad_size, window_length)\n");
if( mxGetN(input_arg[0]) != 1) mexErrMsgTxt( "RMS.c: the signal must be a column vector\n");
//read input arguments:
//-read the signal and its size
padded_sig = (double *) mxGetData( input_arg[0]);
padded_sig_length = mxGetM(input_arg[0]);
tmp = (double *) mxGetData( input_arg[1]);
sig_length = (int)(*tmp);
//-read the pad size
tmp = (double *) mxGetData( input_arg[2]);
pad_size = (int) (*tmp);
//-read the window length
tmp = (double *) mxGetData( input_arg[3]);
window_length = (int) (*tmp);
//create an output array
output_arg[0] = mxCreateDoubleMatrix(sig_length, 1, mxREAL);
sig_rms = mxGetPr(output_arg[0]);
RMS(padded_sig, sig_length, padded_sig_length, pad_size, sig_rms);
}