libdspl-2.0
Библиотека алгоритмов цифровой обработки сигналов
psd_bartlett.c
1 /*
2 * Copyright (c) 2015-2024 Sergey Bakhurin
3 * Digital Signal Processing Library [http://dsplib.org]
4 *
5 * This file is part of libdspl-2.0.
6 *
7 * is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * DSPL is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with Foobar. If not, see <http://www.gnu.org/licenses/>.
19 */
20 
21 #include <stdlib.h>
22 #include <stdio.h>
23 #include <string.h>
24 #include <float.h>
25 #include "dspl.h"
26 
27 
28 
29 #ifdef DOXYGEN_ENGLISH
30 
31 #endif
32 #ifdef DOXYGEN_RUSSIAN
33 
143 #endif
144 int DSPL_API psd_bartlett(double* x, int n, int nfft,
145  fft_t* pfft, double fs,
146  int flag, double* ppsd, double* pfrq)
147 {
148  int err, pos, k;
149  double *pdgr = NULL;
150  double *tmp = NULL;
151  fft_t *ptr_fft = NULL;
152 
153  pos = 0;
154 
155  pdgr = (double*)malloc(nfft * sizeof(double));
156  if(!pdgr)
157  return ERROR_MALLOC;
158 
159  if(!pfft)
160  {
161  ptr_fft = (fft_t*)malloc(sizeof(fft_t));
162  memset(ptr_fft, 0, sizeof(fft_t));
163  }
164  else
165  ptr_fft = pfft;
166 
167  memset(ppsd, 0, nfft * sizeof(double));
168  while(pos + nfft <= n)
169  {
170  err = fft_mag(x + pos, nfft, ptr_fft, fs,
171  flag & DSPL_FLAG_FFT_SHIFT, pdgr, NULL);
172  if(err != RES_OK)
173  goto exit_label;
174  for(k = 0; k < nfft; k++)
175  ppsd[k] += pdgr[k];
176  pos += nfft;
177  }
178 
179  if(pos < n)
180  {
181  tmp = (double*)malloc(nfft * sizeof(double));
182  if(!tmp)
183  {
184  err = ERROR_MALLOC;
185  goto exit_label;
186  }
187  memset(tmp ,0, nfft * sizeof(double));
188  memcpy(tmp, x + pos, (n - pos)*sizeof(double));
189 
190  err = fft_mag(tmp, nfft, ptr_fft, fs,
191  flag & DSPL_FLAG_FFT_SHIFT, pdgr, NULL);
192  if(err != RES_OK)
193  goto exit_label;
194 
195  for(k = 0; k < nfft; k++)
196  ppsd[k] += pdgr[k];
197  }
198 
199  /* fill frequency */
200  if(pfrq)
201  {
202  if(flag & DSPL_FLAG_FFT_SHIFT)
203  if(n%2)
204  err = linspace(-fs*0.5 + fs*0.5/(double)nfft,
205  fs*0.5 - fs*0.5/(double)nfft,
206  n, DSPL_SYMMETRIC, pfrq);
207  else
208  err = linspace(-fs*0.5, fs*0.5, nfft, DSPL_PERIODIC, pfrq);
209  else
210  err = linspace(0, fs, nfft, DSPL_PERIODIC, pfrq);
211  }
212 
213  /* scale magnitude */
214  if(flag & DSPL_FLAG_LOGMAG)
215  {
216  for(k = 0; k < nfft; k++)
217  ppsd[k] = 10.0 * log10(ppsd[k] / (double)n / fs);
218  }
219  else
220  {
221  for(k = 0; k < nfft; k++)
222  ppsd[k] /= (double)n * fs;
223  }
224 
225 
226 exit_label:
227  if(pdgr)
228  free(pdgr);
229  if(tmp)
230  free(tmp);
231  if(ptr_fft && (ptr_fft != pfft))
232  {
233  fft_free(ptr_fft);
234  free(ptr_fft);
235  }
236  return err;
237 }
238 
void fft_free(fft_t *pfft)
Очистить структуру fft_t алгоритма БПФ
Definition: fft_free.c:61
int psd_bartlett(double *x, int n, int nfft, fft_t *pfft, double fs, int flag, double *ppsd, double *pfrq)
Непараметрическая оценка спектральной плотности мощности (СПМ) вещественного сигнала методом Бартлетт...
Definition: psd_bartlett.c:144
Структура данных объекта быстрого преобразования Фурье
Definition: dspl.h:277
#define RES_OK
Функция завершилась корректно. Ошибки отсутствуют.
Definition: dspl.h:558
int linspace(double x0, double x1, int n, int type, double *x)
Функция заполняет массив линейно-нарастающими, равноотстоящими значениями от x0 до x1
Definition: linspace.c:169
#define ERROR_MALLOC
Ошибка динамического выделения памяти. Данная ошибка означает, что при динамическом выделении памяти ...
Definition: dspl.h:599